diff --git a/src/sap.ui.core/src/sap/base/security/URLListValidator.js b/src/sap.ui.core/src/sap/base/security/URLListValidator.js index 9b5cbdd4d642..fd678ab97c47 100644 --- a/src/sap.ui.core/src/sap/base/security/URLListValidator.js +++ b/src/sap.ui.core/src/sap/base/security/URLListValidator.js @@ -16,6 +16,7 @@ sap.ui.define([], function() { var rCheckValidIPv6 = /^\[(((([0-9a-f]{1,4}:){6}|(::([0-9a-f]{1,4}:){5})|(([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4})|((([0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3})|((([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2})|((([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:)|((([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::))(([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])))|((([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4})|((([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::))\]$/i; var rCheckHostName = /^([a-z0-9]([a-z0-9\-]*[a-z0-9])?\.)*[a-z0-9]([a-z0-9\-]*[a-z0-9])?$/i; var rSpecialSchemeURLs = /^((?:ftp|https?|wss?):)([\s\S]+)$/; + var rBlobURLs = /^blob:(?[\w\+]+:\/\/(?=.{1,254}(?::|$))(?:(?!\d|-)(?![a-z0-9\-]{1,62}-(?:\.|:|$))[a-z0-9\-]{1,63}\b(?!\.$)\.?)+(:\d+)?)\/(?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/; /* eslint-disable no-control-regex */ var rCheckWhitespaces = /[\u0009\u000A\u000D]/; @@ -266,11 +267,24 @@ sap.ui.define([], function() { } } + // Test for Blob URLs (Schema: "blob:[ORIGIN]/[UUID]", + // e.g: "blob:https://sapui5.hana.ondemand.com/c56a4180-65aa-42ec-a945-5fd21dec0538") + var result = rBlobURLs.exec(sUrl); + if (result && result.groups) { + // Blob URLs are only valid if from the same origin + if (result.groups.origin !== window.location.origin) { + return false; + } + + // get the url without 'blob:' for further validation + sUrl = result.groups.origin + "/" + result.groups.uuid; + } + // for 'special' URLs without a given base URL, the whatwg spec allows any number of slashes. // As the rBasicUrl regular expression cannot handle 'special' URLs, the URL is modified upfront, // if it wouldn't be recognized by the regex. // See https://url.spec.whatwg.org/#scheme-state (case 2.6.) - var result = rSpecialSchemeURLs.exec(sUrl); + result = rSpecialSchemeURLs.exec(sUrl); if (result && !/^[\/\\]{2}/.test(result[2])) { sUrl = result[1] + "//" + result[2]; } diff --git a/src/sap.ui.core/test/sap/ui/core/qunit/base/security/URLListValidator.qunit.js b/src/sap.ui.core/test/sap/ui/core/qunit/base/security/URLListValidator.qunit.js index 7b93f35317df..0e138d35e3e7 100644 --- a/src/sap.ui.core/test/sap/ui/core/qunit/base/security/URLListValidator.qunit.js +++ b/src/sap.ui.core/test/sap/ui/core/qunit/base/security/URLListValidator.qunit.js @@ -140,6 +140,16 @@ sap.ui.define(["sap/base/security/URLListValidator"], function(URLListValidator) assert.notOk(URLListValidator.validate({}), "object is not a valid URL"); }); + QUnit.test("object urls", function(assert) { + var sUrlBase = "blob:[ORIGIN]/c56a4180-65aa-42ec-a945-5fd21dec0538"; + + var sUrlInvalid = sUrlBase.replace("[ORIGIN]", "http://www.sap.com"); + assert.notOk(URLListValidator.validate(sUrlInvalid), "object urls from another host are not valid"); + + var sUrlValid = sUrlBase.replace("[ORIGIN]", window.location.origin); + assert.ok(URLListValidator.validate(sUrlValid), "object urls from same host are valid"); + }); + QUnit.test("unknown protocol", function(assert) { var sUrl = "httpg://www.example.com"; assert.ok(URLListValidator.validate(sUrl), sUrl + " valid");