Skip to content

Commit

Permalink
Documentation & updated CSP
Browse files Browse the repository at this point in the history
  • Loading branch information
corrideat committed Jun 26, 2024
1 parent 6005591 commit 037311e
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 7 deletions.
139 changes: 139 additions & 0 deletions AUDITING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Auditing

## Purpose of this document

This document is meant to highlight security-relevant aspects of this tool that
might be relevant to facilitate a rigorous audit process.

## Data exfiltration

These are some of the built-in protections to prevent data exfiltration.

### Content Security Policy (CSP)

Content Security Policy (CSP) is used to limit communication with the outside
world. In particular, no external resources are allowed to be loaded. You can
verify this by assessing the contents of the corresponding `<meta>` tag and note
that no external content is allowed.

### Navigation

- **`window.open`:** `window.open`, or similar functions that can be used to
make requests to external resources, is not used.
- **Form submissions:** No forms with an external `action` are used. This is
further enforced with CSP.
- Links: Links to external resources use statically-defined URLs that do not
depend on user input. No links to external resources are opened without user
interaction.

### Dynamic resource loading

- **`fetch()` / `XMLHttpRequest`:** Only used on local resources. Also
restricted by CSP.
- **`import()`:** Not used. Also restricted by CSP.
- **`ping` attribute**: Not used. Also restricted by CSP.
- **Other dynamic resources**: Not used. Also restricted by CSP.

### Additional measures

All cryptographic operations are sandboxed where possible. This places
additional restrictions on the flow of data.

## Correctness

### Cryptographic primitives

This application relies on the primitives exposed by the `SubtleCypto` API, and
the cryptographic operations used are restricted to what is needed to construct
and parse a Cryptographic Message Syntax (CMS) payload.

The following methods of the `SubtleCypto` API are used:

- **`decrypt`:** When decrypting a file, this function is used to decrypt the
Content Encryption Key (CEK) with a password-derived Key Encryption Key (KEK),
and to use that CEK to decrypt the file and file name.
- **`deriveKey`:** When encrypting or decrypting a file, this function is used
to derive the Key Encryption Key (KEK) from a user-supplied password.
- **`encrypt`:** When encrypting a file, this function is used to encrypt the
Content Encryption Key (CEK) with a password-derived Key Encryption Key (KEK),
and to use that CEK to encrypt the file and file name.
- **`exportKey`:** When encrypting a file, this function is used to export the
randomly-generated Content Encryption Key (CEK). This is needed so that it can
then be encrypted using the Key Encryption Key (KEK) and included, in
encrypted form, in the CMS payload.
- **`generateKey`:** When encrypting a file, this function is used to generate
a random AES-256-GCM Content Encryption Key (CEK), which is subsequently used
to encrypt user-supplied data.
- **`importKey`:** When encrypting or decrypting a file, this function is used
on the user-supplied password in order to derive the Key Encryption Key (KEK).
Additionally, when decrypting a file, this function is used to import the
Content Encryption Key (CEK) after it has been decrypted.

In addition, the `getRandomValues` method of the `Crypto` API is used as an
entropy source when encrypting a file. This is used to derive a salt, used in
the KEK derivation process, as well as to generate initialisation vectors (IVs)
for encrypted payloads.

### Password-based key derivation

The user-supplied password is used to derive the Key Encryption Key (KEK) using
the PBKDF2 algorithm. This is implemented in the file `src/lib/deriveKEK.ts`.

### Data encryption and decryption

#### Data encryption

User-supplied data (file and file name) are encrypted in two separate steps, one
for file contents and another for a file name. The base implementation for
encryption can be found in the file `src/lib/fileEncryptionCms.ts`. In addition,
the file `src/sandbox/fileEncryptionCms.ts` implements the two distinct steps
used for contents and name.

#### Data decryption

User-supplied data (file and file name) are decrypted in two separate steps, one
for file contents and another for a file name. The base implementation for
decryption can be found in the file `src/lib/fileDecryptionCms.ts`. In addition,
the file `src/sandbox/fileDecryptionCms.ts` implements the two distinct steps
used for contents and name.

#### Initialisation vector (IV) reuse

Because this application uses AES-256-GCM, it is of paramount importance that
initialisation vectors are not reused. This is accomplished by generating fresh
initialisation vectors each time one is needed.

#### Other relevant files

