Repository navigation
chore: delete unused firebase-admin.ts - #1116
Conversation
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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
💤 Files with no reviewable changes (1)
📝 WalkthroughWalkthroughThe 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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
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): 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-*.
Summary
apps/web/src/lib/firebase-admin.ts— no imports found anywhere in the codebaseexpo-server-sdkmigrationTest plan
pnpm turbo typecheck— 0 errors🤖 Generated with Claude Code
Summary by CodeRabbit