Skip to content

feat(code-scanner): add the config subsystem (PRD 0005) - #54

Merged
ralyodio merged 1 commit into
masterfrom
feat/code-scanner-config
Jul 28, 2026
Merged

feat(code-scanner): add the config subsystem (PRD 0005)#54
ralyodio merged 1 commit into
masterfrom
feat/code-scanner-config

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Implements PRD 0005 — the config/ subsystem, completing the four subsystems PRD.md scopes to code-scanner.

Subsystem PRD Status
deps/ 0002
secrets/ 0003
sast/ 0004
config/ 0005 ✅ this PR

Why this one has the highest yield

The other three each have a CI counterpart doing overlapping work — Dependabot, gitleaks, CodeQL. Configuration has none, because a docker-compose.yml in a repository says what someone intended. The file on the box, plus what is actually served, plus the directory permissions, say what is true. Only an agent on the host sees the second.

And for the users this product targets, configuration is what actually gets them breached: a .env served by a web root, a reachable .git, debug mode left on, a mounted Docker socket. No exploit required — just a default nobody changed.

Two rules shape the output

Rank by reachability, not benchmark severity. An exposed medium outranks a local critical, because reachability is what sets the deadline. A tool that scores both identically makes the operator do the triage the tool should have done.

Every finding carries a fix, including the follow-through. Moving an exposed .env is not remediation — the credentials must be rotated, because it should be assumed read. Operators routinely do the first half and stop, so the text says both. A test asserts every finding has a remediation and a consequence; a rule added without them is the start of the compliance-checklist failure mode this PRD exists to avoid.

Honest about the weak link

Every exposure check depends on knowing what the webserver serves, and real nginx configs use includes, variables and per-vhost roots. When inference fails, the scan sets webRootUnknown and marks the whole result incomplete rather than reporting clean — silence there means "did not look", not "nothing exposed". Same honesty rule as PRD 0002 R6. The web root's provenance (configured / parsed / conventional) is reported with the finding, so a conventional guess isn't presented with the confidence of a parsed directive.

Not a compliance tool

Stated plainly in the PRD and the docs: this is a short, defensible check set, not CIS/STIG. A clean result is not certification, and compliance-reporter remains a separate marketplace module in PRD.md.

Verification

112 tests (22 new), build clean.

Implements PRD 0005, completing the four subsystems PRD.md scopes to
code-scanner.

This is the subsystem with the least CI overlap and, for small-team servers,
probably the highest yield. Dependabot, gitleaks and CodeQL each cover part of
the other three; configuration has no equivalent, because a docker-compose.yml
in a repository says what someone INTENDED while the file on the box — plus
what is actually served, plus the directory permissions — says what is TRUE.
Only an agent on the host sees the second.

Checks, all traceable to how servers actually get breached: sensitive files
inside a served directory (.env, .git, dumps, backups, compose files),
directory listing, wildcard CORS combined with credentials, debug flags in
production, world-writable deploy directories, world-readable credential
files, privileged containers, mounted Docker sockets, host networking,
CAP_SYS_ADMIN.

Two rules shape the output:

  - Rank by REACHABILITY, not benchmark severity. An exposed medium outranks a
    local critical, because reachability is what sets the deadline. A tool that
    scores both the same makes the operator do the triage the tool should have
    done.
  - Every finding carries a fix INCLUDING the follow-through. Moving an exposed
    .env is not remediation; the credentials must be rotated because it should
    be assumed read. Operators routinely do the first half and stop, so the
    text says both. A test asserts every finding has a remediation and a
    consequence — a rule added without them is the start of the
    compliance-checklist failure mode this PRD exists to avoid.

Web-root inference is the weakest link and is treated as such: when it cannot
determine what is served, the scan reports webRootUnknown and marks the result
incomplete rather than reporting clean. Silence there means "did not look",
not "nothing exposed" — the same honesty rule as PRD 0002 R6.

112 tests (22 new).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

const trimmed = line.trim();
if (trimmed.startsWith('#')) continue;

const nginx = /^root\s+([^;]+);/.exec(trimmed);
const nginx = /^root\s+([^;]+);/.exec(trimmed);
if (nginx?.[1]) roots.add(nginx[1].trim().replace(/^["']|["']$/g, ''));

const apache = /^DocumentRoot\s+(.+)$/i.exec(trimmed);
.filter((line) => !line.trim().startsWith('#'))
.join('\n');

if (/autoindex\s+on|Options\s+[^\n]*\+Indexes/i.test(body)) {

// Individually defensible, together a vulnerability: a wildcard origin with
// credentials allows any site to make authenticated requests as the user.
const wildcardOrigin = /Access-Control-Allow-Origin[^\n]*\*/i.test(body);
// Individually defensible, together a vulnerability: a wildcard origin with
// credentials allows any site to make authenticated requests as the user.
const wildcardOrigin = /Access-Control-Allow-Origin[^\n]*\*/i.test(body);
const allowCredentials = /Access-Control-Allow-Credentials[^\n]*true/i.test(body);
@ralyodio
ralyodio merged commit 8f124a7 into master Jul 28, 2026
8 of 9 checks passed
@ralyodio
ralyodio deleted the feat/code-scanner-config branch July 28, 2026 17:34
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