- **`src/lib/constructCmsData.ts`:** This file implements construction of a
CMS payload (used after encryption). It does not handle unprotected user data,
but is used to produce a payload that is derived from user input.
- **`src/lib/fixBrokenSandboxSecureContext.ts`:** This file is used to define
various methods provided by the `SubtleCrypto` API if they are not available.
Certain browsers do not consider the sandboxed environment a _secure context_,
which means that the `SubtleCrypto` API is not available. In those cases, this
file is used to define those methods with an external implementation, provided
by the top document. While this is necessary in these situations, it negates
some of isolation that a fully sandboxed environment would provide.
- **`src/lib/parseCmsData.ts`:** This file implements partial parsing of a CMS
payload (used before decryption). It does not handle unprotected user data,
but it receives user-supplied input that will ultimately be used to recover
encrypted user data.
- **`src/lib/setupConstructCmsSandbox.ts`:** This file implements the creation
of a sandbox for constructing a CMS payload. The sandbox entrypoint is that
from `src/sandbox/constructCmsData.ts`.
- **`src/lib/setupDecryptionSandbox.ts`:** This file implments the creation of
two sandboxes used during decryption, one to derive the KEK and another one to
decrypt data. The sandbox entrypoints are those from
`src/sandbox/deriveKEK.ts` and `src/lib/fileDecryptionCms.ts`.
- **`src/lib/setupEncryptionSandbox.ts`:** This file implments the creation of
two sandboxes used during encryption, one to derive the KEK and another one to
encrypt data. The sandbox entrypoints are those from
`src/sandbox/deriveKEK.ts` and `src/lib/fileEncryptionCms.ts`.
- **`src/lib/setupParseCmsSandbox.ts`:** This file implements the creation
of a sandbox for parsing a CMS payload. The sandbox entrypoint is that
from `src/sandbox/parseCmsData.ts`.
- **`src/sandbox/constructCmsData.ts`:** Wrapper around
`src/lib/constructCmsData.ts`.
- **`src/sandbox/deriveKEK.ts`:** Wrapper around `src/sandbox/deriveKEK.ts`.
- **`src/sandbox/parseCmsData.ts`:** Wrapper around `src/lib/parseCmsData.ts`.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Using this secure file sharing utility is simple:
- Share the generated HTML file with your recipient.

3. **Decrypt the File**:

- Your recipient can open the HTML file in their browser.
- They will be prompted to enter the password you provided and will need to
click on the "Next &#x2192;" button to decrypt the file and confirm details
Expand All @@ -65,6 +66,21 @@ decrypted content.
Want to see how it works? Check out the live demo at
<https://cms-sfx-demo.exact.realty>.

## 🌐 Browser Support

The following is a non-comprehensive list of browsers that have been tested.
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–

## 🔒 Security Considerations

This utility is designed with security in mind. By using the CMS standard, PWRI,
Expand All @@ -77,6 +93,9 @@ security of this tool _greatly_ depend on the strength of the password you
choose. We recommend using a strong, unique password to protect your files.
Weak or compromised passwords can put your data at risk.

For more detailed information about the security of this tool and how it works,
see [`AUDITING.md`](./AUDITING.md).

## ❗️ Disclaimer

This tool is provided in the hope that it will be helpful, but it comes with
Expand Down Expand Up @@ -113,7 +132,7 @@ or feature requests, please feel free to submit them.

This project is licensed under the Apache 2.0 License with the LLVM exception.
You are free to use this package in compliance with the terms of the license.
For more information, see the `LICENSE` file.
For more information, see the [`LICENSE`](./LICENSE) file.

We hope you find this secure file sharing utility useful! If you have any
questions or feedback, please don't hesitate to reach out.
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.6",
"version": "1.0.7",
"description": "Secure File Sharing Utility",
"type": "module",
"main": "-",
Expand Down
7 changes: 6 additions & 1 deletion src/fallbackMessage.inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ self.onerror = function (
return false;
} as unknown as Window['onerror'];

if (typeof Reflect === [] + [][0])
if (
typeof Reflect === [] + [][0] ||
typeof Blob !== 'function' ||
!Blob.prototype ||
typeof Blob.prototype.arrayBuffer !== 'function'
)
self.onload = function (
_document: Document,
_body$: HTMLElement,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/generateHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const generateHtml_ = async (
' http-equiv="content-security-policy"' +
// Safari / WebKit seem to require frame-ancestors 'self' for starting
// sandboxes
` content="default-src 'none'; script-src 'self' 'unsafe-eval' data:; script-src-elem blob: data: '${fallbackMessage.sri}' '${loader.sri}' '${mainScriptTextSriDigest}'; script-src-attr 'none'; style-src data: '${cssTextSriDigest}'; child-src blob:; connect-src blob: data:; frame-ancestors 'self'; form-action data:"` +
` content="default-src 'none'; script-src 'self' 'unsafe-eval' blob: data:; script-src-elem blob: data: '${fallbackMessage.sri}' '${loader.sri}' '${mainScriptTextSriDigest}'; script-src-attr 'none'; style-src data: '${cssTextSriDigest}'; child-src blob:; connect-src blob: data:; frame-src blob:; worker-src blob:; frame-ancestors 'self'; form-action data:"` +
'/>' +
`<title>HTML CMS Tool</title>` +
`<script src="data:text/javascript;base64,${xmlEscapeAttr(fallbackMessage.contentBase64)}" integrity="${xmlEscapeAttr(fallbackMessage.sri)}" crossorigin="anonymous">` +
Expand Down
2 changes: 1 addition & 1 deletion src/utils/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const server = http.createServer((req, res) => {
['content-type', 'text/html; charset=UTF-8'],
[
'content-security-policy',
"default-src 'none'; script-src 'self' 'unsafe-eval' data:; script-src-elem blob: data:; script-src-attr 'none'; style-src data:; child-src blob:; connect-src blob: data:; frame-ancestors 'self'; form-action 'self' data:",
"default-src 'none'; script-src 'self' 'unsafe-eval' blob: data:; script-src-elem blob: data:; script-src-attr 'none'; style-src data:; child-src blob:; connect-src blob: data:; frame-src blob:; worker-src blob:; frame-ancestors 'self'; form-action 'self' data:",
],
[
'permissions-policy',
Expand Down

0 comments on commit 037311e

Please sign in to comment.