diff --git a/resources/static/common/js/browserid.js b/resources/static/common/js/browserid.js index cf4e9f167e4bfcf838ef80abcf7a775e91b7a453..d20093840aa5536e3c2754e1b4559cbb1f7c16c0 100644 --- a/resources/static/common/js/browserid.js +++ b/resources/static/common/js/browserid.js @@ -17,7 +17,12 @@ KEY_LENGTH: 128, PASSWORD_MIN_LENGTH: 8, - PASSWORD_MAX_LENGTH: 80 + PASSWORD_MAX_LENGTH: 80, + // IE8 has a max total URL length of 2083 and a max path length of 2048. + // http://support.microsoft.com/kb/q208427 + // See issue #2080 - https://github.com/mozilla/browserid/issues/2080 + URL_MAX_LENGTH: 2083, + PATH_MAX_LENGTH: 2048 }); }()); diff --git a/resources/static/dialog/js/modules/dialog.js b/resources/static/dialog/js/modules/dialog.js index 7ed80ec7d026164860778e7cee7f979b557f9a18..e9e3555ae3f08c37fba8806e24cbce2ecf43c3a4 100644 --- a/resources/static/dialog/js/modules/dialog.js +++ b/resources/static/dialog/js/modules/dialog.js @@ -86,7 +86,22 @@ BrowserID.Modules.Dialog = (function() { else if (/^\//.test(url)) u = URLParse(origin + url); else throw "relative urls not allowed: (" + url + ")"; // encodeURI limits our return value to [a-z0-9:/?%], excluding <script> - return encodeURI(u.validate().normalize().toString()); + var encodedURI = encodeURI(u.validate().normalize().toString()); + + // All browsers have a max length of URI that they can handle. IE8 has the + // shortest total length at 2083 bytes. IE8 can handle a path length of + // 2048 bytes. See http://support.microsoft.com/kb/q208427 + + // Check the total encoded URI length + if (encodedURI.length > bid.URL_MAX_LENGTH) + throw "urls must be < " + bid.URL_MAX_LENGTH + " characters"; + + // Check just the path portion. encode the path to make sure the full + // length is checked. + if (encodeURI(u.path).length > bid.PATH_MAX_LENGTH) + throw "path portion of a url must be < " + bid.PATH_MAX_LENGTH + " characters"; + + return encodedURI; } function fixupAbsolutePath(origin_url, path) { diff --git a/resources/static/test/cases/dialog/js/modules/dialog.js b/resources/static/test/cases/dialog/js/modules/dialog.js index 8857ee8ff414da78f10965ed5deb0debc6a3df2b..153eda71708d624b7fef2a3a3f2fbd12760bb649 100644 --- a/resources/static/test/cases/dialog/js/modules/dialog.js +++ b/resources/static/test/cases/dialog/js/modules/dialog.js @@ -531,6 +531,47 @@ }); }); + asyncTest("get with absolute path that is too long - not allowed", function() { + createController({ + ready: function() { + mediator.subscribe("start", function(msg, info) { + ok(false, "start should not have been called"); + }); + + // create a logo path that is one character too long + var siteLogo = '/' + testHelpers.generateString(bid.PATH_MAX_LENGTH); + var retval = controller.get(HTTPS_TEST_DOMAIN, { + siteLogo: siteLogo + }); + + equal(retval, "path portion of a url must be < " + bid.PATH_MAX_LENGTH + " characters"); + testErrorVisible(); + start(); + } + }); + }); + + asyncTest("get with absolute path causing too long of a URL - not allowed", function() { + createController({ + ready: function() { + mediator.subscribe("start", function(msg, info) { + ok(false, "start should not have been called"); + }); + + var shortHTTPSDomain = "https://test.com"; + // create a URL that is one character too long + var siteLogo = '/' + testHelpers.generateString(bid.URL_MAX_LENGTH - shortHTTPSDomain.length); + var retval = controller.get(shortHTTPSDomain, { + siteLogo: siteLogo + }); + + equal(retval, "urls must be < " + bid.URL_MAX_LENGTH + " characters"); + testErrorVisible(); + start(); + } + }); + }); + asyncTest("get with absolute path and https RP - allowed URL but is properly escaped", function() { createController({ ready: function() {