Skip to content

security(ci): GitHub Actions permissions hardening — overly broad scopes and missing least-privilege #12

Description

@datalackey

Summary

Four related security findings in .github/workflows/:

1. contents: write overly broad on disabled release job

.github/workflows/javascript-ci.yml:47-48 — The `release` job is gated by `if: false`, so the permission is never granted in practice. However, if `if: false` is removed without a separate review, the job runs with write access to repository contents on every push to `main`.

Fix: Scope the permission explicitly to the minimum needed for a release (e.g. only add `contents: write` at the step level, or document the intent in a comment so a reviewer knows to re-evaluate before removing the gate).

2. No explicit permissions: on build job

.github/workflows/javascript-ci.yml:9 — The build job inherits the repository's default GITHUB_TOKEN scope. Adding an explicit `permissions: {}` (or minimal scope such as `contents: read`) enforces least-privilege as defence-in-depth.

Fix: Add `permissions: contents: read` (or `permissions: {}`) to the build job.

3. Path traversal in validateRelativeLink

`src/markdown/validateRelativeLink.ts:22` — `path.resolve(sourceDir, filePart)` with a crafted link like `../../../../etc/shadow` silently resolves to an arbitrary filesystem path. The tool is read-only and local, so exploitability is low, but a maliciously crafted Markdown file could probe for the existence of arbitrary files.

Fix: After resolving the path, assert it is still under the repository root (e.g. `if (!resolved.startsWith(repoRoot)) throw …`), or document this as an accepted risk.

4. --debug logs full config object to stderr

`src/cli/runCli.ts:94-96`, `src/cli/parseStandardCli.ts:169` — Full `config` and raw `argv` are written to stderr when `--debug` is passed. `RunConfig` currently contains no secrets, but this is a latent risk if credentials are ever threaded through config (e.g. auth tokens for private link validation).

Status: Redaction-risk comments have been added above both `debugLog` call sites. No runtime change yet.

Fix: Either add a config-scrubbing step before logging, or document the accepted risk in CLI-BEHAVIOR.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions