From be9a5e6fac0febadaedfd226bd8108701bcdc776 Mon Sep 17 00:00:00 2001 From: Trevor Johnston Date: Tue, 2 Feb 2016 15:07:31 -0500 Subject: [PATCH] whitelist candidate line fields to help prevent problems caused by new fields --- src/churn/candidate.spec.ts | 22 +++++++++++++++++++++- src/churn/candidate.ts | 21 +++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/churn/candidate.spec.ts b/src/churn/candidate.spec.ts index 7087efa..c82fc66 100644 --- a/src/churn/candidate.spec.ts +++ b/src/churn/candidate.spec.ts @@ -101,4 +101,24 @@ describe("extractEndpointFromCandidateLine", function() { // Roundtrip expect(c.toRTCIceCandidate()).toEqual(rtcIceCandidate); }); -}); \ No newline at end of file + + // Ensure un-whitelisted extensions are stripped: + // https://github.com/uProxy/uproxy/issues/2167 + it('un-whitelisted extensions are removed', () => { + const rtcIceCandidate = { + candidate: 'candidate:1302982778 1 tcp 1518214911 172.29.18.131 0 typ host generation 0 ufrag abc123', + sdpMid: '', + sdpMLineIndex: 0 + }; + const c = Candidate.fromRTCIceCandidate(rtcIceCandidate); + expect(c.extensions.length).toEqual(1); + expect(c.extensions[0]).toEqual({ key: 'generation', value: '0' }); + + // Roundtrip, sanitised. + expect(c.toRTCIceCandidate()).toEqual({ + candidate: 'candidate:1302982778 1 tcp 1518214911 172.29.18.131 0 typ host generation 0', + sdpMid: '', + sdpMLineIndex: 0 + }); + }); +}); diff --git a/src/churn/candidate.ts b/src/churn/candidate.ts index 958c78a..77130df 100644 --- a/src/churn/candidate.ts +++ b/src/churn/candidate.ts @@ -12,6 +12,15 @@ export interface IceExtension { value: string; } +// The unexpected introduction of new fields has impacted churn +// in the past, e.g. ufrag: +// https://github.com/uProxy/uproxy/issues/2167 +// To help prevent similar breakages re-occurring, we generally +// remove fields that aren't defined in the spec. Exceptions are +// made for TCP candidates and Chrome's generation field, which +// has been around forever. +const EXTENSION_WHITELIST = ['tcptype', 'generation']; + // Represents an RTCIceCandidate object from the WebRTC spec: // http://www.w3.org/TR/webrtc/#rtcicecandidate-type // This encapsulates a candidate as described in section 15.1 of the ICE RFC @@ -136,10 +145,14 @@ export class Candidate { } for (; i < tokens.length; i += 2) { - c.extensions.push({ - key: tokens[i], - value: tokens[i + 1] - }); + const key = tokens[i]; + const value = tokens[i + 1]; + if (EXTENSION_WHITELIST.indexOf(key) >= 0) { + c.extensions.push({ + key: key, + value: value + }); + } } c.sdpMid = rtcIceCandidate.sdpMid;