Skip to content

fix(api): stop comma-splitting -H/--field/--raw-field values - #14

Merged
emsearcy merged 3 commits into
mainfrom
claude/autopatch-scan-29eb251e-vuln-4956725-1o1rj1
Oct 14, 2026
Merged

emsearcy merged 3 commits into
mainfrom
claude/autopatch-scan-29eb251e-vuln-4956725-1o1rj1

Conversation

@dealako

@dealako dealako commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Summary

lfx api declares -H/--header, -F/--field and --raw-field as urfave/cli v3 StringSliceFlags. By default urfave/cli splits every slice flag value on ,, and there is no way to escape a literal comma. So one flag value turned into several entries:

  • --raw-field 'a=x,b=y' produced the body {"a":"x","b":"y"} instead of {"a":"x,b=y"}
  • --field 'note=hi,active=true' also added "active": true as a boolean
  • -H 'X: a,Authorization: z' set a second header, and because headers use Header.Set, it replaced the Authorization/Content-Type values the command had already set

If a wrapper script puts untrusted text into a single flag value, whoever controls that text can add arbitrary body fields or headers to a request sent with the user's bearer token. The endpoint, method and token can't be changed this way. It also broke ordinary values that contain commas, such as Accept: a, b and desc=hello, world.

Changes

  • internal/commands/api.go: set DisableSliceFlagSeparator: true on the api command, so each flag occurrence becomes exactly one element. This setting has to go on api and not the root command: urfave/cli uses the setting of the command that parses the flag and does not take it from parent commands. You still pass multiple fields or headers by repeating the flag.
  • internal/commands/api_test.go: regression tests that run the real api command under a root command:
    • --raw-field 'a=x,b=y' → {"a":"x,b=y"}
    • --field 'c=1,active=true' → {"c":"1,active=true"}
    • -H 'X: a,Authorization: z' → one header value

Behavior change

Anyone who relied on -H 'A: 1,B: 2' or -F a=1,b=2 meaning two entries now needs to repeat the flag. This splitting was never documented in the README.

Testing

  • go test ./... passes. Without the fix, the new tests fail and show the injected entries.
  • make check passes (go vet, golangci-lint: 0 issues).
  • An independent review checked every way these flags can be passed (--flag v, --flag=v, -H v, -H=v, flags after the path, root flags before api) and found each one now produces a single entry.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kvw34hYiaHVuYdeVXA7TLd


Generated by Claude Code

dealako and others added 2 commits October 1, 2026 22:28
urfave/cli v3 splits every StringSliceFlag value on "," by default,
with no escape for a literal comma. A single --raw-field 'a=x,b=y' was
therefore delivered as two elements and marshalled into two JSON body
keys, and -H 'X: a,Authorization: z' set a second (overriding) header.
A wrapper script interpolating untrusted text into one flag value could
inject arbitrary body fields or headers into a request sent with the
user's bearer token.

Set DisableSliceFlagSeparator on the api command so each flag
occurrence is exactly one element. It has to live on the api command
itself: urfave/cli applies the separator config of the command parsing
the flag and does not inherit it from the root. Repeating the flag
remains the way to pass multiple fields or headers.

Add regression tests that parse through the real api command.

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kvw34hYiaHVuYdeVXA7TLd
Guard against the regression tests passing vacuously if parsing ever
short-circuits (e.g. help is shown) without invoking the action.

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kvw34hYiaHVuYdeVXA7TLd
Copilot AI balanced review requested due to automatic review settings October 1, 2026 22:30
@dealako
dealako requested review from a team and emsearcy as code owners October 1, 2026 22:30

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

🟢 Approval recommended

The focused parser change correctly addresses the issue and is covered by command-level regression tests.

Review effort: Balanced
Findings: None

What changed in this PR

Prevents comma-containing API flag values from being split into unintended fields or headers.

Changes:

  • Disables slice-value comma splitting for lfx api.
  • Adds regression tests for comma-containing fields and headers.
File Description
internal/​commands/​api.go Preserves each slice-flag occurrence as one value.
internal/​commands/​api_test.go Verifies comma-safe field and header parsing.

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

@dealako
dealako requested a review from jordane October 1, 2026 22:31
@dealako dealako added the security An issue, task, feature, bug, or pull request related security or security audit. label Oct 1, 2026
@dealako dealako self-assigned this Oct 1, 2026
Copilot AI balanced review requested due to automatic review settings October 14, 2026 23:17

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.

🟢 Approval recommended

The targeted fix and regression tests address the reported issue, with only a non-blocking documentation follow-up remaining.

0 open findings

🧠 Review effort: Balanced

@emsearcy
emsearcy merged commit b803b9c into main Oct 14, 2026
9 checks passed
@emsearcy
emsearcy deleted the claude/autopatch-scan-29eb251e-vuln-4956725-1o1rj1 branch October 14, 2026 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security An issue, task, feature, bug, or pull request related security or security audit.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants