Fix unauth-SSRC memory grow#372
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #372 +/- ##
=======================================
Coverage 82.42% 82.42%
=======================================
Files 19 19
Lines 1462 1474 +12
=======================================
+ Hits 1205 1215 +10
- Misses 142 143 +1
- Partials 115 116 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
02b62e5 to
feffa0b
Compare
|
Nice find! @sirzooro would you mind adding a test to assert no allocations on auth failure. IMO the warning on NULL crypto isn’t needed. If we add to much noise then maybe something real would get ignored. |
|
Does doing replay detection without authentication allow a DoS? I can spam RTP packets and break sessions now without keying materials |
Added new tests. Is there some valid production use of NULL cipher beside debugging? If yes, I would add another option to silence these warnings. I would like to have at least warning if someone would accidentally use insecure configuration in production environment.
I do not see anything obvious in the code, AI scan also did not reveal anything related to this. Maybe this is caused by increased CPU usage (higher jitter) or receive UDP buffer was overflown and some frames were dropped? |
|
i looked yesterday and it looks good to me, but i didn't really review it, I can review it tonight, @Sean-Der what do you think? |
|
@sirzooro Can we reduce it down to just fix I would like to still keep single purpose commits (even if AI can do big changes easily) especially in these security changes. Sorry for the push back :/ I think we should merge/tag that right away! |
Prevent memory growth from processing of unauthenticated SSRCs. Added explicit warnings when insecure configuration options are active.
|
@Sean-Der I have removed logging changes. PR contains main fix for unauth-SSRC memory grow, and two other small ones in context.go (first two points in description above). I also updated PR's description to match actual changes. |
Fix unauthenticated-SSRC memory exhaustion and add security-warning logging
Summary
This change addresses two classes of vulnerability where unauthenticated data in RTP/RTCP headers could be used to allocate unbounded per-SSRC state before the auth tag is verified.
Security Fixes
Unauthenticated SSRC state allocation (memory exhaustion)
srtp.go / srtcp.go —
getSRTPSSRCStateandgetSRTCPSSRCStatenow accept akeepNew boolparameter. During decryption the SSRC is read from the unauthenticated RTP/RTCP header, so these functions are called in read-only mode (keepNew = false): a temporary state object is created but not inserted into the map. The state is committed to the map by the newsetSRTPSSRCState/setSRTCPSSRCStatehelpers only aftermarkAsValid()succeeds (i.e. authentication is confirmed).session_srtp.go —
decryptRTPis now called beforegetOrCreateReadStream. Previously an unauthenticated peer could causegetOrCreateReadStreamto allocate a per-SSRC stream for an arbitrary spoofed SSRC, exhausting memory without ever providing a valid packet.Both fixes include inline comments explaining the security rationale and the intentional ordering of the replay check relative to authentication.
What Changed
context.go
authTagRTPLen < 0returnserrTooShortSRTPAuthTagbefore the profile auth-key length is queried.errShortSrtpMasterKeyerror message was accidentally printing the rawmasterKeyslice instead of its lengthmasterKeyLen.setSRTPSSRCStateandsetSRTCPSSRCStatehelpers for explicit post-auth state commitment.getSRTPSSRCStateandgetSRTCPSSRCStatereturn a secondboolindicating whether the state was pre-existing.SetROCandSetIndexupdated to passkeepNew = true(they always want to create state).session_srtp.go
decryptRTPcall abovegetOrCreateReadStreamto prevent unauthenticated stream allocation (see Security Fixes above).srtcp.go / srtp.go
getSRTCPSSRCState(ssrc, false)/getSRTPSSRCState(ssrc, false)with deferredsetSRTCPSSRCState/setSRTPSSRCStateafter authentication.getSRTCPSSRCState(ssrc, true)/getSRTPSSRCState(ssrc, true)(no behaviour change for encrypt).API Notes
getSRTPSSRCState/getSRTCPSSRCStatesignatures changed (internal); callers outside the package are unaffected.Tests
go test ..Reviewer Notes
markAsValid()is explicitly called.