Skip to content

Commit

Permalink
Improved backwards compatibility
Browse files Browse the repository at this point in the history
* Use `FileReader` instead of `File.prototype.arrayBuffer`
* Avoid using `globalThis`
  • Loading branch information
corrideat committed Jun 27, 2024
1 parent 037311e commit d83ef7b
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 50 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ Even though we have tested with older versions for compatibility support and
reporting, we strongly recommend using up-to-date browsers that still receive
security updates.

- Chrome: ✅️ 77–
- Edge: ✅️ 79–
- Firefox: ✅️ 69
- Internet Explorer: ❌ Not supported
- Opera: ✅️ 63–
- Pale Moon: ❌ Not supported [yet](https://repo.palemoon.org/MoonchildProductions/UXP/issues/2534)
- Safari: ✅️ 14–
- Chrome: ✅️ 77–
- Edge: ✅️ 79–
- Firefox: ✅️ 65
- Internet Explorer: ❌ Not supported
- Opera: ✅️ 63–
- Pale Moon: ❌ Not supported [yet](https://repo.palemoon.org/MoonchildProductions/UXP/issues/2534)
- Safari: ✅️ 14–

## 🔒 Security Considerations

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@exact-realty/cms-ep-sfx",
"version": "1.0.7",
"version": "1.0.8",
"description": "Secure File Sharing Utility",
"type": "module",
"main": "-",
Expand Down
15 changes: 12 additions & 3 deletions src/fallbackMessage.inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,18 @@ self.onerror = function (

if (
typeof Reflect === [] + [][0] ||
typeof Blob !== 'function' ||
!Blob.prototype ||
typeof Blob.prototype.arrayBuffer !== 'function'
typeof globalThis === [] + [][0] ||
typeof AbortController !== 'function' ||
typeof Promise !== 'function' ||
!Promise.prototype ||
typeof Promise.prototype.finally !== 'function' ||
typeof Blob !== 'function'
// There's also <https://bugzilla.mozilla.org/show_bug.cgi?id=1469045>,
// <https://bugzilla.mozilla.org/show_bug.cgi?id=1502801>,
// <https://repo.palemoon.org/MoonchildProductions/UXP/issues/2534>, but
// feature detecting that (message from iframe has isTrusted = false) is
// more involved
// Detecting globalThis might work in this case
)
self.onload = function (
_document: Document,
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/// <reference types="svelte" />

import App from '~/App.svelte';
import { ROOT_ELEMENT_ID_ } from '~/lib/elementIds.js';
import { ERROR_ELEMENT_ID_, ROOT_ELEMENT_ID_ } from '~/lib/elementIds.js';
import isCI from '~/lib/isCI.js';

const onLoad = (handler: { (): void }) => {
Expand Down Expand Up @@ -97,7 +97,7 @@ onLoad(() => {
}

window.onerror = null;
const error$ = document.getElementById('error');
const error$ = document.getElementById(ERROR_ELEMENT_ID_);
if (error$?.parentElement) {
error$.parentElement.removeChild(error$);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

const newId = () => {
const buf = new Uint8Array(16);
globalThis.crypto.getRandomValues(buf);
crypto.getRandomValues(buf);
return Array.from(buf)
.map((c) => c.toString(16).padStart(2, '0'))
.join('');
Expand Down
6 changes: 3 additions & 3 deletions src/lib/deriveKEK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ const deriveKEK_ = async (

if (!salt) {
const saltBuffer = new Uint8Array(32);
globalThis.crypto.getRandomValues(saltBuffer);
crypto.getRandomValues(saltBuffer);
salt = saltBuffer;
}

const KEK = await globalThis.crypto.subtle
const KEK = await crypto.subtle
.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, [
'deriveKey',
])
.then((baseKey) => {
return globalThis.crypto.subtle.deriveKey(
return crypto.subtle.deriveKey(
{
['name']: 'PBKDF2',
['salt']: salt,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/fileDecryptionCms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const fileDecryptionCms_ = async (
): Promise<AllowSharedBufferSource> => {
const KEK = await deriveKEK();

const rawCEK = await globalThis.crypto.subtle.decrypt(
const rawCEK = await crypto.subtle.decrypt(
{
['name']: 'AES-GCM',
['iv']: noncePWRI,
Expand All @@ -33,14 +33,14 @@ const fileDecryptionCms_ = async (
KEK,
encryptedKey,
);
const CEK = await globalThis.crypto.subtle.importKey(
const CEK = await crypto.subtle.importKey(
'raw',
rawCEK,
{ ['name']: 'AES-GCM', ['length']: 256 },
false,
['decrypt'],
);
const data = await globalThis.crypto.subtle.decrypt(
const data = await crypto.subtle.decrypt(
{
['name']: 'AES-GCM',
['iv']: nonceECI,
Expand Down
35 changes: 17 additions & 18 deletions src/lib/fileEncryptionCms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ const fileEncryptionCms_ = async (
const noncePWRI = new Uint8Array(12);
const nonceECI = new Uint8Array(12);

globalThis.crypto.getRandomValues(noncePWRI);
globalThis.crypto.getRandomValues(nonceECI);
crypto.getRandomValues(noncePWRI);
crypto.getRandomValues(nonceECI);

const [encryptedKey, encryptedContent] = await globalThis.crypto.subtle
const [encryptedKey, encryptedContent] = await crypto.subtle
.generateKey({ ['name']: 'AES-GCM', ['length']: 256 }, true, [
'encrypt',
])
Expand All @@ -49,21 +49,20 @@ const fileEncryptionCms_ = async (
});

return Promise.all([
Promise.all([
KEKp,
globalThis.crypto.subtle.exportKey('raw', CEK),
]).then(([KEK, rawCEK]) => {
return globalThis.crypto.subtle.encrypt(
{
['name']: 'AES-GCM',
['iv']: noncePWRI,
['tagLength']: 128,
},
KEK,
rawCEK,
);
}),
globalThis.crypto.subtle.encrypt(
Promise.all([KEKp, crypto.subtle.exportKey('raw', CEK)]).then(
([KEK, rawCEK]) => {
return crypto.subtle.encrypt(
{
['name']: 'AES-GCM',
['iv']: noncePWRI,
['tagLength']: 128,
},
KEK,
rawCEK,
);
},
),
crypto.subtle.encrypt(
{
['name']: 'AES-GCM',
['iv']: nonceECI,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/fixBrokenSandboxSecureContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ declare const external$exportKey: SubtleCrypto['exportKey'] | undefined;
declare const external$generateKey: SubtleCrypto['generateKey'] | undefined;
declare const external$importKey: SubtleCrypto['importKey'] | undefined;

if (!globalThis.crypto.subtle) {
if (!crypto.subtle) {
console.warn(
'SubtleCrypto is not available. External (unsandboxed) calls will be used instead.',
);
Expand Down Expand Up @@ -62,7 +62,7 @@ if (!globalThis.crypto.subtle) {
assign('importKey', external$importKey);
}

Object.defineProperty(globalThis.crypto, 'subtle', {
Object.defineProperty(crypto, 'subtle', {
['configurable']: true,
['value']: Object.create(subtlePrototypePolyfill),
});
Expand Down
5 changes: 1 addition & 4 deletions src/lib/generateHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ const bbtoa = (buf: AllowSharedBufferSource) => {
};

const sriDigest = async (buf: AllowSharedBufferSource) => {
const digest = await globalThis.crypto.subtle.digest(
{ ['name']: 'SHA-384' },
buf,
);
const digest = await crypto.subtle.digest({ ['name']: 'SHA-384' }, buf);

return 'sha384-' + bbtoa(digest);
};
Expand Down
2 changes: 1 addition & 1 deletion src/lib/getWrappedCryptoFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type TIndirectCryptoKey = string;

const getWrappedCryptoFunctions_ = () => {
const keyCache = new Cache<CryptoKey>();
const subtle = globalThis.crypto.subtle;
const subtle = crypto.subtle;

const decrypt = async (
algorithm:
Expand Down
4 changes: 2 additions & 2 deletions src/pages/decrypt.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
.then(async () => {
const stage1AbortController = new AbortController();
const abortHandler = () => stage1AbortController.abort();
abortController.signal.addEventListener(
abortController.signal?.addEventListener(
'abort',
abortHandler,
false,
Expand Down Expand Up @@ -151,7 +151,7 @@
initError = new Error(message);
throw initError;
} finally {
abortController.signal.removeEventListener(
abortController.signal?.removeEventListener(
'abort',
abortHandler,
false,
Expand Down
11 changes: 10 additions & 1 deletion src/pages/encrypt.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,16 @@
? parseInt(_userIterationCount[1])
: defaultIterationCount;
const buffer = await _file.arrayBuffer();
const buffer = await new Promise<ArrayBuffer>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onerror = () => {
reject(fileReader.error);
};
fileReader.onload = () => {
resolve(fileReader.result as ArrayBuffer);
};
fileReader.readAsArrayBuffer(_file);
});
if (
typeof cmsSandbox !== 'function' ||
Expand Down

0 comments on commit d83ef7b

Please sign in to comment.