Files
BillyOutlast a8a82aeb76 ci: fix fallow SARIF upload, upstream-sync token dead end, guard coverage; refresh vuln docs (#124)
* ci: fix fallow SARIF, upstream-sync token dead end, guard coverage; refresh vuln docs

Four independent defects found while reviewing the open Dependabot queue.

fallow.yml
- `--format` and `--output` are the SAME option (`--output` is a documented
  alias of `--format`), so `--format sarif --output fallow.sarif` aborted with
  "the argument '--format <FORMAT>' cannot be used multiple times" and never
  wrote the file. The following `upload-sarif` step then failed with
  "Path does not exist: fallow.sarif", reddening `Fallow full scan` on master
  and on every PR. Use `--output-file` for the path.
- Pin the CLI to 3.27.0. A bare `npx fallow` resolves the `latest` dist-tag at
  run time and was observed returning 3.3.0 on one run and 3.27.0 on another,
  so the full scan could silently disagree with the `audit` job (which pins
  3.27.0 through the action's `version:` input).

upstream-sync.yml
- Org policy forces a read-only GITHUB_TOKEN and no SYNC_PAT secret exists, so
  `gh pr create` can never succeed ("Resource not accessible by integration")
  and the run failed with exit 1 every day. The branch is already pushed by
  that point, so degrade to a warning plus a ready-to-click compare URL in the
  step summary instead of failing.

check-lockfiles.js
- `newIDE/visual-tests/package-lock.json` existed on disk but was absent from
  the guard's list (10 lockfiles, 9 guarded). Added.

dependabot.yml
- Drop the `ignore:` block pinning electron to 32.x. Both manifests are now on
  the current release line (newIDE/electron-app 44.4.3, GDJS/Runtime/Electron
  44.3.0), so the block only suppressed legitimate updates.
- `exclude-patterns` on the newIDE/app weekly group: for 0.x packages a
  "minor" bump is breaking by semver convention, so the group silently carried
  migrations like three 0.160->0.186 and spine-pixi-v7 4.2->4.3 alongside real
  patch bumps. One such group PR grew into a 19-package migration.
- Raise newIDE/app's `open-pull-requests-limit` 5 -> 10; 6 PRs are already
  open there, so new ones were being suppressed at the source.

KNOWN_VULNS.md
- Rewritten against the live API and the manifests. The previous revision
  claimed the fork stays on electron 32.x with 47 advisories (it is on 44.4.3),
  and that all non-electron vulnerabilities were remediated (the API reports
  49 open alerts: 22 high, 25 medium, 2 low, across 18 packages).
- Documented two guard gaps: the `tar` floor (`< 6.2.1`) is bypassed by the
  guard's same-major rule while advisories cover `<= 7.5.17`, and
  newIDE/visual-tests was unguarded.
- Recorded the four no-patch advisories as accepted risk.

DEPENDABOT_PR_REMEDIATION_PLAN.md
- Full review of the 32 open PRs: 6 root causes, all reproduced locally, with
  fixes verified before being proposed.

* fix(deps): repair three lockfiles already desynced on master; gate lockfile sync in CI

`npm ci` hard-fails when package.json and package-lock.json disagree, but CI
only installed the directories some later job happened to need. Three lockfiles
had rotted on master without anything noticing:

  GDJS                        16 missing packages (@pixi/* 7.4.3)
  newIDE/electron-app/app      6 missing + 3 invalid (electron 44.4.3, @electron/get)
  SharedLibs/TileMapHelper    36 missing + 2 invalid (@webassemblyjs/*, terser)

Each only failed the moment someone tried to install in that directory — which
is how the GDJS one stayed invisible while PR #121 was being reviewed for an
unrelated reason.

Regenerated all three with `npm install --package-lock-only`. All ten manifests
now install clean under `npm ci --dry-run`:

  GDevelop.js GDJS GDJS/tests newIDE/app newIDE/electron-app
  newIDE/electron-app/app newIDE/web-app newIDE/visual-tests
  SharedLibs/TileMapHelper SharedLibs/ThreeAddons      -> rc=0, 0 sync errors

Added a `lockfile-sync` matrix job over all ten directories so drift fails on
the PR that causes it. `--ignore-scripts` keeps postinstall hooks
(patch-package, import-resources) out of it — the job only asserts that the
lockfile resolves.

`node scripts/security/check-lockfiles.js` still exits 0.

* fix(deps): bump adm-zip 0.6.0 -> 0.6.1, closing 2 high advisories

`[email protected]` is vulnerable to GHSA-7q85-xj36-vmfc (high, patched in 0.6.1).
It is a *direct* dependency declared as `^0.6.0` in both manifests, so 0.6.1 was
already permitted — the lockfiles were simply pinned at the vulnerable 0.6.0 and
never re-resolved.

Verified the overrides already present in both manifests (`^0.6.0`) are harmless
here: a fresh resolution with or without them yields 0.6.1. Raising the override
to `^0.6.1` is NOT the fix — npm rejects it with EOVERRIDE because the override
would conflict with the direct dependency. Regenerating is the correct fix.

  newIDE/app/package-lock.json          adm-zip 0.6.0 -> 0.6.1
  newIDE/electron-app/package-lock.json adm-zip 0.6.0 -> 0.6.1

Closes 2 of the 22 open high-severity alerts. The remaining `adm-zip` medium
advisory (GHSA-vwc7-r8mq-g2x9) has no patch and stays documented as accepted
risk in KNOWN_VULNS.md.

All ten manifests verified: `npm ci --dry-run` rc=0, 0 sync errors, and
`node scripts/security/check-lockfiles.js` exits 0.

* docs: record execution status for the PR remediation plan

Queue 32 -> 25 open; 8 merged. Adds the evidence used to justify each merge,
the repo fixes landed in PR #124, the three master lockfiles found already
desynced (GDJS, newIDE/electron-app/app, SharedLibs/TileMapHelper) and the
adm-zip 0.6.0 -> 0.6.1 bump that closed 2 high advisories.

Also records the rebase mechanics blocker: PRs 18/26/37/39/40/104 do not move
on '@dependabot rebase' because they were edited by hand; only #40 reports it.

* Merge master into chore/ci-remediation

Master advanced 10 merges (our own dependency PRs), so the lockfiles this
branch regenerated were stale against it. The merge reverted
newIDE/electron-app/package-lock.json to master's pre-regeneration copy;
regenerated it again (adm-zip stays 0.6.1).

All ten manifests verified in the merged state: npm ci --dry-run rc=0,
0 sync errors, guard exits 0.

* ci: run lockfile-sync as one job, not a 10-way matrix

Each matrix entry was a dry-run resolve taking a few seconds, so the 10-way
matrix bought ~30s of wall clock at the cost of 10 runners. The queue
contention that produced was starving the slower build-libgd and Jest jobs,
which dominate the workflow anyway.

Now a single job loops the same ten directories, continues past a failure so
one run reports every drifted manifest, and exits 1 at the end. Verified both
paths locally: on a good tree it prints "All lockfiles in sync." and exits 0;
with one drifted manifest it prints the per-directory ❌ with the npm
Missing:/Invalid: lines, keeps checking the rest, and exits 1.
2026-09-21 20:51:37 -04:00

7.3 KiB

Known Vulnerabilities — Current State & Accepted Risk

Last verified: 2026-09-21 against the live Dependabot API and the manifests in this repo. Every number and version below was read from the repository or the API, not carried over from an earlier revision.

If you are here because a check is red, jump to Guard coverage gaps — the guard's tar floor is stale.


Summary

Metric Value
Open Dependabot alerts 49
— high 22
— medium 25
— low 2
Distinct packages 18
Stale alerts (package absent from lockfile) 0
Lockfiles in repo 10
Lockfiles covered by scripts/security/check-lockfiles.js 10

Reproduce:

gh api "repos/Heretek-AI/GDevelop-Heretek/dependabot/alerts?state=open&per_page=100" \
  --jq 'group_by(.security_advisory.severity) | map({sev: .[0].security_advisory.severity, n: length})'

An earlier revision of this file claimed "All non-electron vulnerabilities across the repository have been remediated." That was true of the curated override set at the time, but not of the alert feed. The override set and the advisory feed are different populations; only this file's alert section reflects the feed.


Electron is no longer pinned to 32.x

Resolved. The previous 32.x pin (and its 47 advisories) is gone:

Manifest Version
newIDE/electron-app/package.json 44.4.3
GDJS/Runtime/Electron/package.json 44.3.0

44.4.3 is the current latest on npm, so both are at the head of the release line. The ignore: block that held electron at 32.x has been removed from .github/dependabot.yml, so electron is once again eligible for major/minor updates through the normal PR flow.

No native-module rebuild was required at the time of the bump.


Open alerts by package

Grouped by package, with the advisory range and the version this repo actually resolves. "Fixable" means a patched version exists in the advisory.

High

Package Advisory Range Resolved Patched Manifest(s)
tar 6 advisories (GHSA-34x7-hfp2-rc4v, -83g3-92jg-28cx, -8qq5-rm4j-mr97, -9ppj-qmqm-q256, -qffp-2rhf-9h96, -r6q2-hw4h-h46w) <= 7.5.17 6.2.1 7.5.18 newIDE/app, newIDE/electron-app
adm-zip GHSA-7q85-xj36-vmfc < 0.6.1 0.6.0 0.6.1 newIDE/app, newIDE/electron-app
extract-zip GHSA-7pqw-9j4j-h8q3, GHSA-jmr9-qjv8-65gv <= 2.0.1 2.0.1 none newIDE/app, newIDE/visual-tests
svgo GHSA-2p49-hgcm-8545, GHSA-w27v-7q3p-w38r >= 1.0.0, < 2.8.4 1.3.2, 2.8.2 2.8.4 newIDE/app
vite GHSA-fx2h-pf6j-xcff <= 6.4.2 5.4.21 6.4.3 newIDE/app
serialize-javascript GHSA-5c6j-r48x-rmvq <= 7.0.2 4.0.0 7.0.3 SharedLibs/TileMapHelper

Medium

Package Advisory Range Resolved Patched Manifest(s)
webpack-dev-server 6 advisories <= 5.2.5 4.15.2 5.2.6 newIDE/app
tar GHSA-w8wr-v893-vjvp, GHSA-vmf3-w455-68vh <= 7.5.17 6.2.1 7.5.18 newIDE/app, newIDE/electron-app
adm-zip GHSA-vwc7-r8mq-g2x9 >= 0.5.9, <= 0.6.0 0.6.0 none newIDE/app, newIDE/electron-app
vite GHSA-4w7w-66w2-5vf9, GHSA-v6wh-96g9-6wx3 <= 6.4.2 5.4.21 6.4.3 newIDE/app
svgo GHSA-4vpr-x523-8j87 >= 1.0.0, < 2.8.4 1.3.2, 2.8.2 2.8.4 newIDE/app
karma GHSA-7x7c-qm48-pq9c, GHSA-rc3x-jf5g-xvc5 < 6.3.16 1.7.1 6.3.16 GDJS/tests
firebase GHSA-3wf4-68gx-mph8 < 10.9.0 9.0.0-beta.2 10.9.0 newIDE/app
launch-editor GHSA-v6wh-96g9-6wx3 <= 2.14.0 2.13.1 2.14.1 newIDE/app
picomatch GHSA-3v7f-55p6-f55p >= 4.0.0, < 4.0.4 3.0.2, 4.0.3 4.0.4 newIDE/app
yargs-parser GHSA-p9pc-299p-vxgp >= 6.0.0, < 13.1.2 7.0.0 13.1.2 newIDE/app
uuid GHSA-w5hq-g745-h8pq < 11.1.1 3.4.0 11.1.1 GDevelop.js
tough-cookie GHSA-72xf-g2v4-qvf3 < 4.1.3 2.5.0 4.1.3 GDevelop.js
decode-uri-component GHSA-vcc3-ghjq-m6fr <= 0.4.2 0.2.2 0.5.0 GDJS/tests
request GHSA-p8p7-x288-28g6 <= 2.88.2 2.88.2 none GDevelop.js

Low

Package Advisory Range Resolved Patched Manifest(s)
@tootallnate/once GHSA-vpq2-c234-7xj6 < 2.0.1 1.1.2 2.0.1 newIDE/app
elliptic GHSA-848j-6mx2-7j84 <= 6.6.1 6.6.1 none SharedLibs/TileMapHelper

Accepted risk — no upstream patch exists

These cannot be closed from this fork. Each is recorded here so it is a documented decision rather than an unexamined red badge.

Package Advisory Why accepted
extract-zip GHSA-7pqw-9j4j-h8q3, GHSA-jmr9-qjv8-65gv No patched release. Reached only through dev/build tooling, never shipped in a game export.
adm-zip GHSA-vwc7-r8mq-g2x9 No patched release. Note the separate high advisory GHSA-7q85-xj36-vmfc does have a patch (0.6.1) and should be taken.
elliptic GHSA-848j-6mx2-7j84 No patched release. Test-only dependency under SharedLibs/TileMapHelper.
request GHSA-p8p7-x288-28g6 No patched release; the package is deprecated upstream. Build-time only in GDevelop.js.

Guard coverage gaps

scripts/security/check-lockfiles.js is a curated floor list, not a mirror of the advisory feed. Two gaps are worth knowing about:

  1. tar floor is stale. The guard asserts 'tar': ['< 6.2.1'], and this repo resolves [email protected] — so the guard passes. But the current advisories cover <= 7.5.17, which includes 6.2.1. The guard is therefore quiet on 16 live advisories. Raising the floor to < 7.5.18 without also moving to [email protected] would simply turn master red, so this needs the tar 6→7 migration first (tracked in the dependabot remediation issue).
  2. newIDE/visual-tests/package-lock.json was unguarded. There were 10 lockfiles on disk and 9 in the guard's list. Added — it is now covered.

Confirm coverage at any time:

comm -23 \
  <(find . -name package-lock.json -not -path '*/node_modules/*' | sed 's|^\./||' | sort) \
  <(sed -n '/^const lockfiles/,/^];/p' scripts/security/check-lockfiles.js \
    | grep -oE "'[^']+'" | tr -d "'" | sort)
# expect: no output
node scripts/security/check-lockfiles.js   # expect: exit 0

CodeQL

js/incomplete-sanitization in test files

One alert is on GDevelop.js/__tests__/ExpressionCompletionFinder.spec.js:21. The string being escaped is test input, not production data. Dismiss with False positive in the CodeQL UI and leave a comment in the file.

js/disabling-electron-websecurity

The two alerts on newIDE/electron-app/app/main.js and LocalExternalEditorWindow.js are intentional — the local-external-editor window needs webSecurity: false to load user-supplied game previews from file:// URLs. Dismiss with Used in tests plus a code comment pointing at BUILD.md.


Google API key secret alerts

Upstream-owned secrets this fork cannot dismiss (no permission to revoke). They remain in the Security tab until upstream purges them from history. This branch stops re-leaking them via the env-var pattern documented in SECRETS.md.