Otherwise any client in your network may populate your usrlow without credentials and depending on your setup just grab other users accounts.
Even if you save() during request processing and have "bad" data in the usrloc table account hijacking shouldn't be possible because if the registration fails on the registrar, the registrar wont forward incoming calls to openser.
Consider the following sequence:
- User A registers sucessfully. openser usrloc and upstream usrloc are in
sync. 2) User B fakes user A registration. upstream says no - but openser already saved => usrlocs are out of sync 3) call from outside which should get to A will go to B (and B might forward to A, staying in the middle of course)
In step 3 it depends.
Usually, if openser forwards the REGISTER it has to manipulate it.
E.g the following scenario (for simplicity no NAT traversal and no multi-domain): user aor: sip:alice@atlanta.com user contact: sip:1.2.3.4
Registrar is a dumb SIP registrar at domain atlanta.com
Openser acts as outboundproxy, listening on domain obp.atlanta.com.
When openser forwards the REGISTER to the registrar it has to replace the contact header with the contact of itself (so that the registrar will forward the requests to openser). Further, openser has to put some id into the userpart to match incoming INVITEs to the proper user, e.g:
alice ----REGISTER-----> openser REGISTER sip:alice@atlanta.com To: sip:alice@atlanta.com Contact: sip:1.2.3.4
openser ----REGISTER-----> registrar REGISTER sip:alice@atlanta.com To: sip:alice@atlanta.com Contact: sip:userid@obp.atlanta.com
usrloc table of openser: AoR | contact ---------------------------+---------------------------- sip:userid@obp.atlanta.com | sip:1.2.3.4
usrloc table of registrar: AoR | contact ---------------------------+---------------------------- sip:alice@atlanta.com | sip:userid@obp.atlanta.com
Now, depending on how the "userid" is generated in the openser, the system is vulnerable in the above step 3 or not. Of course if the attacker find out how "userid" is generated or it makes brute force registration with all possible userid then the system is vulnerable. Anyway, you are correct - the save() should happen in the reply route after successful 200 OK.
I think a good generic solution would be to make a save() function which takes AoR and Contact from a parameter, e.g.: save("string/pv-spec","string/pv-spec") and this save function should work in reply route too. In single-domain setup the "userid" could be just the username of the AoR, e.g: in request route: $avp(s:contact) = $ct; remove_hf("Contact"); append_hf("Contact: sip:$tU@obp.atlanta.com\r\n"); t_on_reply(...)
in reply route if (200 OK) save("sip:$tU@obp.atlanta.com","$avp(s:contact)");
Thus, for a nice solution I guess you are right - source code modification would be necessary (but it shouldn't be that hard to expand save() to take parameters)
regards Klaus