Skip to content

Commit d37caa4

Browse files
harden: address actionable Hypatia advisory findings (#41)
Resolve the clearly-actionable, low-risk items from the Hypatia neurosymbolic scan. Genuine false positives are intentionally left in place and documented in the PR description rather than mangled. - instant-sync.yml: presence-gate the repository-dispatch step on FARM_DISPATCH_TOKEN. The `secrets` context is unavailable in `if:`, so the token is mapped to a job-level env var and both steps skip when it is unset (e.g. on forks) instead of invoking the secret-consuming action with an empty token. - scorecard.yml: declare explicit least-privilege job permissions (contents:read, security-events:write, id-token:write) matching the scopes the reusable Scorecard workflow declares/needs. - codeql.yml: add the `actions` language to the analysis matrix so the workflow files themselves are scanned. - run.js / Justfile: replace `deno run --allow-all` with scoped `--allow-read --allow-run --allow-env` (run.js needs no net/write). - fli-editable.js: clear the cell via replaceChildren() instead of `innerHTML = ''`. Claude-Session: https://claude.ai/code/session_01LvsZgNxFbeqfRmrVFNhJ8G Co-authored-by: Claude <noreply@anthropic.com>
1 parent df47771 commit d37caa4

6 files changed

Lines changed: 32 additions & 8 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ jobs:
3333
include:
3434
- language: javascript-typescript
3535
build-mode: none
36+
# Scan the GitHub Actions workflows themselves (CodeQL `actions`
37+
# language). (Hypatia workflow_audit: codeql_missing_actions_language)
38+
- language: actions
39+
build-mode: none
3640

3741
steps:
3842
- name: Checkout

.github/workflows/instant-sync.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@ jobs:
1515
dispatch:
1616
runs-on: ubuntu-latest
1717
timeout-minutes: 10
18+
# Presence gate: the `secrets` context is not available in `if:`, so map
19+
# the token to a job-level env var and skip the dispatch when it is unset
20+
# (e.g. on forks) rather than invoking the secret-consuming action with an
21+
# empty token. (Hypatia workflow_audit: secret_action_without_presence_gate)
22+
env:
23+
FARM_DISPATCH_TOKEN: ${{ secrets.FARM_DISPATCH_TOKEN }}
1824
steps:
1925
- name: Trigger Propagation
26+
if: ${{ env.FARM_DISPATCH_TOKEN != '' }}
2027
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3
2128
with:
22-
token: ${{ secrets.FARM_DISPATCH_TOKEN }}
29+
token: ${{ env.FARM_DISPATCH_TOKEN }}
2330
repository: hyperpolymath/.git-private-farm
2431
event-type: propagate
2532
client-payload: |-
@@ -31,4 +38,5 @@ jobs:
3138
}
3239
3340
- name: Confirm
41+
if: ${{ env.FARM_DISPATCH_TOKEN != '' }}
3442
run: echo "::notice::Propagation triggered for ${{ github.event.repository.name }}"

.github/workflows/scorecard.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,14 @@ permissions: read-all
1212

1313
jobs:
1414
analysis:
15+
# Explicit least-privilege permissions for the reusable Scorecard call:
16+
# contents:read to check out, security-events:write to upload the SARIF,
17+
# id-token:write to publish results to the OpenSSF API. Matches the scopes
18+
# declared by scorecard-reusable.yml@5a93d9d5.
19+
# (Hypatia workflow_audit: scorecard_wrapper_missing_job_permissions)
20+
permissions:
21+
contents: read
22+
security-events: write
23+
id-token: write
1524
uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@5a93d9d57cc04de4002d6d0ecd336fc7a8698910
1625
secrets: inherit

Justfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,10 @@ lint:
671671
# ═══════════════════════════════════════════════════════════════════════════════
672672
673673
# Launch GSA (platform-detect, self-heal, git cycle)
674+
# Scoped Deno permissions (read source/stat, run subprocesses, read env) —
675+
# run.js needs no network or write capability of its own.
674676
run:
675-
deno run --allow-all run.js
677+
deno run --allow-read --allow-run --allow-env run.js
676678
677679
# Run the GSA binary directly (status probe, config, etc.)
678680
run-admin *args: build-ffi

run.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
// for Game Server Admin (GSA)
66
//
77
// Usage:
8-
// deno run --allow-all run.js # auto-detect and launch
9-
// deno run --allow-all run.js --help # show usage
10-
// deno run --allow-all run.js --reflect
8+
// deno run --allow-read --allow-run --allow-env run.js # auto-detect and launch
9+
// deno run --allow-read --allow-run --allow-env run.js --help # show usage
10+
// deno run --allow-read --allow-run --allow-env run.js --reflect
1111

1212
// ─────────────────────────────────────────────────────────────────────────────
1313
// REGISTRY — homoiconic data; the script reads this at runtime via reflect()
@@ -248,7 +248,7 @@ if (import.meta.main) {
248248
${c.bold}${REGISTRY.identity.display} — run.js${c.reset}
249249
${REGISTRY.identity.license} | ${REGISTRY.identity.repo}
250250
251-
Usage: deno run --allow-all run.js [OPTIONS]
251+
Usage: deno run --allow-read --allow-run --allow-env run.js [OPTIONS]
252252
253253
Options:
254254
--help, -h Show this help

src/gui/fli/fli-editable.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,9 @@
216216
+ 'border:1px solid var(--link-color,#58a6ff);border-radius:4px;outline:none;'
217217
+ 'box-shadow:0 0 0 2px rgba(88,166,255,0.2);';
218218

219-
// Replace content with input
220-
element.innerHTML = '';
219+
// Replace content with input (replaceChildren clears without an
220+
// innerHTML re-parse — no markup interpretation, no injection surface).
221+
element.replaceChildren();
221222
element.appendChild(input);
222223
input.focus();
223224
if (input.select) input.select();

0 commit comments

Comments
 (0)