diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
commit | def92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch) | |
tree | 2ef34b9ad8bb9a9220e05d60352558b15f513894 /dom/manifest | |
parent | Adding debian version 125.0.3-1. (diff) | |
download | firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/manifest')
-rw-r--r-- | dom/manifest/Manifest.sys.mjs | 37 | ||||
-rw-r--r-- | dom/manifest/test/browser_Manifest_install.js | 45 |
2 files changed, 76 insertions, 6 deletions
diff --git a/dom/manifest/Manifest.sys.mjs b/dom/manifest/Manifest.sys.mjs index 15e1e2ef93..97f786318f 100644 --- a/dom/manifest/Manifest.sys.mjs +++ b/dom/manifest/Manifest.sys.mjs @@ -29,11 +29,11 @@ ChromeUtils.defineESModuleGetters(lazy, { * @note The generated hash is returned in base64 form. Mind the fact base64 * is case-sensitive if you are going to reuse this code. */ -function generateHash(aString) { +function generateHash(aString, hashAlg) { const cryptoHash = Cc["@mozilla.org/security/hash;1"].createInstance( Ci.nsICryptoHash ); - cryptoHash.init(Ci.nsICryptoHash.MD5); + cryptoHash.init(hashAlg); const stringStream = Cc[ "@mozilla.org/io/string-input-stream;1" ].createInstance(Ci.nsIStringInputStream); @@ -66,11 +66,39 @@ class Manifest { this._manifestUrl = manifestUrl; // The key for this is the manifests URL that is required to be unique. // However arbitrary urls are not safe file paths so lets hash it. - const fileName = generateHash(manifestUrl) + ".json"; - this._path = PathUtils.join(MANIFESTS_DIR, fileName); + const filename = + generateHash(manifestUrl, Ci.nsICryptoHash.SHA256) + ".json"; + this._path = PathUtils.join(MANIFESTS_DIR, filename); this.browser = browser; } + /** + * See Bug 1871109 + * This function is called at the beginning of initialize() to check if a given + * manifest has MD5 based filename, if so we remove it and migrate the content to + * a new file with SHA256 based name. + * This is done due to security concern, as MD5 is an outdated hashing algorithm and + * shouldn't be used anymore + */ + async removeMD5BasedFilename() { + const filenameMD5 = + generateHash(this._manifestUrl, Ci.nsICryptoHash.MD5) + ".json"; + const MD5Path = PathUtils.join(MANIFESTS_DIR, filenameMD5); + try { + await IOUtils.copy(MD5Path, this._path, { noOverwrite: true }); + } catch (error) { + // we are ignoring the failures returned from copy as it should not stop us from + // installing a new manifest + } + + // Remove the old MD5 based file unconditionally to ensure it's no longer used + try { + await IOUtils.remove(MD5Path); + } catch { + // ignore the error in case MD5 based file does not exist + } + } + get browser() { return this._browser; } @@ -80,6 +108,7 @@ class Manifest { } async initialize() { + await this.removeMD5BasedFilename(); this._store = new lazy.JSONFile({ path: this._path, saveDelayMs: 100 }); await this._store.load(); } diff --git a/dom/manifest/test/browser_Manifest_install.js b/dom/manifest/test/browser_Manifest_install.js index d3b949be19..aad43e0263 100644 --- a/dom/manifest/test/browser_Manifest_install.js +++ b/dom/manifest/test/browser_Manifest_install.js @@ -23,18 +23,59 @@ function makeTestURL() { return url.href; } +function generateHash(aString, hashAlg) { + const cryptoHash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + cryptoHash.init(hashAlg); + const stringStream = Cc[ + "@mozilla.org/io/string-input-stream;1" + ].createInstance(Ci.nsIStringInputStream); + stringStream.data = aString; + cryptoHash.updateFromStream(stringStream, -1); + // base64 allows the '/' char, but we can't use it for filenames. + return cryptoHash.finish(true).replace(/\//g, "-"); +} + +const MANIFESTS_DIR = PathUtils.join(PathUtils.profileDir, "manifests"); + add_task(async function () { const tabOptions = { gBrowser, url: makeTestURL() }; + const filenameMD5 = generateHash(manifestUrl, Ci.nsICryptoHash.MD5) + ".json"; + const filenameSHA = + generateHash(manifestUrl, Ci.nsICryptoHash.SHA256) + ".json"; + const manifestMD5Path = PathUtils.join(MANIFESTS_DIR, filenameMD5); + const manifestSHAPath = PathUtils.join(MANIFESTS_DIR, filenameSHA); + await BrowserTestUtils.withNewTab(tabOptions, async function (browser) { - let manifest = await Manifests.getManifest(browser, manifestUrl); - is(manifest.installed, false, "We haven't installed this manifest yet"); + let tmpManifest = await Manifests.getManifest(browser, manifestUrl); + is(tmpManifest.installed, false, "We haven't installed this manifest yet"); + + await tmpManifest.install(); + // making sure the manifest is actually installed before proceeding + await tmpManifest._store._save(); + await IOUtils.move(tmpManifest.path, manifestMD5Path); + + let exists = await IOUtils.exists(tmpManifest.path); + is( + exists, + false, + "Manually moved manifest from SHA256 based path to MD5 based path" + ); + Manifests.manifestObjs.delete(manifestUrl); + + let manifest = await Manifests.getManifest(browser, manifestUrl); await manifest.install(browser); is(manifest.name, "hello World", "Manifest has correct name"); is(manifest.installed, true, "Manifest is installed"); is(manifest.url, manifestUrl, "has correct url"); is(manifest.browser, browser, "has correct browser"); + is(manifest.path, manifestSHAPath, "has correct path"); + + exists = await IOUtils.exists(manifestMD5Path); + is(exists, false, "MD5 based manifest removed"); manifest = await Manifests.getManifest(browser, manifestUrl); is(manifest.installed, true, "New instances are installed"); |