Skip to content

Quality hardening (adversarial review) + BIG-IP/NGINX docs & screenshots - #57

Merged
henleda merged 3 commits into
mainfrom
fix-nginx-review-hardening-and-docs
Aug 18, 2026
Merged

Quality hardening (adversarial review) + BIG-IP/NGINX docs & screenshots#57
henleda merged 3 commits into
mainfrom
fix-nginx-review-hardening-and-docs

Conversation

@henleda

@henleda henleda commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Three things you asked for: a quality deep-dive on the new virtual-patch code, refreshed docs for the BIG-IP + NGINX functionality, and product screenshots taken against the live appliances.

1. Quality deep-dive (adversarial review → fixes)

Ran a multi-agent bug-hunt over the NGINX App Protect variant + the Task A report/console generalization; verified the findings against the code and fixed the real ones, each with a regression test (+17 tests):

Security

  • Path traversal via finding_id — it lands in on-box file paths and reaches the transport from the console /api/apply-nginx body, so x/../../../etc/nginx/nginx could sudo-write/delete arbitrary root files. Now validated at apply/retire + a ..-guard in the client; remove_dir refuses a non-vpcopilot- dir.
  • Config injection via origin/location — interpolated raw into the vhost; a value with ;{} could inject a second server block. Now validated.
  • DOM XSSesc() didn't escape quotes; a crafted finding id in a value="…" attribute could inject a handler. Fixed.
  • SSH host-key verification was hardcoded off (MITM could forge a "blocked" verdict). Now TOFU (accept-new) by default, NGINX_SSH_STRICT overridable.

Safety / correctness

  • An exception after the real apply left an enforcing, un-ledgered band-aid (retire/reconcile could never find it) — now detaches + reloads before re-raising.
  • nginx_lab.remove ran rm -f on a directory (rc=1 → reload/audit skipped) — uses a new rm -rf.
  • create dry-run deleted an existing live vhost — now preserves it.
  • The vhost hardcoded /etc/nginx/conf.d, so a custom NGINX_INCLUDE_DIR silently never enforced — now uses the real dir.
  • get_config masked a failed nginx -T as empty; _await_enforcement re-hammered a failing login; a corrupt spec aborted a valid apply — all fixed.

Every fix re-verified live on the box (status + apply-nginx still block, with the hardened transport). Full suite 1178 pass, ruff clean.

2. Docs — the hybrid fabric

The same band-aid, three enforcement points (XC · BIG-IP Advanced WAF · F5 WAF for NGINX). README reframed; docs/BIGIP.md de-staled (3 forms live, console panel shipped); new docs/NGINX.md (NGINX-admin guide mirroring BIGIP.md); docs/TRY_IT.md gains a NGINX section.

3. Screenshots (live)

Captured against both live appliances (BIG-IP AS3 3.56.0, NGINX Plus R37 + App Protect): the ④ Mitigate panels reporting ready with emitter-driven dropdowns + honest declines, and the report's BIG-IP + NGINX sections. Wired into the README and admin guides.

🤖 Generated with Claude Code

Daniel Henley and others added 3 commits August 18, 2026 13:15
…rial review

A multi-agent bug-hunt of the new code surfaced real impacting defects; fixed with
regression tests (+17):

SECURITY
- Path traversal via finding_id: it lands in on-box file paths and reaches the
  transport from the console /api/apply-nginx body, so a value like
  'x/../../../etc/nginx/nginx' could sudo-write/delete arbitrary root files. Now
  validated (^[A-Za-z0-9_.][A-Za-z0-9_.-]*$) at apply/retire + backstopped by a
  '..'-segment guard in the Nginx client; remove_dir also refuses a non-vpcopilot dir.
- Config injection via origin/location: interpolated raw into the vhost, a value
  with ';{}' could inject a second server block. Now validated (host:port / path).
- DOM XSS: esc() didn't escape quotes; a crafted finding id in a value="..." attr
  could inject a handler in the operator console. esc() now escapes " and '.
- SSH host-key verification was hardcoded off (MITM on the policy-push/root channel
  could forge a 'blocked' verdict). Now TOFU (accept-new) by default, NGINX_SSH_STRICT
  overridable, /dev/null only in explicit 'no' mode.

SAFETY / CORRECTNESS
- An exception after the real apply (a step-3 nginx -t the operator's config now
  rejects, a transient validation/reload error) left an enforcing, un-ledgered
  band-aid (retire/reconcile could never find it) or a config-poisoning include.
  The real-apply body now detaches + reloads before re-raising.
- nginx_lab.remove ran `rm -f` on the managed DIRECTORY (rc=1) → reload+audit never
  ran and the vhost stayed loaded. Uses a new rm -rf remove_dir.
- create dry-run overwrote-then-DELETED an existing live vhost; now preserves/restores
  it (new read_file).
- The vhost hardcoded /etc/nginx/conf.d, so band-aids on a custom NGINX_INCLUDE_DIR
  silently never enforced. The include path now uses the real include_dir.
- get_config swallowed a failed `nginx -T` as an empty config; now raises.
- _await_enforcement re-hammered a failing login for the whole window; now short-
  circuits on auth_failed/no_probe/unobservable-leak. A corrupt spec no longer aborts
  a valid apply. status() computes version() inside the try. default_server is opt-in.

Full suite 1178 pass, ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…NGINX.md, TRY_IT.md

The same declarative band-aid now emits + applies for three enforcement points
(XC, BIG-IP Advanced WAF, F5 WAF for NGINX / App Protect). Docs updated to match:

- README: a "one finding, every enforcement point" section (all three forms proven
  on live BIG-IP + NGINX+App-Protect); the ④ Mitigate note now names the "Apply on
  your own BIG-IP / NGINX" panels; docs/NGINX.md added to the table.
- BIGIP.md: "what it can patch" de-staled — service_policy + waf_data_guard +
  api_schema all live-proven (waf honestly declined for signature staging); the
  console ④ Mitigate panel is shipped, not "coming next".
- NGINX.md (new): the NGINX-admin guide mirroring BIGIP.md — SSH connect, nginx-lab
  create, apply/retire, the guard, troubleshooting, the three forms.
- TRY_IT.md: an "Or: mitigate on your own NGINX (App Protect)" section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rt, live

Captured against both live appliances (BIG-IP AS3 3.56.0, NGINX Plus R37 + App
Protect) via the console on the demo dataset:

- 4-mitigate.png (updated): the ④ Mitigate step now shows the XC table PLUS the
  "Apply on your own BIG-IP" and "Apply on your own NGINX" panels, both reporting
  ready, with emitter-driven finding dropdowns and the honest declines.
- apply-your-own-waf.png (new): a focused shot of both apply panels — used in the
  README hybrid-fabric section and both admin guides.
- report-bigip-nginx.png (new): the report's BIG-IP Advanced WAF + F5 WAF for NGINX
  sections — same finding, form emitted, honest declines.

README / BIGIP.md / NGINX.md reference them; the demo report is regenerated with the
NGINX section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@henleda
henleda merged commit c8d575f into main Aug 18, 2026
4 checks passed
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.

1 participant