Skip to content

Commit

Permalink
Bug 1017257 - Attach Loop CSP Policy r=sstamm,dmose
Browse files Browse the repository at this point in the history
  • Loading branch information
adamroach committed Oct 6, 2014
1 parent ad55719 commit 13232b1
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions browser/app/profile/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,11 @@ pref("loop.debug.loglevel", "Error");
pref("loop.debug.dispatcher", false);
pref("loop.debug.websocket", false);
pref("loop.debug.sdk", false);
#ifdef DEBUG
pref("loop.CSP", "default-src 'self' about: file: chrome: http://localhost:*; img-src 'self' data: http://www.gravatar.com/ about: file: chrome:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net http://localhost:* ws://localhost:*");
#else
pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src 'self' data: http://www.gravatar.com/ about: file: chrome:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net");
#endif
pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const kObservedTopics = [
];

const PREF_PERMISSION_FAKE = "media.navigator.permission.fake";
const PREF_LOOP_CSP = "loop.CSP";


Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Expand Down Expand Up @@ -162,12 +163,14 @@ fakeLoopAboutModule.prototype = {
let factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);

let originalLoopCsp = Services.prefs.getCharPref(PREF_LOOP_CSP);
registerCleanupFunction(function() {
gBrowser.removeCurrentTab();
kObservedTopics.forEach(topic => {
Services.obs.removeObserver(observer, topic);
});
Services.prefs.clearUserPref(PREF_PERMISSION_FAKE);
Services.prefs.setCharPref(PREF_LOOP_CSP, originalLoopCsp);
});


Expand All @@ -176,6 +179,8 @@ let gTests = [
{
desc: "getUserMedia about:loopconversation shouldn't prompt",
run: function checkAudioVideoLoop() {
Services.prefs.setCharPref(PREF_LOOP_CSP, "default-src 'unsafe-inline'");

let classID = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator).generateUUID();
registrar.registerFactory(classID, "",
Expand All @@ -198,6 +203,7 @@ let gTests = [
yield closeStream();

registrar.unregisterFactory(classID, factory);
Services.prefs.setCharPref(PREF_LOOP_CSP, originalLoopCsp);
}
},

Expand Down
5 changes: 5 additions & 0 deletions browser/components/loop/run-all-loop-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ set -e

# The browser_parsable_css.js can fail if we add some css that isn't parsable.
./mach mochitest browser/components/loop/test/mochitest browser/base/content/test/general/browser_parsable_css.js

# The check to make sure that the media devices can be used in Loop without
# prompting is in browser_devices_get_user_media_about_urls.js. It's possible
# to mess this up with CSP handling, and probably other changes, too.
./mach mochitest browser/base/content/test/general/browser_devices_get_user_media_about_urls.js
42 changes: 42 additions & 0 deletions content/base/src/nsDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2752,6 +2752,33 @@ AppendCSPFromHeader(nsIContentSecurityPolicy* csp,
return NS_OK;
}

bool
nsDocument::IsLoopDocument(nsIChannel *aChannel)
{
nsCOMPtr<nsIURI> chanURI;
nsresult rv = aChannel->GetOriginalURI(getter_AddRefs(chanURI));
NS_ENSURE_SUCCESS(rv, false);

bool isAbout = false;
bool isLoop = false;
rv = chanURI->SchemeIs("about", &isAbout);
NS_ENSURE_SUCCESS(rv, false);
if (isAbout) {
nsCOMPtr<nsIURI> loopURI;
rv = NS_NewURI(getter_AddRefs(loopURI), "about:loopconversation");
NS_ENSURE_SUCCESS(rv, false);
rv = chanURI->EqualsExceptRef(loopURI, &isLoop);
NS_ENSURE_SUCCESS(rv, false);
if (!isLoop) {
rv = NS_NewURI(getter_AddRefs(loopURI), "about:looppanel");
NS_ENSURE_SUCCESS(rv, false);
rv = chanURI->EqualsExceptRef(loopURI, &isLoop);
NS_ENSURE_SUCCESS(rv, false);
}
}
return isLoop;
}

nsresult
nsDocument::InitCSP(nsIChannel* aChannel)
{
Expand Down Expand Up @@ -2805,9 +2832,13 @@ nsDocument::InitCSP(nsIChannel* aChannel)
}
}

// Check if this is part of the Loop/Hello service
bool applyLoopCSP = IsLoopDocument(aChannel);

// If there's no CSP to apply, go ahead and return early
if (!applyAppDefaultCSP &&
!applyAppManifestCSP &&
!applyLoopCSP &&
cspHeaderValue.IsEmpty() &&
cspROHeaderValue.IsEmpty()) {
#ifdef PR_LOGGING
Expand Down Expand Up @@ -2880,6 +2911,17 @@ nsDocument::InitCSP(nsIChannel* aChannel)
csp->AppendPolicy(appManifestCSP, false);
}

// ----- if the doc is part of Loop, apply the loop CSP
if (applyLoopCSP) {
nsAdoptingString loopCSP;
loopCSP = Preferences::GetString("loop.CSP");
NS_ASSERTION(loopCSP, "Missing loop.CSP preference");
// If the pref has been removed, we continue without setting a CSP
if (loopCSP) {
csp->AppendPolicy(loopCSP, false);
}
}

// ----- if there's a full-strength CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
rv = AppendCSPFromHeader(csp, cspHeaderValue, false);
Expand Down
1 change: 1 addition & 0 deletions content/base/src/nsDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,7 @@ class nsDocument : public nsIDocument,
void DoUnblockOnload();

nsresult CheckFrameOptions();
bool IsLoopDocument(nsIChannel* aChannel);
nsresult InitCSP(nsIChannel* aChannel);

void FlushCSPWebConsoleErrorQueue()
Expand Down
1 change: 1 addition & 0 deletions testing/profiles/prefs_general.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ user_pref("loop.enabled", true);
user_pref("loop.throttled", false);
user_pref("loop.oauth.google.URL", "http://%(server)s/browser/browser/components/loop/test/mochitest/google_service.sjs?action=");
user_pref("loop.oauth.google.getContactsURL", "http://%(server)s/browser/browser/components/loop/test/mochitest/google_service.sjs?action=contacts");
user_pref("loop.CSP","default-src 'self' about: file: chrome: data: wss://* http://* https://*");

// Ensure UITour won't hit the network
user_pref("browser.uitour.pinnedTabUrl", "http://%(server)s/uitour-dummy/pinnedTab");
Expand Down

0 comments on commit 13232b1

Please sign in to comment.