Skip to content

fix: exempt github_api_helpers.cjs from SEC-004 (false positive) - #43731

Merged
pelikhan merged 4 commits into
mainfrom
copilot/sec-004-add-exemption-for-github-api-helpers
Jul 6, 2026
Merged

fix: exempt github_api_helpers.cjs from SEC-004 (false positive)#43731
pelikhan merged 4 commits into
mainfrom
copilot/sec-004-add-exemption-for-github-api-helpers

Conversation

Copilot AI commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

SEC-004 conformance check was flagging github_api_helpers.cjs for containing body fields without calling a sanitization function. This is a false positive — the file is a low-level GraphQL API helper whose callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) already invoke sanitizeContent() before passing body into it.

Change

Added the @safe-outputs-exempt annotation near the top of github_api_helpers.cjs, which the checker already recognizes (lines 145–148 of check-safe-outputs-conformance.sh):

// @safe-outputs-exempt SEC-004: low-level GraphQL helper; body is sanitized by callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) before it reaches this layer.

No changes to the conformance checker were needed. Adding sanitization inside the helper itself was intentionally avoided — double-sanitization would risk stripping workflow markers and allowed mentions preserved by the caller layer.

Copilot AI and others added 2 commits July 6, 2026 07:29
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add exemption for github_api_helpers.cjs in SEC-004 conformance check fix: exempt github_api_helpers.cjs from SEC-004 (false positive) Jul 6, 2026
Copilot AI requested a review from pelikhan July 6, 2026 07:32
@pelikhan
pelikhan marked this pull request as ready for review July 6, 2026 07:45
Copilot AI review requested due to automatic review settings July 6, 2026 07:45
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #43731 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. Test Quality Sentinel skipped.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to resolve a SEC-004 safe-outputs conformance false positive by documenting an exemption for a low-level GraphQL helper (github_api_helpers.cjs) where body values are expected to be sanitized by higher-level callers.

Changes:

  • Added a @safe-outputs-exempt SEC-004 annotation to actions/setup/js/github_api_helpers.cjs to bypass the conformance heuristic for body usage in this helper.
  • Regenerated numerous workflow .lock.yml files, primarily altering YAML block chomping / trailing-newline handling in embedded scripts.
