diff --git a/resources/static/dialog/controllers/dialog.js b/resources/static/dialog/controllers/dialog.js index 36e66dca60e3ccc6310246344cb029f22d637376..930b7707eeb571d26fa6e2ec81ce267bc8e0fa06 100644 --- a/resources/static/dialog/controllers/dialog.js +++ b/resources/static/dialog/controllers/dialog.js @@ -178,6 +178,11 @@ BrowserID.Modules.Dialog = (function() { // that come from other domains, only allow absolute paths from the // origin. params.siteLogo = fixupAbsolutePath(origin_url, paramsFromRP.siteLogo); + // To avoid mixed content errors, only allow siteLogos to be served + // from https RPs + if (URLParse(origin_url).scheme !== "https") { + throw "only https sites can specify a siteLogo"; + } } if (paramsFromRP.siteName) { diff --git a/resources/static/test/cases/controllers/dialog.js b/resources/static/test/cases/controllers/dialog.js index aedd54d97475b720ed0affd26f640161948dfd04..f1ddb37c6f57dfe7afc6d744d0bde0dafb1419b8 100644 --- a/resources/static/test/cases/controllers/dialog.js +++ b/resources/static/test/cases/controllers/dialog.js @@ -560,7 +560,26 @@ }); }); - asyncTest("get with absolute path - allowed URL but it must be properly escaped", function() { + asyncTest("get with absolute path and http RP - not allowed", function() { + createController({ + ready: function() { + mediator.subscribe("start", function(msg, info) { + ok(false, "start should not have been called"); + }); + + var siteLogo = '/i/card.png'; + var retval = controller.get(HTTP_TEST_DOMAIN, { + siteLogo: siteLogo + }); + + equal(retval, "only https sites can specify a siteLogo", "expected error"); + testErrorVisible(); + start(); + } + }); + }); + + asyncTest("get with absolute path and https RP - allowed URL but is properly escaped", function() { createController({ ready: function() { var startInfo; @@ -569,12 +588,12 @@ }); var siteLogo = '/i/card.png" onerror="alert(\'xss\')" <script>alert(\'more xss\')</script>'; - var retval = controller.get(HTTP_TEST_DOMAIN, { + var retval = controller.get(HTTPS_TEST_DOMAIN, { siteLogo: siteLogo }); testHelpers.testObjectValuesEqual(startInfo, { - siteLogo: encodeURI(HTTP_TEST_DOMAIN + siteLogo) + siteLogo: encodeURI(HTTPS_TEST_DOMAIN + siteLogo) }); equal(typeof retval, "undefined", "no error expected"); testErrorNotVisible();