Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

### Fixed

- Resolve all 15 open Dependabot alerts in the employee mobile app's build tooling. node-forge 1.4.2 (lockfile only) fixes 12 advisories, including the one the local RSA backport covered, so that backport is removed. npm `overrides` move Expo's glob to 14.0.3 and minimatch to 11.0.3. deepmerge 4.3.1 has no upstream fix and gets a source-hashed backport that blocks `__proto__` poisoning. None of these packages ship in the app bundle.
- Enforce upload inbox quotas under SQLite's writer lock, including rejected files, and require each retained original to fit the remaining storage allowance. Identical-file duplicates consume no additional retained bytes.
- Align the employee mobile app with Expo SDK 58's supported dependency set: Expo 58.0.17 and TypeScript 6.0.3, preserving React 19.3.0, React Native 0.88.0 and the verified security backports.

Expand Down
4 changes: 2 additions & 2 deletions mobile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ After acceptance, share the approved native distribution links through the organ

Use designated test accounts on an HTTPS staging instance. Test real iPhone and Android builds for login, revoked/expired sessions, cold starts, background/foreground, clock-in/out retries, draft creation, entries, import, submit, rejected-sheet correction, and sign-out. Reviewers use the web review workspace. Check poor connectivity: an unconfirmed mutation should be refreshed and verified before retrying. The UI never claims an offline entry was saved.

The SDK 58.0.17 dependency tree removes the transitive UUID dependency through `xcode` 4.0.0, which uses Node's native UUID generator; the older scoped UUID override is no longer needed. The zod advisory (GHSA-mrhx-c7xc-m3w5) is fixed by an npm `overrides` entry that moves `@expo/cli`'s build-time zod to the patched 4.6.7 release. The remaining two underlying advisories have no published fixed npm version: `braces` 3.0.3 and `node-forge` 1.4.0 receive narrow, source-hashed backports during `npm ci`. Expo and React Native keep their supported versions. See [security backports](security/README.md) for provenance, regression coverage and removal instructions.
The SDK 58.0.17 dependency tree removes the transitive UUID dependency through `xcode` 4.0.0, which uses Node's native UUID generator; the older scoped UUID override is no longer needed. The zod advisory (GHSA-mrhx-c7xc-m3w5) is fixed by an npm `overrides` entry that moves `@expo/cli`'s build-time zod to the patched 4.6.7 release. `node-forge` resolves the fixed 1.4.2 release, and `overrides` move Expo's build-time `glob` and `minimatch` to the fixed 14.0.3 and 11.0.3 releases. The remaining two underlying advisories have no published fixed npm version: `braces` 3.0.3 and `deepmerge` 4.3.1 receive narrow, source-hashed backports during `npm ci`. Expo and React Native keep their supported versions. See [security backports](security/README.md) for provenance, regression coverage and removal instructions.

`npm run check` verifies the actual patched files and rejects any new/unexplained advisory. Raw `npm audit` still reports high findings (4 at the time of writing: `node-forge` and its dependents `@expo/code-signing-certificates`, `@expo/cli` and `expo`) because it identifies upstream versions; the report is retained in `dist/dependency-security.json` with the verified backports. These are not hidden findings or a claim that the registry audit is clean. Run the checks again immediately before signing, and complete real-device acceptance.
`npm run check` verifies the actual patched files and rejects any new/unexplained advisory. Raw `npm audit` still reports the backported `braces` and `deepmerge` findings and their dependents because it identifies upstream versions; the report is retained in `dist/dependency-security.json` with the verified backports. These are not hidden findings or a claim that the registry audit is clean. Run the checks again immediately before signing, and complete real-device acceptance.

See [staff timesheets](../docs/employee-timesheets.md) for account provisioning, web installation, server deployment, and the full API contract.

Expand Down
65 changes: 50 additions & 15 deletions mobile/package-lock.json

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

