Skip to content

Resolve 39 of 40 Dependabot alerts on Expo SDK 57 and rewrite the README - #36

Merged
erickdronski merged 6 commits into
mainfrom
security/dependency-remediation-2026-10
Oct 6, 2026
Merged

erickdronski merged 6 commits into
mainfrom
security/dependency-remediation-2026-10

Conversation

@erickdronski

Copy link
Copy Markdown
Owner

Problem

  • 40 open Dependabot alerts (31 high, 9 medium) and npm audit reporting 36 vulnerable packages (1 critical, 28 high, 7 moderate) from 37 distinct advisories.
  • npm run verify fails on main today: expo install --check reports SDK 57 patch drift (Expo has shipped newer SDK 57 patches). Every single-package Dependabot PR that ran Verify since mid-August failed on that step, not on its own change.
  • 11 open Dependabot PRs, several of which can never pass because the grouped production PR (Bump the production-dependencies group across 1 directory with 33 updates #32) jumps SDK-pinned packages to versions SDK 57 does not support.
  • The README promised "free" and "no advertising" (the app stopped promising both in 46b3d0e) and described records as local, while the app backs its state up to Supabase whenever a session exists.

Approach

Each commit is a separate, verifiable step and stays on Expo SDK 57:

  1. npx expo install --fix moves expo 57.0.27, expo-router 57.0.25, react-native 0.86.3, reanimated 4.5.1, worklets 0.10.1 and the other expo-* modules to the versions SDK 57 expects. This alone makes expo install --check pass again and pulls patched nanoid and compression through the newer @expo/cli.
  2. npm update within existing semver ranges refreshes the lockfile, and the sharp and vitest floors move to their patched releases. This clears @xmldom/xmldom (both 0.8 and 0.9 lines), brace-expansion (both lines), browserslist, baseline-browser-mapping, js-yaml, postcss, source-map-js, sharp, vitest/@vitest/mocker, shell-quote (critical), and drops image-size (metro 0.84.5 no longer uses it). npm audit fix (without --force) was tried afterwards and only reshuffles hoisting, so it is not applied. No overrides were needed; none of the remaining advisories has an override that works (see below).
  3. vitest 4.1.11 → 5.0.3 (dev-only). Tests, typecheck, and lint pass unchanged. This supersedes Bump vitest from 4.1.10 to 5.0.3 #35.
  4. Dependabot ignore rules: SDK-managed packages (expo, expo-*, @expo/*, eslint-config-expo: majors; react, react-dom, react-native, react-native-*, async-storage: majors and minors) are left to npx expo install --fix. Alerts are unaffected.
  5. README rewrite, with every claim checked against the code: status, features, a precise privacy model, architecture, Supabase surface, how to run, quality gates, and CI by actual triggers.
  6. CHANGELOG entries under Unreleased.

Audit: before → after

Source Critical High Moderate Total
Dependabot open alerts (before) 0 31 9 40
Dependabot open alerts (expected after merge) 0 0 1 1
npm audit packages (before) 1 28 7 36
npm audit packages (after) 0 18 3 21
npm audit distinct advisories (before) 1 29 7 37
npm audit distinct advisories (after) 0 2 1 3

The 21 remaining npm audit packages are three root advisories plus the packages that depend on them:

Advisory Package Why it remains
GHSA-86w9-cpqp-85rv (high) node-forge ≤ 1.4.0, via @expo/cli No patched release exists (1.4.0 is the latest). Used by the Expo CLI for dev-server certificates and manifest signing; not in the app bundle.
GHSA-vfj7-8cjw-p6xm (high) braces ≤ 3.0.3, via metro-file-map → micromatch No patched release exists (3.0.3 is the latest). Build-time only; the patterns come from project config, not user input.
GHSA-vcc3-ghjq-m6fr (moderate) decode-uri-component 0.2.2, via expo-router → query-string 7 The only fix (0.5.0) is ESM-only, and query-string 7 require()s it, so an override would break URL parsing at runtime. Fixed by expo-router 58, which ships with SDK 58; SDK 58 is still on npm's next tag, not latest. This is the one Dependabot alert (#11) that stays open.

npm audit flags expo, react-native, reanimated, and worklets themselves only because they sit above these three packages. Dependabot has not opened alerts for node-forge or braces yet; it may once it catches up, and neither has a fix to apply.

Dependabot PRs

Superseded by this branch; Dependabot should close them once this lands on main:

PR Update Version on this branch
#14 js-yaml → 4.3.2 4.3.2
#16 @xmldom/xmldom → 0.8.15 0.8.15 (and 0.9.12)
#19 postcss → 8.5.28 8.5.29
#21 nanoid → 3.3.19 3.3.20
#23 sharp → 0.35.4 0.35.5
#29 brace-expansion → 1.1.21 1.1.21 (and 5.0.12)
#33 browserslist → 4.29.3 4.29.3
#34 baseline-browser-mapping → 2.11.27 2.11.27
#35 vitest → 5.0.3 5.0.3

Not superseded:

  • Bump the production-dependencies group across 1 directory with 33 updates #32 (production group, 33 updates): its SDK 57 patch updates, supabase-js, i18next, react-i18next, and react-native-web land here, but it also carries expo-router 58, @expo/ui 58, react-native 0.87, gesture-handler 3, async-storage 3, worklets 0.13, and react 19.3, which SDK 57 does not support. Recommend closing it; the new ignore rules stop it from coming back.
  • Bump the development-dependencies group with 3 updates #7 (development group): @types/node is already newer here (26.6.4), but eslint 10 and eslint-import-resolver-typescript 4 are untested with eslint-config-expo 57. Recommend closing it or testing it on its own branch.

Validation

GitHub Actions is disabled for this repository, so this PR will show no CI checks. Everything below was run locally on the final commit. main requires the verify check, so merging needs Actions re-enabled or an admin bypass.

  • npm ci then npm run verify (exactly what verify.yml runs) on Node 22.23.3 with npm 10.9.9, matching setup-node@v7 with node-version: 22: lint ✓, typecheck ✓, 24/24 tests in 7 files ✓, content check ✓, backend contract ✓, expo install --check + expo config ✓. The same run on Node 24 also passes.
  • npx expo export --platform ios --platform android --platform web bundles all three platforms (iOS 5.9 MB and Android 6.1 MB Hermes bytecode, static web render of 31 HTML pages).
  • npx expo-doctor: 21/21 checks pass.
  • Native compile on a copy of the branch: expo prebuild --platform ios, pod install, and xcodebuild Debug for the iOS Simulator with Xcode 27.0 end in ** BUILD SUCCEEDED ** (compile only; not launched).
  • npm audit re-run on the final lockfile (table above).
  • Mermaid diagram in the README parses with mermaid 11; every relative link in the README resolves.
  • On-device TestFlight smoke test (owner).

Risk and rollout

  • No SDK major change. The native changes are Expo-sanctioned SDK 57 patch releases (react-native 0.86.0 → 0.86.3, reanimated 4.5.0 → 4.5.1, worklets 0.10.0 → 0.10.1). A TestFlight build should still be smoke-tested before release.
  • testflight.yml only has a workflow_dispatch trigger, so nothing here starts a build. verify.yml triggers on pull_request and pushes to main.
  • Roll back by reverting individual commits; each one stands alone.

🤖 Generated with Claude Code

erickdronski and others added 6 commits October 6, 2026 18:14
`expo install --check` (part of `npm run verify`) now fails on main
because Expo has shipped newer SDK 57 patch releases than the ones
pinned here. Every single-package Dependabot PR that ran Verify since
mid-August failed on this step rather than on its own change. Run
`npx expo install --fix` to move expo 57.0.27, expo-router 57.0.25,
react-native 0.86.3, reanimated 4.5.1, worklets 0.10.1 and the other
expo-* modules to the SDK 57 versions Expo expects.

This stays on SDK 57 with no major version changes. The newer
@expo/cli also brings in patched transitive releases:
- nanoid 3.3.16 -> 3.3.20 (GHSA-2v37-7h3g-55p8)
- compression 1.8.1 -> 1.8.2 (GHSA-vc2v-76pw-4v95)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run `npm update` within the existing semver ranges and raise the
sharp and vitest floors to their patched releases so a fresh resolve
cannot fall back to a vulnerable version. No major versions change.

Patched releases picked up:
- @xmldom/xmldom 0.8.13 -> 0.8.15 and 0.9.10 -> 0.9.12 (23 alerts)
- brace-expansion 5.0.7 -> 5.0.12 and 1.1.16 -> 1.1.21
- browserslist 4.28.5 -> 4.29.3
- baseline-browser-mapping 2.10.42 -> 2.11.27
- js-yaml 4.3.0 -> 4.3.2
- postcss 8.5.22 -> 8.5.29, source-map-js 1.2.1 -> 1.2.2
- sharp 0.35.3 -> 0.35.5 (libheif and librsvg advisories)
- vitest and @vitest/mocker 4.1.10 -> 4.1.11
- shell-quote 1.9.0 -> 1.12.0 (critical in npm audit)
- image-size leaves the tree: metro 0.84.5 no longer depends on it

npm audit across both commits: 36 (1 critical, 28 high, 7 moderate)
-> 21 (18 high, 3 moderate). Nothing left has a patched release
that is compatible with SDK 57; the pull request lists each one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vitest 4.1.11 already carries the @vitest/mocker path traversal fix,
but Dependabot keeps proposing the 5.x line (#35). The suite is plain
Node unit tests with no config file, and it passes unchanged on
vitest 5.0.3 along with typecheck and lint. vitest 5 requires Node
^22.12 or >=24, which matches the Node 22 used in CI.

The change is confined to the dev-only test toolchain; nothing in the
app bundle depends on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The grouped production PR (#32) bundles expo-router 58, @expo/ui 58,
react-native 0.87, gesture-handler 3, async-storage 3 and worklets
0.13 onto an SDK 57 app. Those versions fail `expo install --check`,
and the CHANGELOG records an earlier automated upgrade that crashed
the app at launch. Expo's guidance is to move SDK-managed packages
together with `npx expo install`.

Ignore major (and, for React Native packages, minor) version updates
for the SDK-managed set so the weekly group only carries changes the
SDK accepts. Dependabot alerts are unaffected; patch-level updates
still arrive; SDK upgrades stay a deliberate, tested change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The old README described Mend as free with no advertising, which the
app itself stopped promising in 46b3d0e (tests/positioning.test.ts now
forbids that wording). It also described "private local records" and
"explicit shared-space sync", while the app backs up its whole local
state to Supabase whenever any session exists, including the
anonymous account created when someone skips sign-in.

The new README covers who Mend is for, beta status (TestFlight only,
not on the App Store), features, and a privacy model taken from the
code: what is stored on device, the anonymous background account,
exactly what the backup and shared space send to Supabase, that data
is not end-to-end encrypted, the grant and RPC boundaries in the
migrations, and account deletion. It also documents the Expo Router
structure, the Supabase tables, RPCs and Edge Functions (noting that
mend-delete-account is deployed but its source is not in the repo),
how to run the app, every step of `npm run verify`, and the CI and
release workflows by their actual triggers.

The repository has no app screenshots yet, so the README uses the app
icon only rather than placeholder images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add the security updates, the vitest upgrade, the Dependabot ignore
rules and the README rewrite under Unreleased so the next tagged beta
lists them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@erickdronski erickdronski reopened this Oct 6, 2026
@erickdronski
erickdronski merged commit f5993af into main Oct 6, 2026
1 check passed
@erickdronski
erickdronski deleted the security/dependency-remediation-2026-10 branch October 6, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant