Skip to content

chore: delete unused firebase-admin.ts - #1116

Merged
ogabasseyy merged 1 commit into
mainfrom
chore/remove-firebase-admin
Apr 8, 2026
Merged

ogabasseyy merged 1 commit into
mainfrom
chore/remove-firebase-admin

Conversation

@ogabasseyy

@ogabasseyy ogabasseyy commented Apr 7, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Deletes apps/web/src/lib/firebase-admin.ts — no imports found anywhere in the codebase
  • Left over from before the expo-server-sdk migration

Test plan

  • pnpm turbo typecheck — 0 errors
  • No runtime change (file was unreferenced)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Removed Features
    • Removed Firebase Cloud Messaging notification functionality and related Firebase Admin configuration.

No imports found anywhere in the codebase. Dead code left over from
before expo-server-sdk migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 7, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1e8e852c-b5ed-4477-925a-aa94f2c9ea3a

📥 Commits

Reviewing files that changed from the base of the PR and between cbd3081 and 2d57e59.

📒 Files selected for processing (1)
  • apps/web/src/lib/firebase-admin.ts
💤 Files with no reviewable changes (1)
  • apps/web/src/lib/firebase-admin.ts

📝 Walkthrough

Walkthrough

The Firebase Admin SDK initialization module and FCM push notification sending functionality have been completely removed from the codebase, eliminating all Firebase Admin-related logic and exports previously used to send notifications to device tokens.

Changes

Cohort / File(s) Summary
Firebase Admin Removal
apps/web/src/lib/firebase-admin.ts
Complete removal of Firebase Admin SDK initialization, the messaging export, and the sendFCMNotification() function that handled FCM message delivery with Android/APNs platform-specific configurations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Firebase's farewell,
Admin and messaging take their bow,
72 lines hop away,
Simplicity prevails, notifications say "ciao!"
The rabbit hops on.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change—deletion of an unused firebase-admin.ts file that had no imports in the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/remove-firebase-admin

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ogabasseyy
ogabasseyy merged commit 630b7a7 into main Apr 8, 2026
8 checks passed
@ogabasseyy
ogabasseyy deleted the chore/remove-firebase-admin branch April 8, 2026 03:16
ogabasseyy added a commit that referenced this pull request Oct 1, 2026
Address Muse round-2 findings: the SARIF step now requires inSource suppressions and re-asserts the audited workflow hardening (same-repo guard, single PR-controlled checkout with persist-credentials:false, default-branch trusted scripts), failing closed on drift. Remove the firebase-admin dependency whose only importer was deleted in #1116 (zero references repo-wide); the grpc-js <1.13.6 floor stays for the native-only RNFB transitive.
ogabasseyy added a commit that referenced this pull request Oct 4, 2026
* fix(security): close 43 open vulnerability alerts

41 Dependabot alerts: bump Next.js 16.3.4 -> 16.3.6 (GHSA-vcvr-r3jv-pc5j critical RCE), undici -> 7.29.1, fast-uri -> 3.1.8, ip-address -> 10.7.1, brace-expansion -> 5.0.12, markdown-it -> 14.3.1, dompurify -> 3.4.16, @grpc/grpc-js to 1.13.6/1.14.5 floors via workspace overrides; re-key the PPR backport patch to next@16.3.6 (upstream #94630 still unmerged).

Secret scanning: assemble the AIza redact fixture at runtime so no key-shaped literal remains in test.sh.

Code scanning: strip inSource-suppressed results from SARIF before upload; semgrep --sarif emits nosemgrep findings and code scanning ignores the flag, leaving audited findings open as phantom alerts.

* fix(security): narrow SARIF filter to the audited checkout finding

Address Muse review: the blanket suppressions drop could hide future genuine nosemgrep findings. Only the exact audited rule ID + muse-code-review.yml path is now filtered; everything else keeps uploading.

* fix(security): harden SARIF filter, drop unused firebase-admin

Address Muse round-2 findings: the SARIF step now requires inSource suppressions and re-asserts the audited workflow hardening (same-repo guard, single PR-controlled checkout with persist-credentials:false, default-branch trusted scripts), failing closed on drift. Remove the firebase-admin dependency whose only importer was deleted in #1116 (zero references repo-wide); the grpc-js <1.13.6 floor stays for the native-only RNFB transitive.

* fix(security): spoof-proof SARIF filter matching

Address Codex P2s: invariant checks run on comment-stripped lines with folded ref scalars joined, so guard expressions kept in comments cannot spoof the tripwire; the exemption predicate additionally pins the audited step via the SARIF snippet, so a second suppressed checkout in the same file stays visible. Stdlib-only (no PyYAML in the scan container).

* fix(security): tidy release-age exemptions

Address Muse review: exempt @next/env@16.3.6 alongside next@16.3.6 (lockstep publish, same cooldown window); drop the superseded undici@7.29.0 exemptions. No lockfile impact (exemptions are not lockfile-coupled).

* fix(security): pin SARIF exemption by computed region

Address Muse review: replace the snippet-text match with a startLine check against the audited step span computed from the workflow itself. Survives step renames and snippet-less emitters; a second suppressed checkout elsewhere keeps uploading.

* fix(security): positional SARIF tripwire, exact path match

Address Muse medium + Codex P2: guard must sit in a real if: condition, persist-credentials/ref:/path: must be mapping keys (run: echo strings cannot spoof or trip them), unnamed steps delimit spans, and the artifact URI must equal the audited path after normalization (no suffix lookalikes).

* fix(security): remove head-copy fallback, bind tripwire to resolution

Address Codex P1: the reviewer workflow no longer falls back to executing PR-controlled scripts when the trusted checkout misses (fail closed with an error instead); the SARIF tripwire now asserts the resolver step selects the trusted path with no head-copy fallback.

* fix(security): structural tripwire for resolver and agent

Address Codex P1s: parse every dir= value assigned to GITHUB_OUTPUT (mentions no longer count; unbraced and traversal forms covered) and assert the trusted runner's single muse invocation keeps exact --disable-shell/--disable-write flags plus token isolation.

* fix(security): job-scope SARIF guard, no-checkout no-op

Address CodeRabbit: the same-repo guard must sit in the audited job's own job-level if (a step-level or foreign-job copy no longer satisfies it). Also exit cleanly when no PR-controlled checkout remains (removing the checkout is the safest change, not drift) and deduplicate the count label.

* fix(security): exact dir path, guard conjunct validation

Address Codex P1/P2 + Muse low: assigned dir values must equal the trusted path exactly (lookalike directories rejected); the same-repo guard must be a positive top-level && conjunct of the audited job condition (negations, || fallbacks, and lookalike comparisons fail closed; redundant parens tolerated).

* fix(security): exact trusted ref, assert trusted credentials

Address Codex P1s: trusted checkout ref values must equal the audited default-branch expression exactly (lookalikes like default_branch && head_ref rejected); persist-credentials:false is now asserted on the trusted span too, since a persisted token in the nested repo config is agent-readable file content.

* fix(security): exact SARIF span end + survivor warning for shape drift

Trim trailing blank separators so the audited span ends at the
step's last content line; warn (fail-closed) when a rule+path
finding survives filtering, distinguishing emitter shape drift
from removed nosemgrep.

* fix(security): pin trusted checkout action/repo; bind script consumers to resolver

Codex P1s: forbid repository: and pin uses: on the trusted-scripts
checkout; require scripts-tree path literals to live only in the
owning steps, SCRIPT_DIR bindings to route via the resolver output,
and every run-block interpreter operand to be SCRIPT_DIR-rooted.

* fix(security): audit all resolver output writes, scope muse flags, pin head uses

Codex P1s: every GITHUB_OUTPUT mention in the resolver must be the
known-safe echo (last write wins); muse containment flags scoped to
its own argv segment, not the whole shell line; pin the audited
checkout's uses: alongside its ref; include the runner path in the
Semgrep scope filter so runner-only PRs run the audit.

* fix(security): always-audit on empty scans, token/installer/rebind guards

Muse medium: run the drift audit even when the scan wrote no SARIF
so runner-only PRs cannot skip it; SARIF filtering stays
conditional. Codex P1s: catch builtin-qualified SCRIPT_DIR
rebindings; forbid token expressions in the agent step and job env
under any key; pin install.sh version/checksums/verify-order/URL and
forbid pipe-to-shell.

* fix(security): exact installer checksums + structural URL validation

Codex P1: pin both SHA-256 constants exactly (not 64-hex shape) and
require every URL literal in install.sh to be the pinned versioned
download (pinned host + version=${MUSE_VERSION}); a re-pointed host
with fresh hashes plus a retained lookaside string now fails both
checks. Also documents the intentional .sh SAST gap (Muse low).

* fix(security): per-step argv0 allowlists, flag-parsing operand rule

Codex P1: every command in every run: block allowlists by argv0
(secret steps strictest; others add git/rm), closing execution via
non-bash interpreters and direct executables. Interpreter operands
now parse flags (-o args, -- end, redirects, combined shorts);
-c/-s/stdin/no-operand drift. Also forbids command/process
substitution, env/path propagation, function definitions, shell:
overrides, unpinned actions, sudo/PATH-hijack in secret steps, and
constrains git to read-only workspace subcommands.

* refactor(security): extract SARIF auditor to tested modules

Muse mediums: move the ~900-line inline auditor into
semgrep-sarif-filter.py + semgrep_sarif_* modules (each under the
300-line repo rule) with a committed 60-case regression suite
wired into muse-review-selftest; slim the workflow step to a
one-line call. Behavior proven identical via the full mutation
battery. Also documents the .sh SAST gap SLA (daily 03:00 UTC
scheduled scan) and the resolver fail-closed exception to the
review workflow's advisory header.

* fix(security): close Codex-18 P1s and Muse round lows in SARIF auditor

- Reject top-level || in the same-repo job guard: any depth-0
  disjunction voids the &&-conjunct reading, so (guard && ...) ||
  true now drifts instead of matching the guard conjunct. Nested
  parens (action/edited fallback) still pass.
- Scan job- and step-level YAML env: blocks (block and flow style)
  for shell-startup/loader/interpreter-preload vars (BASH_ENV, ENV,
  PATH, LD_PRELOAD, LD_LIBRARY_PATH, PYTHONPATH, NODE_OPTIONS,
  RUBYOPT, PERL5OPT); run:-block text cannot false-positive since
  only contiguous env: blocks are consumed.
- Enforce exactly two pinned checkout actions: a third uses:,
  even pinned, drifts (reviewer-action-count), closing the
  trusted-path smuggling hole.
- Forbid repository:/path: keys in the audited head-checkout span
  (head-checkout-shape): relocating or re-sourcing the reviewed
  data while the ref still audits.
- Honor load_workflow(path): open the argument instead of the
  AUDITED_PATH constant.

Suite: 137/0 (7 new cases incl. end-appended || true
discriminator, verified red on pre-fix audit.py via stash
negative control); muse-review 66/0.

* fix(security): close Codex-19 P1s (trusted-write, helper audit, change signal)

P1 cat-file rewrite: new quote-aware redirect-target scanner
(semgrep_sarif_scan) rejects any output redirect into
trusted-scripts/${SCRIPT_DIR} in every run block (step label
step-trusted-write), closing the general hole the repro used
(git cat-file blob ... > trusted/...). Legit -e existence check
and GITHUB_OUTPUT/dev-null redirects unaffected.

P1 token-bearing helpers: new audit_helpers (helpers +
interp + embeds modules) content-audits every workflow-invoked
helper plus lib.sh: interpreter operands pinned to the
trusted tree (bash/sh/source, perl -I/-M/program, jq -f,
awk -f, python/node/ruby/php blanket-drift), no workspace-root
execution indirection (variable aliases resolved), no
privilege change, no trusted/$HOME writes, loader/startup
rebinding rejected (two safe idioms kept), /backtick/
process-sub recursion, heredoc/case-pattern awareness.
helpers/interp/embeds/scan/shell/pins all under 300 lines.

B1 change signal: paths-filter trusted_changed (helpers,
auditor, guarded workflows) fails loud for human review, since
directly hostile helper code is indistinguishable from
legitimate token use. Advisory (Security non-required); false
on push/schedule/dispatch where content rules still apply.

Also: sudo/doas now drifts in loose steps too (every step
inherits runner tokens).

Suite 193/0 (28 new cases incl. both P1 repros, verified red
on pre-fix code); muse-review 66/0; actionlint clean.

* fix(security): close Codex-6-P1 + Muse findings on the SARIF auditor

- Normalize quoted YAML keys everywhere (uses/env/run/shell/ref/path/
  steps/name): quoted spellings now audit identically to bare ones.
- Audit every runner-invoking step for token expressions (aliased keys).
- Reject deferred execution: PS4/PROMPT_COMMAND binding, xtrace switch,
  and $/backtick inside $((...)) (proven executable when quoted).
- Resolve indirect muse invocations via top-level literals; word-based
  quote-glued argv0 detection; unresolved indirection fails closed.
- Execute the filter from a base-revision checkout on PRs (no fallback);
  head-side filter replacement is ignored (mechanism regression).
- Audit data programs: ranges.pl (perl danger set) and jq programs
  (env/import rules, inline + gh --jq included); unknown formats drift.
- trusted_changed gates the no-checkout exit; SARIF parse errors fail
  with cause instead of a traceback.
- Scope fix: underscore auditor modules join both path-filter lists,
  with the trusted-relevant subset invariant documented.
- Split security.yml (dependency-review job moves out, byte-identical)
  and muse-code-review.yml (header docs to .github/muse-code-review.md).
- Suite split (lib + filter + hardening, all <300 lines); 117 new
  assertions, all failing pre-fix (negative control verified).

Suites: filter 193/0, hardening 117/0, muse-review 66/0; actionlint,
shellcheck, py_compile clean.

* fix(security): anchor auditor to GITHUB_WORKSPACE, widen selftest coverage

Muse review findings on 8ed3aab:

medium (selftest coverage gap): changes to security.yml /
dependency-review.yml never triggered the selftest nor its
actionlint step. Added both workflows to push/pull_request paths
and to the Workflow-lint actionlint target list.

low (CWD-relative paths): main() now chdirs to
$GITHUB_WORKSPACE-or-CWD at startup (fail-closed on OSError),
so a future working-directory default cannot silently audit the
wrong tree or report a false clean scan. Test lib unsets
GITHUB_WORKSPACE (CI exports it) to keep suites on scratch trees.

Regression: workspace-anchor case (CWD pristine-happy,
GITHUB_WORKSPACE drifted) asserts exit 1 + helper-env-poison —
self-discriminating since the pristine CWD cannot emit drift.

Suites: filter 193/0, hardening 119/0, muse-review 66/0.

* fix(security): close Codex round-23 auditor evasions (5 P1s)

P1 install-src: new semgrep_sarif_install.py binds the install
step to the verified artifact — source/dest operands must equal
"${tmp_bin}"/"${install_dir}/muse" exactly, tmp_bin/install_dir
must be single mktemp/HOME assignments, and any second install,
cp/mv/ln/tee onto the muse path, or redirect there drifts
(muse-installer-source/-rebind/-overwrite).

P1 bare-curl: _check_command denies bare network-capable tools
(helper-network-tool) in all helpers; install.sh keeps its
pinned curl (constrained by the installer URL rule). Threaded
through env/xargs re-dispatch.

P1 escaped-hash: strip_comments is backslash-aware (verified:
echo \#; evil executes the suffix), closing the hole in the
helper, installer, and run-block paths that share it.

P1 last-assign: _collect_vars models bash last-wins and deletes
the entry on an unresolvable last assignment (keeping the
earlier literal would resolve dynamic content to stale trust).

P1 subscript: new subscript_cmdsubst extracts $(...) from
single-quoted [[ -v name[..] ]] operands for audit (fail
closed; bash 3.2 rejects the form at parse time).

Refactor: step-span helpers move shell->steps (with step_name,
cycle-free) to hold the 300-line cap.

Regressions: 9 hardening cases (8 drift + 1 FP); negative
control confirms exactly the 8 drift cases fail pre-fix.
Suites: filter 193/0, hardening 137/0, muse-review 66/0.

* fix(security): gate new install module in base-filter existence check

Muse body-only low on d67dcf7: the base-filter existence loop
enumerated 12 auditor files but omitted semgrep_sarif_install.py,
so a base tree missing it would ImportError instead of failing
with the clean gate message. Added to the loop, plus a
self-maintaining lockstep assertion (module list derived from
the tree, so the next new module cannot repeat the omission).
Negative control: HEAD gate reports exactly install.py missing.

Hardening suite 138/0; actionlint + shellcheck clean.

* fix(security): close Codex d67dcf7 evasions (heredoc, scalar boundary)

P1 heredoc: _strip_heredocs now returns (code, bodies) — quoted
delimiters (<<'EOF', <<"EOF", <<\EOF, with backslash-unescape
so the terminator still matches) drop, while unquoted bodies
(which expand: verified executed) audit via _audit_expansions
(extracted commands fully, arithmetic regions; body words are
stdin data, never commands; per-line so bodies cannot fuse
into phantoms). Moved to semgrep_sarif_heredoc.py to hold the
300-line cap; added to the base-filter existence gate.

P1 scalar boundary: step boundaries must sit at the steps-item
indent derived from the block-style steps: key (quoted
spellings included), so '- name:' inside run: | bodies and
heredocs is prose, not a span cut. Sound: scalar content must
out-indent its key, so an item-indent dash dedents into a real
(audited) step either way. No-steps: fallback preserves
enumeration (never silently empty).

Regressions: helper-heredoc-unquoted, helper-heredoc-quoted-fp,
scalar-fake-step; negative control confirms exactly the 2
drift cases fail pre-fix. Suites: 193/144/66.

* fix(security): close 6 code P1s (copy-dest, poison, deferred, perl, workspace, argv)

P1 file-mutate: new semgrep_sarif_copy.py validates destinations
for cp/mv/ln/install/tee/dd/tar/unzip/zip/patch/ed/sed (trusted
tree, muse binary + ancestor dirs, workspace zones via shared
scan._write_zone; patch/ed unbounded-stdin drifts; tar-create
and zip bundle taint; install.sh exempt, structurally audited).

P1 indirect-poison: new semgrep_sarif_poison.py tracks printf
-v/read/getopts/mapfile/loop-var assignment to PATH-family
names; BARE_POISON_RE extended from PATH/IFS to all 17 vars
(standalone BASH_ENV/LD_PRELOAD were missed; verified).
Bare export needs no rule (values flow through audited assigns).

P1 deferred-eval: trap handlers and mapfile -C callbacks audit
recursively (new defer.py extractors); at/batch/crontab/watch
denied (helper-deferred-exec). install.sh trap handler audits
clean (rm falls through).

P1 perl-open: _open_danger parses paren-free open/sysopen
(statement scanning with call guards for sub/use/pragma/hash
forms); 1-arg opens drift; sysopen flags must be read-only.

P1 workspace-write: redirect + copy + perl/awk-inplace targets
in GITHUB_WORKSPACE drift (helper-workspace-write). awk -i
include of non-inplace code drifts (unpinned source).

P1 flag-gluing: new semgrep_sarif_agent.py parses muse argv
positionally (value flags skip, --opt=value attached,
redirects skipped, exec required, unknowns drift; containment
checked before unknown-flag to preserve existing contracts)
plus exact -u/--unset scrub parsing (twin hole closed) and a
model_args shape rule (empty init + --model single values).

Regressions: 20 hardening cases; negative control confirms
exactly the 17 drift cases fail pre-fix. Suites: 193/184/66.

* fix(security): close Codex P1s on f5ca446 (loaders, toctou, staging, perl)

- loaders: LOAD_DENY (75 build/package/container/provisioner names) in
  dispatch + xargs exec-target; lua/luajit join the interpreter deny;
  new semgrep_sarif_git.py allowlists git to fetch/diff/show/merge-base
  /config with -c core.quotePath-only, origin-pinned fetch, no -C,
  --exec-path=, --config-env, --git-dir; wrapper set gains parallel,
  flock, chrt, ionice, taskset, sg, tmux, screen, nsenter
- toctou: runner freezes tmp_bin at the hash line (compare reads stale
  got_sha); post-verify writes via redirect/cp/mv/ln/install/tee/patch/
  ed/truncate/shred/curl -o/dd of=/sed -i drift muse-installer-toctou
- staging: helper-secret-expand drifts on any $GH_TOKEN/$GITHUB_TOKEN
  expansion (sole legit mention is run.sh's -u scrub); helper-env-dump
  covers printenv, command-less env, bare declarators, bare set;
  ENV_POISON grows 17->30 with GIT_SSH*/PAGER/GIT_CONFIG*/GIT_DIR/
  GIT_EXTERNAL_DIFF/GIT_DIFF_OPTS/GIT_ASKPASS (COUNT gates KEY_n,
  verified empirically)
- perl: use-allowlist {strict,warnings} + no-version rules, secret
  $ENV{TOKEN|SECRET|...} + dynamic keys, socket/syscall/fcntl/ioctl
  builtins incl. CORE::; -e/-E inline bodies take content checks
- adjacent: find -delete/-fls targets, awk system()/pipe/getline and
  program redirects, redirect-strip before peel (operands stay clean)
- 77 hardening cases (107 pre-fix red incl. new labels); suites
  filter 193/0 hardening 340/0 muse-review 66/0; all modules <300

* fix(security): close Codex 9-P1 round on 7a2ba86 (aliases, indirect, varmap, CORE, tar/sed, symlink, perl, xargs, compare)

Tmp-bin alias closure, indirect token expansion, varmap staleness, CORE:: builtins, tar/sed exec channels, symlink-alias sources, Perl lexer, xargs full dispatch, fail-closed compare shape. Hardening 460/0, filter 193/0, review 66/0.

* fix(security): hono 4.13.7 + node-forge CVE-2026-85393 backport

hono override 4.13.5 -> 4.13.7 (GHSA-hxh3-vqpv-xpqv boundary XSS). node-forge has no fixed release, so backport upstream digitalbazaar/forge#1152 as a pnpm patch (byte-identical to upstream post-image) with a patch-integrity test; dev-tooling-only reachability via @expo/cli.

* fix(security): close Codex 5-P1 round on bdd6574 (cmdfiles, alias/shopt, nameref, forge vectors)

- Runner command files: value-sensitive GITHUB_ENV (poison NAME=value,
  unknown writers, cmdsub fail-closed) and GITHUB_PATH (workspace/relative
  entries, empty-entry CWD) rules for shell redirections, heredoc bodies
  (quoted-ness aware), and copy-class targets (cp/mv/tee/dd/find).
- Hidden dispatch: alias definitions drift; shopt -s expand_aliases drifts
  (queries, -u, -o, other options pass).
- Nameref edges: declare/local/typeset -n close over helper varmap (secret
  expansion through $ref) and installer tmp_bin alias closure (post-verify
  writes through the ref drift).
- node-forge: RSA verify behavioral test locks the CVE-2026-85393 backport.
- filter: main() returns status, single sys.exit wrapper (Muse low).
- Hardening suite 460 -> 502 (21 new P1 cases, all FP-paired); pristine
  in-scope helpers silent.

* fix(security): use Codex exact P1 mutations as regression cases

cmdf-env-poison, nameref-secret, toctou-alias-nameref now carry the
reviewer's verbatim mutation strings; alias-p1-mutation adds the exact
3-line shopt/alias/invocation chain. Suite 502 -> 504.

* fix(security): close Codex 5-P1 round on 9df9f9d (traversal, enable, gh, coproc, alias)

- Trusted-path traversal: lexical containment (_contained_exec_path)
  under SCRIPT_DIR/HOME/~~/system roots for script operands and direct
  exec argv0; .. past the root, $//backtick/backslash remainders drift.
- enable: -f (dynamic .so load) and -n (builtin->PATH fallback) drift;
  queries and bare enable pass.
- gh: new semgrep_sarif_gh module -- api subcommand only, writes pinned
  to POST+reviews endpoint+pinned --input with no -f fields, --hostname
  and -R/--repo denied, last-wins --method, all --jq programs scanned.
- coproc joins the execution-wrapper deny list (command/builtin/exec/
  sudo already peel transparently).
- YAML aliases: alias-valued run fields (run: *payload, &/!! prefixed)
  drift; quoted literals and block-scalar bodies pass.
- GH_HOST joins ENV_POISON (redirects token-bearing gh traffic).
- Suites: filter 193->201, hardening 504->554; pristine helpers and
  workflows silent.

* fix(security): close Codex 7-P1 round on c25b335 (hash, peel, escapes, sockets, flow, fd, splits)

- Command hash: hash -p installs arbitrary command names and drifts;
  -r/-d/-l/-t queries and bare hash pass (-- honored).
- Wrapper options: exec -a name/-c/-l, command -p (with -v/-V query
  short-circuit), builtin --, time -p parsed before dispatch, so the
  real argv0 audits (sudo/doas peel bare: privilege always drifts).
- Escapes/concatenation: tokenizer joins adjacent words and escaped
  spaces; _bare_word normalizes quotes/escapes at every words/toks
  site (helpers, steps, consumer, varmap, install, nameref, cmdfile
  values); declare-prefixed assigns tolerate escaped names (bare
  \u=x verified dead); steps poison names tolerate escapes with a
  literal = (verified). Escaped builtins/keywords proven dead, so
  bare-matching them over-approximates safely.
- Sockets: any redirect (in or out, bare-normalized) to /dev/tcp or
  /dev/udp drifts (helper-network-tool / untrusted-command).
- Flow steps: '- {' mappings at step indent drift (their run bodies
  audit nowhere); deeper-indent occurrences pass.
- Installer fds: nonstandard fd digits (>2), {name}/$var fd
  spellings, and /proc/self/fd or /dev/fd paths drift as TOCTOU;
  standard 0/1/2 redirections pass.
- 300-line rule: split shell (300->152: segments + script_operand to
  pins), poison (350->154: cmdfile), scan (302->229: redirect);
  security.yml module loop extended (lockstep green).
- Suites: filter 201->207, hardening 554->596; pristine helpers and
  workflows silent; bash-3.2 semantics verified by probe.

* fix(security): close Codex 2-P1 round on b19339c (alt shells, environ reads)

- Alternate interpreters (dash/ash/zsh/ksh/mksh/pdksh/lksh/yash/fish/
  tcsh/csh) bind through script_operand like bash/sh; busybox already
  denied via NET_DENY. Steps side already denies via allowlists.
- Process-environment reads: /proc/<pid>/environ in any pid spelling
  (self, digits, $$, vars), quoted or not, drifts as helper-env-dump
  in helpers and run-body-environ in every run body (even secretless
  steps inherit runner tokens). Quoting is no defense since readers
  open quoted paths; comments strip before the check.
- Suites: filter 207->213, hardening 596->612; pristine helpers and
  workflows silent.

* fix(security): close Codex 5-P1 round on 7a658a3 (awk-alias, procfs, git-params, gh-post, bracket-token)

- interp: audit mawk/nawk/gawk/oawk/original-awk (+distro versions) like awk
- scan/helpers/consumer/redirect: collapse /proc/<pid>/root aliases before
  environ matching, socket detection, and write-zone classification
- shell: add GIT_CONFIG_PARAMETERS to ENV_POISON (printf -v, bare, declare)
- gh: field flags (-f/-F/--field/--raw-field) and --input imply POST;
  explicit GET/HEAD still passes; -q/-t/-p value flags skipped in scan
- steps: bracket token lookups (quoted github_token/token, computed)
  escalate steps and trip agent-token-expression
- hardening suite: 13 new cases incl. Codex exact mutations (638 total)

* fix(security): close 7 Codex P1 + 3 CodeRabbit round (wrappers, @p, java, env-ref, promptfile, run-parts)

* fix(security): close 5 Codex P1 + lows (sqlite3, install-shadow, exit-255, arith-recurse, env-alias)

* fix(security): close 4 Codex P1 on 773f806 (gcc, escapes, subscripts, operand-freeze)

gcc/clang drivers (+versioned/cross spellings) join LOAD_DENY: -B search dirs execute workspace subprograms with the token. strip_comments/split_commands2/tokenize track backslash escapes in double quotes so " can no longer phantom-close and swallow a ; separator. subscript_cmdsubst generalizes to test/[ -v, printf -v, declare/local/typeset/readonly, unset, read, let with keyword/wrapper/assign peeling, per-builtin flag skipping, and LHS-only subscript-span extraction (declare values never evaluate: verified syntax-error-no-exec). Installer freezes got_sha/want_sha post-hash: any rebind (assign, read/printf -v/for/select, nameref, let, (( )), mapfile/getopts) drifts muse-installer-operand-rebind. Self-found: _peel_env subscript/+= assigns prefix commands (verified), no longer return []. 32 new hardening cases (738 asserts green); filter 221, muse-review 66, pristine exit 0.

* fix(security): close 10 missed Codex P1s + split auditor under 300-line cap

Missed-P1 fixes (all reproduced exit-0 pre-fix, 64 new hardening tests):
- YAML escape decode: _yaml_double_unescape in map_key_value/unquote_value/
  is_pr_ref/ref_is_pr_controlled ("\u0075ses": -> uses)
- checkout-order: PR<clear<trusted<resolver + uniqueness (checkout-order)
- runner-work exclusion from trusted exec (/home/runner/work, normpath)
- glob write zone -> helper-unzoneable-write (_write_zone/_audit_line/
  audit_copy_dest/audit_find_output/audit_sed_programs/_source_alias)
- ps e BSD-only env dump -> helper-env-dump (audit_ps_env)
- LD_AUDIT in ENV_POISON; eval any-use drifts helper-untrusted-exec
- binutils copy dispatch: objcopy/ld/as/strip/ar/ranlib in COPY_TOOLS
  with -o/--dump-section/archive logic (audit_binutils_targets)
- flow with:{} -> checkout-flow-with; flow shell: -> shell-override

Size splits (all modules <300 lines, byte-identical function moves
verified vs HEAD except the 14 intended edits above):
- new: consts/words/binutils/alias/peel/varcollect/subscript/zone/
  refs/helpertree/agentenv/order; security.yml lockstep loop in sync

Suites: filter 221/0, hardening 802/0, muse-review 66/0, pristine exit 0

* fix(security): close 5 Codex P1s (jshell, ssh-keygen, pwsh, container, secret-bindings)

- jshell/ssh-keygen/pwsh/powershell join LOAD_DENY (helper-code-loader):
  load-file execution, -D PKCS#11 provider .so constructor, -File
  scripts (ubuntu image ships PowerShell); no legit helper use.
- job containers: any container: key in the audited workflow drifts
  container-override (audited file pins none; semgrep image lives in
  security.yml outside audit scope). New semgrep_sarif_container.py,
  wired into main + security.yml lockstep loop.
- secret bindings allowlisted (SECRET_BINDINGS): unexpected NAME bound
  to exact secrets.KEY value drifts secret-step-unexpected-binding
  (whole-file scan: job-level env precedes step boundaries).
- step exfil trio: echo/printf of a bound name or runner token var
  (secret-step-exfil, boundary-guarded refs, single-quote masked),
  secrets. refs inside run: code (secret-step-inline-secret), bare
  env builtins / -p dumps (secret-step-env-dump, set -o exempt).

All 5 reproduced exit-0 pre-fix; 17 new hardening tests (incl.
quoted-container, jobenv, singlequote/namesake/set-o FPs). Suites:
filter 221/0, hardening 838/0, muse-review 66/0, pristine exit 0.

* fix(security): close 15 Codex P1s on e060d4e/f146b44/81350d13

Loaders: direct ld.so/musl (_LD_SO_RE, helper-code-loader), ld
-plugin, swift/swiftc join LOAD_DENY.
Writers: sort/iconv/shuf -o (+sort -T), uniq positional output,
split prefix, csplit -f join COPY_TOOLS; split --filter and sort
--compress-program drift untrusted-exec. Value-aware
_tool_operands skips -f/-s/-w, -a/-b/-C/-l/-n/-t values.
Queries: script_operand parses the leading option prefix
left-to-right (verified: -c beats later --help, query-first
wins); source/. never honored (planted-file sourcing).
Dumps: shared _is_env_dump (bare, -p, flags-without-names;
-f code listings pass; set -p privileged-mode passes).
Agent: --workspace pinned to ${GITHUB_WORKSPACE} and
--prompt-file to ${PROMPT_FILE} (agent-workspace/promptfile-
rebind, both required); toJSON(github|secrets) rejected in
agent env; HOME rejected (agent-env-home).
Bindings: new secretbind module (block scalars resolved,
flow pairs, interpolated values, dynamic keys, toJSON) with
agent-scope AGENT_SECRET_BINDINGS for agent/consumer/job-env.
Checkout shape: any with: value drifts (anchor/alias/tag/flow);
flow-PR lines join pr_refs; ref anchor/alias fails closed to
pr-ref-unresolved; flow check runs before the early return.

All 15 reproduced exit-0 pre-fix; 41 new hardening tests.
Suites: filter 221/0, hardening 918/0, muse-review 66/0,
pristine exit 0; all modules <300 lines.

* fix(security-audit): close 11 Codex P1s on 95a5207 + 2 CodeRabbit findings

- secretbind: track github.token bindings (dot/bracket/dynamic);
  data-flow expression classifier replaces booleanized skip
  (case/format/join carry, comparisons/bool-funcs skip); _EXPR DOTALL
- binutils/copy/interp: route llvm- and -versioned spellings
  through the destination audit
- peel: GNU time option peeling (-o/-f values, --output=/--format=)
- consts: script joins LOAD_DENY (-c executes its operand)
- zone/redirect: dequote words before procfs match and write zoning
- heredoc: backslash escapes inside double quotes (no false body)
- shell: ANSI-C $'..' decode + $".." in _bare_word
- install/interp/install.sh: installer curl requires --disable
  first, rejects -K/--config
- pins: drop /opt from _safe_exec_path (hostedtoolcache writable)
- steps: git -C confined to workspace root/trusted tree (no
  siblings, no ..); help/--help removed (man.viewer RCE)
- 36 regression tests (29 hardening + 7 filter); suites
  976/0, 235/0, muse-review 66/0; pristine exit 0

* fix(security-audit): close 3 new Codex findings on 51c468e (rpm/m4, reviewfile, suite split)

- consts: rpm + m4 join LOAD_DENY (--eval feeds /bin/sh,
  syscmd/esyscmd execute; both ship on ubuntu runners)
- helpers: review_file pinned to ${RUNNER_TEMP}/muse-review-body.md
  via the prompt_file mechanism (parameterized pin loop)
- split 750-line hardening suite into 4 sourced parts
  (185/215/178/170) + 20-line entrypoint per AGENTS.md cap;
  selftest paths-filter covers the new part files
- 4 regression tests (rpm-eval, m4-syscmd, reviewfile-rebind,
  reviewfile-assign); suites 984/0, 235/0, 66/0; pristine 0

* fix(security-audit): close 3 CodeRabbit findings on 4e88324 (arith-heredoc, opt writes, labels)

- heredoc: skip balanced arithmetic regions ($((...)), ((...)),
  obsolescent $[...] before heredoc detection; shift << can no
  longer start a false body that hides later commands
- zone/scan: /opt/hostedtoolcache writes zone as trusted
  (helper copy+redirect and step redirects all drift)
- filter: no-checkout exit prints actual drift labels instead of
  always blaming the trusted tree; 2 expectations updated
- 7 regression tests (3 arith, 3 opt-write, 1 flow-label);
  suites 998/0, 235/0, 66/0; pristine 0

* fix(security-audit): close 2 Codex P1s on 0cfdb93 (binutils plugins, sensitive cwd)

- interp/binutils: plugin loader rule covers ld/nm/ar/ranlib
  incl. llvm-/versioned spellings plus --plugin= form; nm joins
  the canon (read-only: no dest audit, plugin-checked)
- zone/interp: cd/pushd/popd rejected conservatively
  (helper-sensitive-cwd) unless provably temp (/tmp, /var/tmp,
  RUNNER_TEMP); bare/tilde/unknown/rotations drift; zero legit
  helper uses; step blocks already reject cd via allowlist
- 12 regression tests; suites 1022/0, 235/0, 66/0; pristine 0

* fix(security-audit): close 3 Codex P1s on 95a2590 (7z, hg, julia)

- archive (new): 7z/7za destinations zone like copy targets
  (extraction -o dir; a/u/d/rn archive operand; bare extraction
  silent like tar); wired from interp (copy.py at cap);
  lockstep loop updated
- consts: hg + julia join LOAD_DENY (config hooks execute on
  any command; program-file operand executes; both ship on
  ubuntu runners; zero legit helper use)
- 5 regression tests; suites 1032/0, 235/0, 66/0; pristine 0

* fix(security-audit): close 2 Codex P1s on c9d7987 (lldb, anchor-flow)

- consts: lldb joins LOAD_DENY (-s/--source executes command
  files; platform shell runs repo scripts; zero legit use)
- steps: flow-step guard normalizes anchor/tag prefixes
  (&evil/!tag, either order) before brace detection; alias
  run-guard aligned to single-! tags (same hole one line up)
- 4 regression tests; suites 1034/0, 241/0, 66/0; pristine 0

* fix(security-audit): close 2 Codex P1s on 87f37da (dotnet, bash-func)

dotnet joins LOAD_DENY (run/build/test execute repo code). BASH_FUNC_<name>%% function-import keys drift reviewer-env-poison in env: blocks/flow (new semgrep_sarif_bashfunc module; relocated from consumer.py, at cap), helper-env-poison in helper bare/export/env/cmdfile/xargs paths, and secret-step-path-hijack in step run blocks. 9 regression tests; suites 1052/241/66 green, pristine exit 0. P1 4176327356 (selftest sharding) declined with evidence: CI run 37180406516 succeeds in 3m51s of 10min.

* chore(web): refresh storefront-edge inventory snapshot for main #3617

main@6a4bab7cd0 changed inventoried API source (blog feed sanitize) without regenerating the snapshot; the repository test fails on main itself. Regenerated via create-storefront-edge-inventory-cli (rows unchanged, 558; only input digests rotated). No edge-surface change.

* fix(security-audit): close 9 Codex P1s on cd810d2 (round 15)

tclsh/expect/wish (+versioned) and autoconf-family loaders join LOAD_DENY. PERL5DB/SHELLOPTS/PS4/BASH_CMDS join ENV_POISON (all paths inherit); perl -d rejected via flag-letter scan (bundled -wd verified); subscript/append assigns covered in bare/direct/step shapes. env --split-string rejected. AWK: -E/--exec pinned, -D/--debug/-W/--load rejected, -o/-p outputs zoned, long-option abbreviation engine. jq --run-tests rejected, --indent value fixed. New semgrep_sarif_awk/jq modules (interp/embeds splits). 24 regression tests; suites 1100/241/66 green, pristine exit 0.

* fix(security-audit): close 3 cursor + 3 Codex P1s on c3aa7da (round 16)

AWK: separate-word -e scanned (no program_seen claim), bare --profile/--pretty-print drift like short -o/-p (zoneq merged into dump kind), short -d/-dFILE dump handling (zone attached, drift bare). kotlin/kotlinc/kotlinc-jvm/kapt join LOAD_DENY; sshpass joins NET_DENY; SSH_ASKPASS joins ENV_POISON; envsubst/eval_gettext/eval_ngettext rejected as secret-expand. 9 regression tests; suites 1120/241 green, pristine exit 0.

* fix(security): close 4 round-17 Codex P1s (varmap ops, gfortran -B, glob abspath, TAR_OPTIONS)

- varmap: parameter operators / specials in argv0 drift unresolved-command
  even when the var is statically known (_resolve keeps the literal while
  bash computes the value); start-anchored so assignments and bare ${V}
  still pass
- consts: gfortran joins _GCC_RE (-B plants f951 et al); TAR_OPTIONS joins
  ENV_POISON (checkpoint-action=exec)
- pins: glob metacharacters rejected in contained and absolute-system exec
  paths (/usr/bin/ba?h no longer resolves as trusted)
- hardening suite: 10 regression tests (1140 passed, 0 failed)

* test(security): exact-mutation regressions for round-17 P1s

- loader-gfortran-cross: target-prefixed driver spelling
- helper-tar-options: exact checkpoint-action=exec construction

* fix(security): reject brace expansion in exec paths (cursor High)

- pins: { and } join the denylist in _contained_exec_path and the
  absolute-system branch of _safe_exec_path (brace expansion runs
  before globbing; normpath never collapses {..})
- hardening suite: helper-brace-abspath + helper-brace-scriptdir
  (1146 passed, 0 failed)

* fix(security): close 3 round-18 Codex P1s (runghc, ${BASH}, proc task)

- consts: runghc/runhaskell/ghc/ghci join LOAD_DENY (interpret file
  operand; TH splices execute at compile time)
- consts+varmap: SHELL_EXEC_VARS (BASH, SHELL) drift unresolved-command
  like stale names (predefined executable paths, never assigned)
- zone: has_proc_environ strips one /task/<tid>/ level (same process
  bytes; nested task/ stays silent, kernel ENOENT)
- hardening suite: 7 regression tests (1160 passed, 0 failed)

* fix(security): close 12 round-19 Codex P1s + symlink low

- consts: cabal/stack/ant join LOAD_DENY
- interp: fakeroot/xvfb-run wrappers denied; versioned perl
  (perl5.38.2, target-qualified) dispatches to _check_perl
- tar: --rsh-command/--rmt-command drift untrusted-exec
- copy: zip -TT drifts; tar extract without -C lands
  implicit=workspace; audit_find_output splits to
  semgrep_sarif_findout.py (300-line cap) + lockstep sync
- awk: @include/@load directives drift (post string-blank)
- consumer: declare/local/typeset -n drifts script-dir-rebound
- agentenv: double-quoted flow keys YAML-unescaped (U+0048)
- filter: O_NOFOLLOW on sarif tmp (symlink write-through)
- security.yml: trust notes -> sarif-filter-notes.md (282 lines)
- suites: 20 regression tests (1196/245/66, pristine 0)

* fix(security): close 5 round-20 Codex P1s + CODEOWNERS medium

- interp: prlimit/timeout join wrapper denylist
- poison: unresolved (non-assignment) words drift env-dump
  for declare/typeset/readonly/export/local (constructed -p)
- consts+interp: clang-tidy in LOAD_DENY, _TIDY_RE for
  versioned spellings wired to code-loader
- copy: unzip without -d lands implicit=workspace (list/test
  spellings drift fail-closed, at/crontab precedent)
- agentenv: explicit ? HOME block keys drift agent-env-home
  (quoted/escaped/single-line forms)
- notes: CODEOWNERS backstop stated precisely (auto-request
  vs unenforced require-review; owner settings post-merge)
- suites: 9 regression tests (1214/245/66, pristine 0)

* fix(security): close 4 round-21 Codex P1s + notes medium

- consts: webpack/webpack-dev-server join LOAD_DENY
- interp: setarch/linux32/linux64 join wrapper denylist;
  RUNNER_TEMP source exception pinned to muse-vars.env
- varmap: brace expansions ({a,b}, {a..z}) in argv0 drift
  unresolved-command (single {a}/{} stay silent)
- notes: enforcement gap tracked in issue #3622
- suites: 8 regression tests (1230/245/66, pristine 0)

* fix(security): close 4 round-22 Codex P1s

- consts: cpack joins LOAD_DENY
- interp: dbus-run-session/dbus-launch join wrapper denylist
- archive: 7z extract without -o lands implicit=workspace;
  sevenz-extract-cwd-fp flipped to drift regression
- awk: whole-word dynamic programs ($prog, cmdsubst) drift
  untrusted-exec (leading quotes stripped for -e'$p')
- suites: 4 new + 1 flipped (1238/245/66, pristine 0)

* fix(security): close 5 round-23 Codex P1s

- interp: start-stop-daemon joins wrapper denylist
- archive: new audit_dpkg_dest (-x/-X/-e/-b destinations,
  CWD-default implicit workspace; info actions silent)
- consts: SECRET_EXPAND_RE covers META_API_KEY +
  ACTIONS_RUNTIME_TOKEN/ACTIONS_ID_TOKEN_REQUEST_TOKEN
- consts: mono joins LOAD_DENY
- consumer: explicit ? SCRIPT_DIR keys drift rebound
  (quote/escape reuse via map_key_value)
- suites: 9 regression tests (1254/247/66, pristine 0)

* fix(security-audit): round-24 Codex findings - bison loader, glob argv0, selftest sharding

- Add bison to LOAD_DENY: -S skeleton runs through m4 and
  m4_esyscmd executes repo scripts with the helper token.
- Reject pathname expansion in command position: b[as][as]h
  becomes bash when a later PR adds a workspace file named
  bash. New glob rule in audit_unresolved_argv (exact [ is
  test, [[ opens a conditional, name[sub]= assigns); env and
  xargs operands re-enter since the shell expands pre-exec.
- Blank ((...)) compounds before helper dispatch so
  arithmetic operators cannot read as glob argv0s; share the
  case-pattern stripper with the run-block dispatcher and
  confine its leading-glob argv0s to the step allowlist.
- Shard muse-review-selftest across 7 parallel matrix jobs
  and fix the stale <2min claim (741 cases re-audit the
  whole tree per case).
- Regressions: loader-bison, 14 glob-argv0 helper cases
  (exact mutation + workspace bash file), 5 run-block
  step-glob cases.

* fix(security-audit): round-25 Codex findings - jar/upx destinations, 8 loader gaps

- Audit jar extraction destinations (audit_jar_dest): -x zones
  each -C dir, CWD-implicit without -C; -c/-u/-i zone the -f
  archive (bundled/dashless/getopt-correct op parsing).
- LOAD_DENY += javadoc (-doclet), protoc (--plugin),
  swift-run/swift-build/swift-test/swift-package, rake
  (-f Rakefile), fastlane (workspace Fastfile); fix stale
  mix/stack/rake/port exclusion comment.
- Canonicalize GNU target-prefixed binutils
  (x86_64-linux-gnu-ld) before the --plugin guard.
- COPY_TOOLS += upx: -o/--output destination, else
  in-place subjects (list spellings fail closed).
- Regressions: 8 loader-*, ld-target-prefix-plugin,
  4 jar-*, 2 upx-*.
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.

2 participants