Show a summary per file
File Description
actions/setup/js/github_api_helpers.cjs Adds SEC-004 exemption annotation for the helper file to avoid false-positive conformance failures.
.github/workflows/workflow-skill-extractor.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/workflow-health-manager.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/weekly-blog-post-writer.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/unbloat-docs.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/uk-ai-operational-resilience.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/test-quality-sentinel.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/step-name-alignment.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/static-analysis-report.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/stale-repo-identifier.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/spec-extractor.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/schema-consistency-checker.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/repository-quality-improver.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/release.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/prompt-clustering-analysis.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/pr-description-caveman.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/objective-impact-report.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/mergefest.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/mattpocock-skills-reviewer.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/linter-miner.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/lint-monster.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/issue-arborist.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/impeccable-skills-reviewer.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/gpclean.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/glossary-maintainer.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/eslint-monster.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/docs-noob-tester.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/designer-drift-audit.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/design-decision-gate.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/dependabot-burner.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/delight.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/dataflow-pr-discussion-dataset.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/daily-spdd-spec-planner.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/daily-security-observability.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/daily-multi-device-docs-tester.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/daily-community-attribution.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/daily-ambient-context-optimizer.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/copilot-pr-nlp-analysis.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/copilot-centralization-drilldown.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/contribution-check.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/code-simplifier.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/cli-consistency-checker.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/ci-doctor.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/aw-failure-investigator.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/auto-triage-issues.lock.yml Lockfile regeneration / YAML block chomping change (`
.github/workflows/architecture-guardian.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/agentic-token-trend-audit.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/agentic-token-optimizer.lock.yml Lockfile regeneration / embedded script formatting change.
.github/workflows/agentic-token-audit.lock.yml Lockfile regeneration / embedded script formatting change.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 49/49 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment on lines 492 to +493
name: Build Inventory
run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Run compilation validation and capture output\ngh aw compile --validate > /tmp/gh-aw/agent/compile-validate.txt 2>&1 || true\n# List executable workflow files (exclude shared/ subdirectory)\nls .github/workflows/*.md 2>/dev/null > /tmp/gh-aw/agent/workflow-list.txt || true\necho \"Inventory complete: $(wc -l < /tmp/gh-aw/agent/workflow-list.txt | tr -d ' ') workflows found\"\n"
run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Run compilation validation and capture output\ngh aw compile --validate > /tmp/gh-aw/agent/compile-validate.txt 2>&1 || true\n# List executable workflow files (exclude shared/ subdirectory)\nls .github/workflows/*.md 2>/dev/null > /tmp/gh-aw/agent/workflow-list.txt || true\necho \"Inventory complete: $(wc -l < /tmp/gh-aw/agent/workflow-list.txt | tr -d ' ') workflows found\""
@github-actions github-actions Bot mentioned this pull request Jul 6, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underlying fix is correct — the current callers do sanitize, SEC-004 is genuinely a false positive, and the conformance checker passes. Two non-blocking concerns about the exemption's forward-looking robustness are noted inline.

### Review themes

The exemption is correct today but operates at file scope, not function scope. The checker does a whole-file continue when it finds @safe-outputs-exempt SEC-004, which means any future body-taking function added to github_api_helpers.cjs will be silently excluded from SEC-004 checks. Given the module already has 11+ importers and is growing, this scope needs to be documented explicitly in the annotation or constrained in the checker.

Caller contract is asserted but not enforced. The annotation names two callers as the sanitization guarantee, but createDiscussionComment is a public export and the contract has no machine-readable enforcement (no JSDoc precondition, no type brand). A future caller bypassing sanitization would not be caught by SEC-004 (because the file is exempted) and would not be caught by types. Adding a JSDoc @param note adjacent to the function is a low-effort improvement.

The core security claim holds. Both named callers call sanitizeContent() before reaching the helper. No double-sanitization hazard exists. The lock file bumps are correct.

🔎 Code quality review by PR Code Quality Reviewer · 81.4 AIC · ⌖ 6.91 AIC · ⊞ 5.4K
Comment /review to run again

// @ts-check
/// <reference types="@actions/github-script" />

// @safe-outputs-exempt SEC-004: low-level GraphQL helper; body is sanitized by callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) before it reaches this layer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File-level exemption silently blanket-covers all future functions in this module. The checker skips the entire file when it finds @safe-outputs-exempt SEC-004, so any future function added here that accepts user-controlled body content will be permanently invisible to SEC-004 with no warning.

💡 Details and suggested mitigation

check-safe-outputs-conformance.sh lines 145–148 does a whole-file continue on match:

if grep -q "`@safe-outputs-exempt`[[:space:]]\+SEC-004" "$handler"; then
  continue  # skips the whole file
fi

github_api_helpers.cjs is already imported by 11 other files. Only createDiscussionComment (line ~188) actually carries user-controlled body content — all other exports (logGraphQLError, fetchAllRepoLabels, getFileContent, resolveTopLevelDiscussionCommentId, etc.) are body-free today. But as the module grows, any future function that does accept a body will never be flagged.

Suggested mitigations (pick one):

  • Update the annotation to explicitly state the whole-file scope and the invariant: // @safe-outputs-exempt SEC-004: WHOLE-FILE — only createDiscussionComment carries user-controlled body; all other exports are body-free. Update if new body-taking functions are added.
  • Or update the checker to support a narrower function-adjacent annotation so the exemption scope is bounded.

// @ts-check
/// <reference types="@actions/github-script" />

// @safe-outputs-exempt SEC-004: low-level GraphQL helper; body is sanitized by callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) before it reaches this layer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotation asserts caller sanitization but nothing enforces that contract; stale annotation risk is real. The annotation names two callers as the sanitization guarantee, but there are currently 10+ other importers of this module and createDiscussionComment is a public export — any new caller can bypass sanitization silently.

💡 Details

Currently createDiscussionComment is called only from add_comment.cjs (sanitizes at line 646) and add_reaction_and_edit_comment.cjs (sanitizes at line 245). Those two are correct.

But the function is exported and the module is already imported by 11 other files. Nothing in the code, types, or checker prevents a third caller from passing unsanitized content. As the exemption suppresses the whole file from SEC-004 (see sibling comment), the usual safety net for new callers is also gone.

A low-cost mitigation: add a JSDoc @param note or a branded type so the expectation is machine-visible:

/**
 * `@param` {string} body - Comment body. MUST be pre-sanitized by the caller
 *   using sanitizeContent() before passing here. Do not add sanitization
 *   inside this function — double-sanitization strips allowed mentions.
 */
async function createDiscussionComment(github, discussionId, body, replyToId) {

This doesn't prevent misuse but makes the contract explicit in IDEs and makes it visually obvious when reviewing future callers.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: SEC-004 exemption for github_api_helpers.cjs

Change adds @safe-outputs-exempt SEC-004 to github_api_helpers.cjs with 48 lock-file trailing-newline normalizations.

Correctness: annotation recognized by conformance checker (line 146). Both callers sanitize before passing body to createDiscussionComment. No other callers exist. Lock changes are cosmetic recompile artifacts. No issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 91.3 AIC · ⌖ 6.27 AIC · ⊞ 4.9K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs — the fix is correct but has two small gaps that could create future maintenance risk.

📋 Key Themes & Highlights

Key Themes

  • Missing regression test: No test verifies that check-safe-outputs-conformance.sh correctly skips the file after the annotation. A regex change in the checker would silently re-introduce the false positive (or fail to catch a real violation).
  • Undocumented sanitization contract: createDiscussionComment's JSDoc doesn't state that body must be pre-sanitized by callers. Future contributors adding a third caller won't see this invariant without reading the conformance checker script.

Positive Highlights

  • ✅ Root cause correctly identified: the checker triggers on "body" references without a co-located sanitize call; helper is validly exempt because sanitization is enforced one layer up.
  • ✅ Exemption justification is clear and specific (names the two caller files and the reason for avoiding double-sanitization).
  • ✅ Follows the established pattern — other files in actions/setup/js/ use the same @safe-outputs-exempt convention correctly.
  • ✅ Lock files are correctly auto-generated; no manual edits needed.

Summary

The exemption is accurate and the reasoning is sound. The two comments above are not blocking — they're incremental improvements to make the invariant explicit and to add a safety net. Happy to approve once those are addressed or explicitly deferred.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 76.2 AIC · ⌖ 5.39 AIC · ⊞ 6.7K
Comment /matt to run again

// @ts-check
/// <reference types="@actions/github-script" />

// @safe-outputs-exempt SEC-004: low-level GraphQL helper; body is sanitized by callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) before it reaches this layer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] No regression test guards the exemption: if the checker's exemption regex ever changes (e.g. adding a colon variant), this annotation silently stops matching and the false positive returns — or a real violation could be silently skipped.

💡 Suggested regression test

Consider adding a small shell test that verifies the checker exits clean when run against a stub file containing the exemption annotation and a body field:

# test: sec-004 exemption is honoured
stub=$(mktemp --suffix=.cjs)
printf '%s\n' '// `@safe-outputs-exempt` SEC-004: test' 'const x = { "body": foo };' > "$stub"
grep -q '`@safe-outputs-exempt`[[:space:]]\+SEC-004' "$stub" && echo PASS || echo FAIL
rm "$stub"

Without this, a future refactor of the exemption pattern in check-safe-outputs-conformance.sh could re-introduce the false positive invisibly.

@copilot please address this.

// @ts-check
/// <reference types="@actions/github-script" />

// @safe-outputs-exempt SEC-004: low-level GraphQL helper; body is sanitized by callers (add_comment.cjs, add_reaction_and_edit_comment.cjs) before it reaches this layer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The createDiscussionComment JSDoc does not document the sanitization contract — that callers must pre-sanitize body before passing it in. A future caller could omit sanitization and silently introduce a real SEC-004 violation without the checker catching it (since the file is now exempt).

💡 Suggested JSDoc addition

Add a @remarks or a note to the @param body line:

/**
 * ...
 * `@param` {string} body - Comment body. MUST be pre-sanitized by the caller
 *   (e.g. via sanitizeContent()) before being passed here. This file is
 *   exempt from SEC-004 checks on the assumption that all callers sanitize.
 * ...
 */

This makes the invariant machine-readable and visible to future contributors without requiring them to trace back through the conformance checker script.

@copilot please address this.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR Triage

Category chore
Risk Low
Score 40/100 (impact 15 + urgency 12 + quality 13)
Action batch_review

Adds @safe-outputs-exempt annotation to github_api_helpers.cjs to suppress false positive SEC-004 alert. 1 line annotation; callers already sanitize. Very low risk.

Run §28776188550

Generated by 🔧 PR Triage Agent · 98.5 AIC · ⌖ 11.4 AIC · ⊞ 5.5K ·

@pelikhan
pelikhan merged commit 7019a84 into main Jul 6, 2026
14 checks passed
@pelikhan
pelikhan deleted the copilot/sec-004-add-exemption-for-github-api-helpers branch July 6, 2026 08:12
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Safe Outputs Conformance] SEC-004: github_api_helpers.cjs flagged for body field without sanitization (false positive — add exemption)

3 participants