Summary
- Scan Date: 2026-03-22 (Sunday)
- Scan Mode: WEEKLY FULL SCAN (all 6 techniques)
- Files Analyzed: 499 (461
.cjs + 38 .sh)
- Findings: 1 (MEDIUM severity)
- Status: ⚠️ Review required
Critical Issues
None. No backdoors, secret leaks, destructive code, obfuscated payloads, or suspicious network domains were detected.
Finding 1: Unsanitized Path in Dynamic require() — MEDIUM
Type: DYNAMIC_REQUIRE_PATH_TRAVERSAL
Severity: MEDIUM
Location: actions/setup/js/safe_output_handler_manager.cjs:171
Vulnerable code (simplified):
// scriptFilename comes directly from GH_AW_SAFE_OUTPUT_SCRIPTS env var (JSON-parsed)
const scriptPath = require("path").join(
process.env.RUNNER_TEMP || "/tmp",
"gh-aw", "actions",
scriptFilename // ← not sanitized for path traversal
);
const scriptModule = require(scriptPath);
Why it matters:
path.join() does NOT prevent directory traversal. A scriptFilename value like ../../../some/other/file would resolve outside the intended $RUNNER_TEMP/gh-aw/actions/ directory. Since require() then loads the resolved path, an attacker who controls the GH_AW_SAFE_OUTPUT_SCRIPTS environment variable could cause arbitrary .cjs files from the runner filesystem to be loaded and executed.
Context:
GH_AW_SAFE_OUTPUT_SCRIPTS is populated by the workflow compiler from user-defined safe-outputs.scripts configuration. If untrusted workflow inputs can influence this value (e.g., via expression injection), it becomes an execution vector.
Forensics:
Repository history is shallow (1 commit visible: debeacb — docs: update dictation skill glossary with current project terms). Unable to determine the exact commit that introduced this pattern from available history.
Remediation Tasks
Scan Results by Technique
View All Technique Results
| Technique |
Result |
| Pattern Analysis |
✅ Clean — no secret exfiltration, no eval with external input, no suspicious domains, no backdoor keywords |
| AST Inspection |
✅ Clean — no suspicious function names, no unusual exports |
| Entropy Analysis |
✅ Clean — no anomalous base64/hex blobs, no obfuscated payloads |
| Network Analysis |
✅ Clean — all network calls target expected GitHub/Microsoft endpoints |
| Behavioral Analysis |
✅ Clean — no time bombs, no anti-debugging, no persistence mechanisms |
| Dependency Audit |
⚠️ 1 finding — dynamic require() path without traversal sanitization |
References
- Workflow Run: §23405378463
- Scanned Directories:
actions/setup/js/ (461 files), actions/setup/sh/ (38 files)
- Cache State:
/tmp/gh-aw/cache-memory/security-red-team/
Generated by Daily Security Red Team Agent · ◷
Summary
.cjs+ 38.sh)Critical Issues
None. No backdoors, secret leaks, destructive code, obfuscated payloads, or suspicious network domains were detected.
Finding 1: Unsanitized Path in Dynamic require() — MEDIUM
Type:
DYNAMIC_REQUIRE_PATH_TRAVERSALSeverity: MEDIUM
Location:
actions/setup/js/safe_output_handler_manager.cjs:171Vulnerable code (simplified):
Why it matters:
path.join()does NOT prevent directory traversal. AscriptFilenamevalue like../../../some/other/filewould resolve outside the intended$RUNNER_TEMP/gh-aw/actions/directory. Sincerequire()then loads the resolved path, an attacker who controls theGH_AW_SAFE_OUTPUT_SCRIPTSenvironment variable could cause arbitrary.cjsfiles from the runner filesystem to be loaded and executed.Context:
GH_AW_SAFE_OUTPUT_SCRIPTSis populated by the workflow compiler from user-definedsafe-outputs.scriptsconfiguration. If untrusted workflow inputs can influence this value (e.g., via expression injection), it becomes an execution vector.Forensics:
Repository history is shallow (1 commit visible:
debeacb—docs: update dictation skill glossary with current project terms). Unable to determine the exact commit that introduced this pattern from available history.Remediation Tasks
Task 1: Add path traversal sanitization for
scriptFilenameinsafe_output_handler_manager.cjs:171scriptFilenamecontains no path separators (/,\) or..sequencesif (scriptFilename.includes('/') || scriptFilename.includes('\\') || scriptFilename.includes('..')) { core.error('Invalid script filename'); continue; }path.basename(scriptFilename)to strip any directory components before joiningscriptPathstarts with the expected base directory before callingrequire()Task 2: Audit
GH_AW_SAFE_OUTPUT_SCRIPTSpopulation pathGH_AW_SAFE_OUTPUT_SCRIPTSScan Results by Technique
View All Technique Results
require()path without traversal sanitizationReferences
actions/setup/js/(461 files),actions/setup/sh/(38 files)/tmp/gh-aw/cache-memory/security-red-team/