Skip to content

ci: add PR security heuristics workflow + cross-source audit checks#905

Merged
Salem874 merged 3 commits into
mainfrom
claude/adoring-bardeen-ebQ5x
Jun 3, 2026
Merged

ci: add PR security heuristics workflow + cross-source audit checks#905
Salem874 merged 3 commits into
mainfrom
claude/adoring-bardeen-ebQ5x

Conversation

@Salem874

@Salem874 Salem874 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Adapts the WebMS-Intra pr-security.yml approach to MeedyaDL's Rust + TypeScript + Tauri stack. All checks are non-blocking advisory — the merge gate stays with ci.yml (cargo clippy -D warnings, cargo test, cargo-deny, tsc, eslint, CodeQL). This adds the heuristic layer those gates don't cover and posts a single upserted PR comment.

This PR is the first real-world exercise of the new workflow — it runs pr-security.yml on itself.

What's added

File Purpose
.github/workflows/pr-security.yml 8 advisory checks on PRs to main/release-candidate/beta/alpha, one upserted comment
tools/audit-checks/check_ipc_commands.py Every #[tauri::command] is registered in lib.rs generate_handler[] and every frontend invoke('x') targets a registered command
tools/audit-checks/check_codec_registry.py Every codecs.toml meta resolves_to target is a real codec section and every audio services.gamdl flag is a SongCodec variant
tools/audit-checks/README.md Local-run docs + how to add a check
.github/pull_request_template.md Manual security-review checklist
.claude/CLAUDE.md One convention bullet documenting the above

The 8 workflow checks

  1. gitleaks secrets scan (redacted) · 2. Rust sh -c shell-interpolation · 3. unsafe Rust · 4. frontend sinks (eval/dangerouslySetInnerHTML/innerHTML=) · 5. hardcoded paths · 6. unpinned Actions (non-SHA uses:) · 7. sensitive/proprietary path touches (assets/brand/ is proprietary) · 8. cross-source consistency scripts.

Checks 2–7 scan only PR-changed files; check 8 validates whole-repo state.

Adaptation notes

This is not a copy — WebMS-Intra is PHP. Dropped the inapplicable PHP checks (PHP lint, mysqli SQL-injection, CSRF tokens, Psalm) and re-targeted the heuristic layer onto MeedyaDL's own documented invariants (the "no sh -c" subprocess rule, SHA-pinned Actions, proprietary brand assets, the IPC contract). Added an unpinned-Action detector WebMS lacks, and upserts one PR comment instead of posting a fresh one per push.

Verification

  • Both consistency scripts report zero findings on a clean tree; negative-tested (injected a bad invoke(), a dangling resolves_to, a bogus gamdl= flag → all caught, exit 1 under --strict).
  • Every heuristic regex exercised against deliberately-bad inputs; the unpinned-Action check finds 0 false positives against the real (fully SHA-pinned) repo.
  • actionlint (with bundled shellcheck on the run: scripts) passes clean.

https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m


Generated by Claude Code

claude added 2 commits June 3, 2026 16:30
Adapt the WebMS-Intra PR-security approach to MeedyaDL's Rust/TS/Tauri
stack. All checks are non-blocking advisory; the merge gate stays with
ci.yml (cargo clippy -D warnings, cargo test, cargo-deny, tsc, eslint,
CodeQL). This adds the heuristic layer those gates don't cover.

New .github/workflows/pr-security.yml runs eight checks on PRs to
main/release-candidate/beta/alpha and posts a single upserted comment
(edited in place by hidden marker, not one comment per push):
gitleaks secrets scan, Rust subprocess shell-interpolation (no sh -c),
unsafe Rust, dangerous frontend sinks (eval/dangerouslySetInnerHTML),
hardcoded absolute paths, unpinned GitHub Actions (non-SHA refs),
sensitive/proprietary path touches (assets/brand is proprietary), and
cross-source consistency.

New tools/audit-checks/ holds two zero-dependency Python validators:
- check_ipc_commands.py: every #[tauri::command] is registered in the
  lib.rs generate_handler![] and every frontend invoke('x') targets a
  registered command (the runtime "command not found" class).
- check_codec_registry.py: every codecs.toml meta resolves_to target is
  a real codec section and every audio services.gamdl flag is a kebab
  SongCodec variant.
Both report zero findings on the current tree and exit 1 under --strict
on injected drift.

Also add .github/pull_request_template.md (manual security-review
checklist) and a CLAUDE.md convention entry.

https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
The pinned actions/setup-python SHA (inherited from upstream-gamdl-watch.yml)
is not resolvable on GitHub, so the job failed at action-resolution before
any check ran. The audit-checks scripts are stdlib-only (re / sys / pathlib;
the TOML is regex-parsed, not via tomllib), so the runner's preinstalled
python3 is sufficient and the step can be removed outright.

https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

PR Security Checks

⚠️ 1 category(ies) of findings — these are heuristics, please review each:

PR touches a sensitive / proprietary path (assets/brand is PROPRIETARY; confirm intentional)

.github/workflows/pr-security.yml

Generated by .github/workflows/pr-security.yml. Non-blocking — the merge gate is ci.yml. Cross-source checks live in tools/audit-checks/ and run locally. False positives are expected.

Add .claude/memory/project_pr_security_checks.md (type: project) documenting
the pr-security.yml advisory gate, the two tools/audit-checks consistency
scripts, the design choices (upsert comment, advisory-not-blocking,
stdlib-only scripts), and the gotchas from standing it up (the unresolvable
setup-python SHA still present in upstream-gamdl-watch.yml; detecting CI
success from a remote session). Hook it into MEMORY.md.

The CLAUDE.md convention bullet and the workflow/scripts/template themselves
landed earlier on this branch (PR #905).

https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
@Salem874 Salem874 merged commit 06369e1 into main Jun 3, 2026
12 checks passed
@Salem874 Salem874 deleted the claude/adoring-bardeen-ebQ5x branch June 3, 2026 19:51
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