2 changes: 2 additions & 0 deletions mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"typescript": "~7.0.2"
},
"overrides": {
"glob": "14.0.3",
"minimatch": "11.0.3",
"zod": "4.6.7"
}
}
2 changes: 1 addition & 1 deletion mobile/scripts/security-backports.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ export function verifyBackports({ apply = false } = {}) {
}
if (process.argv[1] && existsSync(process.argv[1]) && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
verifyBackports({ apply: process.argv.includes('--apply') });
console.log('Pinned braces/node-forge security backports verified.');
console.log('Pinned braces/deepmerge security backports verified.');
}
9 changes: 6 additions & 3 deletions mobile/security/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ Expo 58.0.17 / React Native 0.88.0 stay on the SDK-supported dependency matrix.
| --- | --- |
| [UUID buffer bounds, GHSA-w5hq-g745-h8pq](https://github.com/advisories/GHSA-w5hq-g745-h8pq) | Expo's compatible dependency tree now uses `xcode` 4.0.0, which removes UUID in favor of Node's `crypto.randomUUID()`. The obsolete override is removed; tests verify dependency removal and unique 24-character project identifiers. See [upstream release notes](https://github.com/apache/cordova-node-xcode/blob/4.0.0/RELEASENOTES.md). |
| [braces recursion, GHSA-vfj7-8cjw-p6xm](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm) | Upstream 3.0.3 has no published fix. Locally bound parser nesting and all three recursive AST walkers (compile, expand, stringify) to 256 levels. Iterative validation rejects cycles while ignoring normal `parent`/`prev` links. Tests reject deep balanced/unbalanced strings, deep ASTs and cycles, and preserve normal brace/glob results. |
| [node-forge DigestInfo validation, GHSA-86w9-cpqp-85rv](https://github.com/advisories/GHSA-86w9-cpqp-85rv) | Upstream 1.4.0 has no published fix. Reject extra DigestAlgorithm children and nonempty NULL parameters in RSA PKCS#1 v1.5 verification. Ephemeral-key regression tests reject signed malformed ASN.1, accept valid signatures with optional NULL and reject a wrong digest. |
| [node-forge DigestInfo validation, GHSA-86w9-cpqp-85rv](https://github.com/advisories/GHSA-86w9-cpqp-85rv), plus GHSA-5x38-2vff-x55p, GHSA-hqq3-7jhf-c5jx, GHSA-8hrf-8g6f-7xwp, GHSA-jc66-7q78-782g, GHSA-7wch-p9px-956x, GHSA-5cwg-6vw7-rj6p, GHSA-525v-9gp9-w22h, GHSA-6wvx-3r32-xmcg, GHSA-4487-j8r4-4g2f, GHSA-h6cr-wjv9-3cpp, GHSA-4642-5mcj-2rqw | Fixed upstream; the local backport is retired. Lockfile now resolves node-forge **1.4.2** (inside Expo's `^1.4.0`). 1.4.1 fixes the eleven advisories published for `<= 1.4.0`; 1.4.2 re-encodes the DigestInfo canonically and compares bytes (RFC 8017 8.2.2), which rejects extra DigestAlgorithm children and nonempty NULL parameters. The existing ephemeral-key regression test now runs unpatched against 1.4.2. Only `@expo/cli` (dev-server certificates) and `@expo/code-signing-certificates` use it; neither ships in the app. |
| [glob abort bypass, GHSA-3g3m-2fjr-6pw4](https://github.com/advisories/GHSA-3g3m-2fjr-6pw4) | Fixed upstream in glob 14.0.2; Expo SDK 58 still declares `glob ^13`, which has no fix. `package.json` `overrides` pins glob **14.0.3**. Expo's calls (`glob()`/`globSync()` with `cwd`, `ignore`, `absolute`, `dot`, `signal`) are unchanged in 14; none of Expo's `ignore` patterns start with `/`, the one semantic change. Tests run Expo CLI's own TypeScript-file glob and an aborted walk. Build-time only (`expo start`/`export`/`prebuild`, config plugins, fingerprint). Remove the override when Expo depends on glob 14.0.2 or later. |
| [minimatch pattern amplification, GHSA-g3hv-75wg-m249](https://github.com/advisories/GHSA-g3hv-75wg-m249) | Fixed upstream in minimatch 11.0.1; glob 13 and `@expo/fingerprint` declare `^10`. `package.json` `overrides` pins minimatch **11.0.3** (11.0.4 also drops Node 18 and was under a day old). 11 removes `makeRe()`, `Minimatch#regexp` and `AST`; no Expo package uses them. `@expo/fingerprint` uses only `new Minimatch()`, `.match()`, `.pattern` and `.negate`, which tests exercise with its default ignore patterns and a negation. Patterns come from Expo and the project, not users. Remove the override with glob's. |
| [deepmerge prototype poisoning, GHSA-gcqx-w48m-w2h4](https://github.com/advisories/GHSA-gcqx-w48m-w2h4) | Upstream 4.3.1 is the latest release and has no fix. Local backport in `dist/cjs.js` (the package's only entry point): `getKeys()` never returns an own `__proto__` key, so a `JSON.parse`d target or source cannot replace the merged object's prototype. Normal key, array and symbol merges are unchanged. Only `@expo/config` uses it, to merge the project's own app config at build time. Tests cover target, source, nested and `deepmerge.all` poisoning plus a normal config merge. |
| [zod oversized collections, GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5) | Fixed upstream, no backport. Only `@expo/cli` (build-time dev-tools plugin schemas, not shipped in the app) depends on zod, declared as `^3.25.76`; no 3.x release has the fix. `package.json` `overrides` pins zod 4.6.7 (fix landed in 4.6.6). The CLI's schemas use only APIs zod 4 keeps; tests check the resolved version, run those CLI schemas under zod 4 and keep the oversized-collection regressions. Remove the override when Expo depends on zod 4.6.6 or later. |

These are local backports, not newly published upstream releases. Sources: [braces report](https://github.com/micromatch/braces/issues/70), [forge report](https://github.com/digitalbazaar/forge/issues/1149) and [upstream nested-length proposal](https://github.com/digitalbazaar/forge/pull/1152). The additional empty-NULL check prevents ignored bytes inside that primitive. This change does not redesign the cryptographic library.
These are local backports, not newly published upstream releases. Sources: [braces report](https://github.com/micromatch/braces/issues/70) and the [deepmerge advisory](https://github.com/advisories/GHSA-gcqx-w48m-w2h4).

`backports.json` records exact upstream versions, before/after SHA-256 hashes and minimal replacement text. `postinstall` validates all sources before writing; repeated application is idempotent. Unknown versions or modified sources fail closed. Do not skip install scripts. `verify:security` also fails if any reviewed patched file is missing or altered, so bypassing postinstall cannot pass `npm run check`.

`audit:security` verifies source hashes, fetches the current npm advisory graph, and permits only the exact advisory URLs above and packages whose findings resolve to those verified backports. New advisories, unexplained findings and audit network failures fail the check. The full raw registry report and the disposition are retained in `dist/dependency-security.json` and in CI's unsigned export artifact. As of this update, raw npm audit still reports 4 high findings: `node-forge` 1.4.0 and its dependents. The verified patched-source gate reports zero unremediated advisories; it does not alter package versions or suppress npm's report.
`audit:security` verifies source hashes, fetches the current npm advisory graph, and permits only the exact advisory URLs above and packages whose findings resolve to those verified backports. New advisories, unexplained findings and audit network failures fail the check. The full raw registry report and the disposition are retained in `dist/dependency-security.json` and in CI's unsigned export artifact. As of this update, raw npm audit reports only the backported `braces` and `deepmerge` findings and their dependents. The verified patched-source gate reports zero unremediated advisories; it does not alter package versions or suppress npm's report.

Before signing, run `npm ci`, `npm run check`, Expo Doctor and both normal Hermes exports. Recheck upstream releases: once a compatible fixed version exists, replace its backport with the supported dependency update, remove its manifest entries and advisory allowance together, then rerun the exploit regressions, Expo compatibility, native prebuild and both platform exports. Never add a new allowance without a reviewed source fix and meaningful regression coverage.
Loading
Loading