Skip to content

Stop an exported API key reaching the dot -V child process in shape - #28

Open
gitkodak wants to merge 1 commit into
mainfrom
fix-graphviz-version-key-leak
Open

Stop an exported API key reaching the dot -V child process in shape#28
gitkodak wants to merge 1 commit into
mainfrom
fix-graphviz-version-key-leak

Conversation

@gitkodak

Copy link
Copy Markdown
Owner

Summary

Response to an external review of ccd1113 (KAN-129), which found three things. Two are fixed here; the third is a documented, deliberate trade-off with no code defect, so no change was made for it.

Fixed — High: API key leak (cli.py)
unifi-map shape's Graphviz-version probe (_graphviz_version, called from cmd_shape) ran dot -V with the plain inherited environment rather than layout.py's scrubbed one. The two Graphviz child processes used to actually render a map have stripped an exported UNIFI_API_KEY since early on; this third one, added later just to report a version number, was missed. shape is specifically the command meant to be safe to paste into a bug report.

Promoted layout._child_env to a public child_env() — it now has two production callers in two modules, so it's a shared primitive rather than one module's private detail. Added a regression test that runs a stand-in dot and confirms an exported key never reaches it; confirmed it fails red against the pre-fix code before applying the fix.

Fixed — Low: malformed-MAC parsing (diagnostics.py)
The KAN-129 randomised-MAC detector parsed only the substring before a MAC's first colon, so a malformed id like "2" read as hex 0x02 and came back locally-administered by accident. Now requires the full six-octet shape before checking the bit — relevant because Node.id isn't trusted input, and a support file's fields are attacker-controlled by this project's own threat model.

Not changed — Medium: release-provenance timing
The review noted the provenance workflow attests artifacts already built locally rather than building from the tagged source in CI. Correct, but already explicitly documented as a deliberate trade-off (RELEASING.md keeps the build local and manual on purpose; the workflow itself says it runs "after the fact"). No code or doc defect, so no change.

Also tightened a SECURITY.md claim the same review flagged as overclaiming: resolving Graphviz to an absolute path once guards against a substitution after resolution, not against PATH itself.

Test plan

  • New regression test confirmed red against the pre-fix code, then green after the fix
  • make check (ruff format/lint + 694 tests) passes clean
  • make docs produces no further changes
  • Reviewed on validate before this PR

🤖 Generated with Claude Code

External review of ccd1113 found unifi-map shape's Graphviz-version
probe (_graphviz_version, called from cmd_shape) ran `dot -V` with the
plain inherited environment rather than layout.py's scrubbed one. The
two Graphviz child processes used to actually render a map have
stripped an exported UNIFI_API_KEY since early on; this third one,
added later just to report a version number, was missed -- the same
"fixed the instance, not the class" failure this repo has hit before.
shape is specifically the command meant to be safe to paste into a bug
report.

Promoted layout._child_env to a public child_env(): it now has two
production callers in two modules, which makes it a shared primitive
rather than one module's private detail (same reasoning that moved the
capped-read helper into httpio.py). Added a regression test that runs
a stand-in `dot` and confirms an exported key never reaches it,
red-tested against the pre-fix code before applying the fix.

Also fixed a second, lower-severity finding from the same review: the
randomised-MAC detector added for KAN-129 parsed only the substring
before a MAC's first colon, so a malformed id like "2" read as hex
0x02 and came back locally-administered by accident. Now requires the
full six-octet shape before checking the bit -- relevant because
Node.id is not trusted input, and a support file's fields are
attacker-controlled by this project's own threat model.

Tightened a SECURITY.md claim the same review flagged as overclaiming:
resolving Graphviz to an absolute path once guards against a
substitution *after* resolution, not against PATH itself.

Updates AI_DISCLOSURE.md's test count (686 -> 694), caught by its own
guard test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants