Skip to content

zac343/csv-guard-action

Repository files navigation

CSV Guard Action

Audit a generated CSV in GitHub Actions for formula-like cell prefixes, duplicate rows, empty rows, whitespace changes, and header normalization. The Action runs entirely on the caller's runner and does not upload CSV data to CSV Guard or any third-party service.

This is a non-destructive check: the input file is never rewritten. Logs, outputs, and the job summary contain only the workspace-relative filename and aggregate counts—not CSV rows or cell values.

Use it

Generate the CSV first, then point the Action at that one explicit file:

name: CSV audit

on:
  pull_request:

permissions:
  contents: read

jobs:
  csv-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
      - name: Generate a CSV fixture (replace with your own command)
        run: npm ci && npm run build:csv-fixture
      - id: csv_guard
        uses: zac343/csv-guard-action@v1.0.0
        with:
          path: artifacts/export.csv
      - run: echo "Formula-like prefixes ${{ steps.csv_guard.outputs.risky-prefixes }}"

For the strongest supply-chain pin, replace the version tag with the release's full commit SHA. A full commit SHA is immutable; a tag can be moved.

By default the step fails when one or more formula-like prefixes are found. To collect counts without failing:

- uses: zac343/csv-guard-action@v1.0.0
  with:
    path: artifacts/export.csv
    fail-on-findings: "false"

Inputs

Input Default Meaning
path required One .csv file inside GITHUB_WORKSPACE. Absolute paths, traversal, symlink files, and non-CSV extensions are rejected.
fail-on-findings true Fail the step when formula-like prefixes are detected. Must be true or false.
formula-prefix-mode portable-apostrophe Audit against portable-apostrophe or excel-tab already-prefixed behavior. The Action still does not modify the file.

Outputs

All outputs are integer counts: input-rows, output-rows, risky-prefixes, duplicates, empty-rows, trimmed-cells, and normalized-headers.

Detection boundary

CSV Guard checks =, +, -, and @ after Unicode normalization and leading whitespace/control characters. It also checks segments exposed by comma, semicolon, tab, pipe, CR, or LF reinterpretation. The parser supports quoted delimiters, escaped quotes, and embedded newlines.

Negative numbers such as -42 are deliberately reported because a conservative prefix policy would turn them into text. This is a false-positive trade-off, not evidence that the value is malicious.

An apostrophe or tab changes the underlying value, and spreadsheet behavior can change after save/reopen or when a downstream parser uses another delimiter. Finding zero prefixes is not a universal safety guarantee. Review the CSV Guard lifecycle guide and OWASP CSV Injection guidance before choosing an export policy.

Limits and privacy

  • UTF-8 only, with invalid byte sequences rejected.
  • Maximum file size: 10 MiB.
  • Maximum 100,000 data rows, 5,000 columns, 500,000 normalized cells, and 2,000,000 characters per field.
  • No network calls, telemetry, token input, automatic commits, or artifact uploads.
  • No CSV content is included in outputs, annotations, or the job summary.

Use ordinary pull_request workflows with permissions: contents: read. Do not use pull_request_target to process untrusted pull-request files with privileged secrets.

Development

npm ci
npm run verify
git diff --exit-code -- dist/action.cjs

The release bundle is committed so callers do not install dependencies at runtime. Runtime dependencies are intentionally zero.

For interactive local cleaning, use CSV Guard. Bugs should use synthetic or redacted fixtures only; report vulnerabilities through GitHub private vulnerability reporting.

MIT licensed.

About

Privacy-first GitHub Action for auditing CSV formula-injection risk

Topics

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors