Hi all
Over coffee we’ve been discussing the uniqueness and safety of call-id this morning. Lots of things like RTPEngine recording use call-id to generate filenames (yes it does escape them first :-). Not to mention dialog tracking (also uses from/to tags) etc.
Which got us thinking. As call-id is determined by the first SIP packet that normally comes from a UA, should we care if this UA was broken or worse malicious?
What would happen if they were repeated? For example we may struggle to determine a recordings owner in RTPEngine (file name format is callid+random.wav).
For security should we be rejecting requests where we’ve seen the call-id before?
All theoretical over coffee, as it was that or start working!
Just wondering what peoples thoughts were?
Cheers Mark
Hello,
there are many things that can go wrong if a bad actor can forge sip messages. That's why the call has to be authenticated/authorized in the first place (either user/password or some other trusted relationship by IP, certificate, ...).
Now if a trusted actor tries to do bad things, then it is harder to prevent, but once discovered, the identity is known and it can be eventually published in a way or another (by laws and the commercial agreement).
Normally, the call-id should be randomly generated, with very low chances of overlapping during the same time frame of active call. If rtpengine is adding its own random part to file names, then the risk of overwriting later is also very low.
The dialog is identified by call-id, from tag (set by caller) and to tag (set by callee), so in this case both caller and callee have to be bad actors.
But in many cases call-id is used alone as a key. Adding the from tag is quite useless, because is set by the same UA, so if it wants to send same call-id, can do the same with from tag. Then the to-tag is set by the called side and during the call initiations, there can be many outgoing branches, so during the 1xx phase there can be a couple of to-tags flowing around. So if something needs to be stored in the early phase, the to-tag of the to-be-answered call is not yet know.
Rejecting new calls having the same callid as another recent one could be safety check to plug if you are really concerned and you don't trust completely who is making the call. You can easily use a htable for that, to cache used call-ids and block new calls with same value.
Cheers, Daniel
On 13.02.20 10:07, Mark Boyce wrote:
Hi all
Over coffee we’ve been discussing the uniqueness and safety of call-id this morning. Lots of things like RTPEngine recording use call-id to generate filenames (yes it does escape them first :-). Not to mention dialog tracking (also uses from/to tags) etc.
Which got us thinking. As call-id is determined by the first SIP packet that normally comes from a UA, should we care if this UA was broken or worse malicious?
What would happen if they were repeated? For example we may struggle to determine a recordings owner in RTPEngine (file name format is callid+random.wav).
For security should we be rejecting requests where we’ve seen the call-id before?
All theoretical over coffee, as it was that or start working!
Just wondering what peoples thoughts were?
Cheers Mark _______________________________________________ Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Mark,
There’s a module in Kamailio for uuid which would be generated by kamailio and may be useful in your needs. You may need the additional step of correlating the uuid to the call-I’d, but should be better prevention of injection type issues.
-- Fred direct/sms +1 (336) 439-3733
On Feb 13, 2020, at 4:57 AM, Daniel-Constantin Mierla miconda@gmail.com wrote:
Hello,
there are many things that can go wrong if a bad actor can forge sip messages. That's why the call has to be authenticated/authorized in the first place (either user/password or some other trusted relationship by IP, certificate, ...).
Now if a trusted actor tries to do bad things, then it is harder to prevent, but once discovered, the identity is known and it can be eventually published in a way or another (by laws and the commercial agreement).
Normally, the call-id should be randomly generated, with very low chances of overlapping during the same time frame of active call. If rtpengine is adding its own random part to file names, then the risk of overwriting later is also very low.
The dialog is identified by call-id, from tag (set by caller) and to tag (set by callee), so in this case both caller and callee have to be bad actors.
But in many cases call-id is used alone as a key. Adding the from tag is quite useless, because is set by the same UA, so if it wants to send same call-id, can do the same with from tag. Then the to-tag is set by the called side and during the call initiations, there can be many outgoing branches, so during the 1xx phase there can be a couple of to-tags flowing around. So if something needs to be stored in the early phase, the to-tag of the to-be-answered call is not yet know.
Rejecting new calls having the same callid as another recent one could be safety check to plug if you are really concerned and you don't trust completely who is making the call. You can easily use a htable for that, to cache used call-ids and block new calls with same value.
Cheers, Daniel
On 13.02.20 10:07, Mark Boyce wrote: Hi all
Over coffee we’ve been discussing the uniqueness and safety of call-id this morning. Lots of things like RTPEngine recording use call-id to generate filenames (yes it does escape them first :-). Not to mention dialog tracking (also uses from/to tags) etc.
Which got us thinking. As call-id is determined by the first SIP packet that normally comes from a UA, should we care if this UA was broken or worse malicious?
What would happen if they were repeated? For example we may struggle to determine a recordings owner in RTPEngine (file name format is callid+random.wav).
For security should we be rejecting requests where we’ve seen the call-id before?
All theoretical over coffee, as it was that or start working!
Just wondering what peoples thoughts were?
Cheers Mark _______________________________________________ Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
-- Daniel-Constantin Mierla -- www.asipto.com www.twitter.com/miconda -- www.linkedin.com/in/miconda Kamailio Advanced Training - March 9-11, 2020, Berlin - www.asipto.com Kamailio World Conference - April 27-29, 2020, in Berlin -- www.kamailioworld.com
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Hi Fred
That’s exactly where we ended up. We’ve just added code to assign a uuid to each new dialog as it’s created. Which when logged via acc gives us the extra unique reference.
Thanks Mark
On 13 Feb 2020, at 10:51, Fred Posner fred@palner.com wrote:
Mark,
There’s a module in Kamailio for uuid which would be generated by kamailio and may be useful in your needs. You may need the additional step of correlating the uuid to the call-I’d, but should be better prevention of injection type issues.
-- Fred direct/sms +1 (336) 439-3733
On Feb 13, 2020, at 4:57 AM, Daniel-Constantin Mierla miconda@gmail.com wrote:
Hello,
there are many things that can go wrong if a bad actor can forge sip messages. That's why the call has to be authenticated/authorized in the first place (either user/password or some other trusted relationship by IP, certificate, ...).
Now if a trusted actor tries to do bad things, then it is harder to prevent, but once discovered, the identity is known and it can be eventually published in a way or another (by laws and the commercial agreement).
Normally, the call-id should be randomly generated, with very low chances of overlapping during the same time frame of active call. If rtpengine is adding its own random part to file names, then the risk of overwriting later is also very low.
The dialog is identified by call-id, from tag (set by caller) and to tag (set by callee), so in this case both caller and callee have to be bad actors.
But in many cases call-id is used alone as a key. Adding the from tag is quite useless, because is set by the same UA, so if it wants to send same call-id, can do the same with from tag. Then the to-tag is set by the called side and during the call initiations, there can be many outgoing branches, so during the 1xx phase there can be a couple of to-tags flowing around. So if something needs to be stored in the early phase, the to-tag of the to-be-answered call is not yet know.
Rejecting new calls having the same callid as another recent one could be safety check to plug if you are really concerned and you don't trust completely who is making the call. You can easily use a htable for that, to cache used call-ids and block new calls with same value.
Cheers, Daniel
On 13.02.20 10:07, Mark Boyce wrote: Hi all
Over coffee we’ve been discussing the uniqueness and safety of call-id this morning. Lots of things like RTPEngine recording use call-id to generate filenames (yes it does escape them first :-). Not to mention dialog tracking (also uses from/to tags) etc.
Which got us thinking. As call-id is determined by the first SIP packet that normally comes from a UA, should we care if this UA was broken or worse malicious?
What would happen if they were repeated? For example we may struggle to determine a recordings owner in RTPEngine (file name format is callid+random.wav).
For security should we be rejecting requests where we’ve seen the call-id before?
All theoretical over coffee, as it was that or start working!
Just wondering what peoples thoughts were?
Cheers Mark _______________________________________________
On Thu, Feb 13, 2020 at 10:59:47AM +0000, Mark Boyce wrote:
That’s exactly where we ended up. We’ve just added code to assign a uuid to each new dialog as it’s created. Which when logged via acc gives us the extra unique reference.
The trouble with that is it requires you to do a lot of gymnastics to keep extra state. Using Call-ID as a key allows you to operate on calls in a way that makes use solely of information contained in the SIP message itself.
In an essentially thermodynamic sense, more state means more complexity, and more fragility due to the inevitable bugs and corner cases that any moving part and synchronisation effort brings.
Call-IDs are required to be adequate GUIDs by the standard, and are sufficiently unique that the chance of a malicious collision is infinitesimal. Even short, bad GUIDs tend to be quite mathematically unique, unless they're just so comically short as to make a mockery of the GUID requirement.
I would carefully weigh the economic and technical trade-offs of assigning calls UUIDs on your side and maintaining that mapping. A more pragmatic policy might be to reject requests with a Call-ID that is below a certain string length.
-- Alex
Also, RTPEngine keys live calls by a combination of Call-ID + available tags + optional Via-branch parameter. The odds of forging all of these are just astronomically low.
If your concern is that an endpoint can overwrite its own recordings or whatnot, one should note that an endpoint can store a history of its own previously used Call-IDs and other unique identifiers regardless of length or the merits of the randomisation algorithm.
-- Alex
On Thu, Feb 13, 2020 at 11:21:21AM -0500, Alex Balashov wrote:
On Thu, Feb 13, 2020 at 10:59:47AM +0000, Mark Boyce wrote:
That’s exactly where we ended up. We’ve just added code to assign a uuid to each new dialog as it’s created. Which when logged via acc gives us the extra unique reference.
The trouble with that is it requires you to do a lot of gymnastics to keep extra state. Using Call-ID as a key allows you to operate on calls in a way that makes use solely of information contained in the SIP message itself.
In an essentially thermodynamic sense, more state means more complexity, and more fragility due to the inevitable bugs and corner cases that any moving part and synchronisation effort brings.
Call-IDs are required to be adequate GUIDs by the standard, and are sufficiently unique that the chance of a malicious collision is infinitesimal. Even short, bad GUIDs tend to be quite mathematically unique, unless they're just so comically short as to make a mockery of the GUID requirement.
I would carefully weigh the economic and technical trade-offs of assigning calls UUIDs on your side and maintaining that mapping. A more pragmatic policy might be to reject requests with a Call-ID that is below a certain string length.
-- Alex
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Hi Alex
The thought process our side was more in these stages;
- What if they’re not unique?
- What would it affect?
- Could it be used as an exploit?
- If not do we care?
… and wondered what others thought about it.
I think you’re/Fred/Daniels points of a simple sanity check on them is probably the simplest/best answer. We can then reject a UA as too broken for us to want to deal with if it fails.
We’ve also added a $dlg_var(dlg_uuid)=$uuid(g) just to tie some other state stuff in to
Mark
On 13 Feb 2020, at 16:35, Alex Balashov abalashov@evaristesys.com wrote:
Also, RTPEngine keys live calls by a combination of Call-ID + available tags + optional Via-branch parameter. The odds of forging all of these are just astronomically low.
If your concern is that an endpoint can overwrite its own recordings or whatnot, one should note that an endpoint can store a history of its own previously used Call-IDs and other unique identifiers regardless of length or the merits of the randomisation algorithm.
-- Alex
On Thu, Feb 13, 2020 at 11:21:21AM -0500, Alex Balashov wrote:
On Thu, Feb 13, 2020 at 10:59:47AM +0000, Mark Boyce wrote:
That’s exactly where we ended up. We’ve just added code to assign a uuid to each new dialog as it’s created. Which when logged via acc gives us the extra unique reference.
The trouble with that is it requires you to do a lot of gymnastics to keep extra state. Using Call-ID as a key allows you to operate on calls in a way that makes use solely of information contained in the SIP message itself.
In an essentially thermodynamic sense, more state means more complexity, and more fragility due to the inevitable bugs and corner cases that any moving part and synchronisation effort brings.
Call-IDs are required to be adequate GUIDs by the standard, and are sufficiently unique that the chance of a malicious collision is infinitesimal. Even short, bad GUIDs tend to be quite mathematically unique, unless they're just so comically short as to make a mockery of the GUID requirement.
I would carefully weigh the economic and technical trade-offs of assigning calls UUIDs on your side and maintaining that mapping. A more pragmatic policy might be to reject requests with a Call-ID that is below a certain string length.
-- Alex
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Hello,
to add a few more from my past experiences ... I have a couple of deployments where I check the call-id not to be duplicate in active transactions because of some other constraints (customer requirements) specific for the respective services -- for example, not allowing parallel forking from upstream/caller side.
Sometimes it bites back, because some UAs re-use the call-id after a 302 redirect, although that should be a completely new call. Because of usual small delays in deleting old records (like being able to catch retransmissions or route the ACK for 302), this extra check might block the follow up INVITE after 302 -- I hit this only once with an old PBX system -- so then you start adding exceptions to the rule.
IMO, the best is to evaluate the risks for your service, what is impacted, and try to keep everything as simple as possible. Putting a very complex system in place might cost way more that having a very rare case happening that you mitigate manually. Keeping backups of data and files has an important role.
Cheers, Daniel
On 13.02.20 18:20, Mark Boyce wrote:
Hi Alex
The thought process our side was more in these stages;
What if they’re not unique?
What would it affect?
Could it be used as an exploit?
If not do we care?
… and wondered what others thought about it.
I think you’re/Fred/Daniels points of a simple sanity check on them is probably the simplest/best answer. We can then reject a UA as too broken for us to want to deal with if it fails.
We’ve also added a $dlg_var(dlg_uuid)=$uuid(g) just to tie some other state stuff in to
Mark
On 13 Feb 2020, at 16:35, Alex Balashov abalashov@evaristesys.com wrote:
Also, RTPEngine keys live calls by a combination of Call-ID + available tags + optional Via-branch parameter. The odds of forging all of these are just astronomically low.
If your concern is that an endpoint can overwrite its own recordings or whatnot, one should note that an endpoint can store a history of its own previously used Call-IDs and other unique identifiers regardless of length or the merits of the randomisation algorithm.
-- Alex
On Thu, Feb 13, 2020 at 11:21:21AM -0500, Alex Balashov wrote:
On Thu, Feb 13, 2020 at 10:59:47AM +0000, Mark Boyce wrote:
That’s exactly where we ended up. We’ve just added code to assign a uuid to each new dialog as it’s created. Which when logged via acc gives us the extra unique reference.
The trouble with that is it requires you to do a lot of gymnastics to keep extra state. Using Call-ID as a key allows you to operate on calls in a way that makes use solely of information contained in the SIP message itself.
In an essentially thermodynamic sense, more state means more complexity, and more fragility due to the inevitable bugs and corner cases that any moving part and synchronisation effort brings.
Call-IDs are required to be adequate GUIDs by the standard, and are sufficiently unique that the chance of a malicious collision is infinitesimal. Even short, bad GUIDs tend to be quite mathematically unique, unless they're just so comically short as to make a mockery of the GUID requirement.
I would carefully weigh the economic and technical trade-offs of assigning calls UUIDs on your side and maintaining that mapping. A more pragmatic policy might be to reject requests with a Call-ID that is below a certain string length.
-- Alex
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users