Skip to content

fix(security): adjudicate the identifier interpolations, lock down the workflow - #16

Merged
shenzhaoyan merged 2 commits into
mainfrom
aikido/2026-09-23
Sep 26, 2026
Merged

shenzhaoyan merged 2 commits into
mainfrom
aikido/2026-09-23

Conversation

@shenzhaoyan

Copy link
Copy Markdown
Contributor

No description provided.

shenzhaoyan and others added 2 commits September 23, 2026 12:21
- `persist-credentials: false` on checkout (Aikido prio 30). Nothing here
  pushes, tags or opens a PR, so the token checkout writes into .git/config
  by default is only an extra thing for a later step — or for the dependency
  code `go test` runs — to find.
- Dropped `id-token: write`. It had no consumer: nothing in this workflow
  does OIDC to a cloud provider.
- `actions/setup-go@v4` -> v5. v4 runs on the node16 runtime GitHub removed;
  actionlint reports it on main. Same inputs, so a runtime bump only.
  checkout v4 -> v5 at the same time, matching the rest of the fleet.

Verified: actionlint 0 (1 on main), go build, go vet and
go test -short -p=1 -count=1 all pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Aikido AIK_go_G202 on the insert and update query builders. Adjudicated a
false positive: what is interpolated is SQL identifiers — the table name and
the two column names — which cannot be bound as query parameters. Neither is
request data. tableName comes from the embedding application (a constant, or
its own configuration — the same configuration that carries the database DSN,
so whoever can set it can already reach the database directly), the column
names are this package's own. Every request-derived value is bound with `?`
in attempt; Aikido auto-ignored that line for exactly that reason.

Per the repo-over-dashboard rule the suppression lives in the source with its
reason on the line, not as a dashboard click.

Two more sites have the same shape and were not flagged: the select query in
New and the CREATE TABLE in Migrate. Left unmarked — silencing lines nothing
reported is how a suppression habit starts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Critical workflow pinning and SQL validation issues remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 High severity · 1 Low severity

Open (4)
What changed in this PR

This PR aims to secure SQL identifier handling and harden the GitHub Actions workflow.

Changes:

  • Documents SQL identifier interpolation and adds suppression annotations.
  • Restricts workflow permissions and disables persisted checkout credentials.
  • Updates checkout and Go setup actions.
File Review summary
sqlrl/​sql.go tableName remains insufficiently validated before SQL interpolation (critical, 2 votes). The nosec suppressions are invalid on both calls (nit, 2 votes).
.github/​workflows/​go.yml actions/checkout@v5 and actions/setup-go@v5 remain mutable tags and should be pinned to verified full-length commit SHAs (critical, 2 votes each).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/go.yml
# persist-credentials: false — checkout writes a token into .git/config by
# default and nothing here pushes, tags or opens a PR, so the credential is
# only an extra thing for a step (or a dependency this workflow runs) to find.
uses: actions/checkout@v5
Comment thread .github/workflows/go.yml
# v4 runs on the node16 action runtime, which GitHub has removed — actionlint
# reports it as "too old to run on GitHub Actions". Same inputs on v5
# (go-version-file + cache), so this is a runtime bump only.
uses: actions/setup-go@v5
Comment thread sqlrl/sql.go
Comment on lines +67 to +70
// of them is request data: tableName is what the embedding application passes to
// New (a constant, or a value from its own configuration — the same configuration
// that carries the database DSN, so whoever can set it can already reach the
// database directly), and the column names are package-level values this package
Comment thread sqlrl/sql.go
s.insertQuery = fmt.Sprintf(`
INSERT INTO %s (%s, %s) VALUES (?, ?)
`, s.tableName, ColumnKey, ColumnTimeToAct)
`, s.tableName, ColumnKey, ColumnTimeToAct) // nosec — SQL identifier, not request data (see above)
@shenzhaoyan
shenzhaoyan merged commit c2bdc5d into main Sep 26, 2026
2 checks passed
@shenzhaoyan
shenzhaoyan deleted the aikido/2026-09-23 branch September 26, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants