79 lines
5.9 KiB
Markdown
79 lines
5.9 KiB
Markdown
# Limited administration exposure audit - 0.7.1
|
|
|
|
## Scope and evidence
|
|
|
|
Reviewed the supplied 0.7.0 source and this patch's admin router/middleware,
|
|
authentication endpoints, sessions, API assets, dashboard login/logout, Swagger
|
|
integration, proxy header rule precedence and deployment readiness consumer.
|
|
This is a manual source review plus static/browser-script regression tests. It
|
|
is **not** a penetration test of the user's installed binary or a complete audit
|
|
of proxy/TLS/QUIC/ACME/operating-system/dependency security. No Rust compiler was
|
|
available; runtime enforcement and complete vendor rendering remain unverified.
|
|
|
|
The reported unauthenticated operational JSON disclosure was not reproduced on
|
|
an installed server. In the input source, `/api/config`, status, logs, metrics,
|
|
backend/cache and certificate endpoints already passed through a session guard.
|
|
The concrete findings were public version/mode metadata, unnecessarily public
|
|
operational HTML/JS/full language assets, broad path-only method exceptions and
|
|
incomplete browser-state minimization. Do not infer that a user's older build,
|
|
reverse-proxy front or a different exposed endpoint had the same behavior.
|
|
|
|
## Findings and source changes
|
|
|
|
| Observation | 0.7.1 change | Verification limit |
|
|
|---|---|---|
|
|
| `/healthz` disclosed version; auth discovery disclosed version/mode/password policy | Health reduced to one status field; auth discovery to setup-required boolean | Source/contract tests; actual router tests supplied, not run |
|
|
| Full operational HTML/modules/language bundle could be fetched anonymously | Root selects minimal login or authenticated document; full modules/bundle are private | Login fetch/DOM checks use mocked fetch, not real HTTP |
|
|
| Public route exemptions were not a strict method/path matrix | Explicit allowlist; private and unknown requests denied before JSON/query parsing | Six additional async Rust test functions supplied, unexecuted |
|
|
| Anonymous JSON rejection could include extractor input detail | Login/setup map parser failures to a fixed message, preserving 400/413/415 status semantics | Source and unexecuted router tests |
|
|
| Mutation marker/CSRF duplicate values were not explicitly rejected | Require one exact Origin, marker and session-bound CSRF value | Existing guards retained; added unexecuted duplicate-header tests |
|
|
| Stale DOM/form values can outlive a visible logout screen | Scrub inputs/state, notify other tabs, reload root; docs clear schema/results on session change | Chromium script tests with simulated location/storage |
|
|
| New API docs would otherwise create another disclosure surface | Protect document, schema and every necessary asset with existing guard; no wildcard asset route | Route/schema contracts; vendor-renderer acceptance outstanding |
|
|
| Interactive docs can carry credentials into requests | Fixed same-origin schema, per-action session verification, no external validator/persisted auth, writes opt-in + CSRF | Custom interceptor tests use a vendor stub; server guard is the authority |
|
|
| Updater used public version in `/healthz` | Locally verify systemd MainPID executable against staged release after minimal readiness | Temporary-file and simulated-systemd tests; real deployment not run |
|
|
|
|
## Deliberate public minimum
|
|
|
|
Anonymous login assets, favicon/shared CSS, setup-needed boolean, minimal health
|
|
status, and guarded login/one-time setup POSTs remain. These are necessary for
|
|
sign-in, initial administration and local readiness. Static CSS may contain UI
|
|
selectors; it contains no runtime configuration or secrets. Invalid Host/Origin
|
|
still returns generic 403 instead of bypassing the boundary.
|
|
|
|
Login/setup POST success is allowed to create/return session information **only
|
|
after credential/capability validation**. No API Bearer token or setup token was
|
|
added as an alternative authority for operational reads. Setup remains one-time,
|
|
local-capability-based; password checking/rate limiting/session invalidation were
|
|
not weakened or replaced by JavaScript-only checks.
|
|
|
|
## Separate Prometheus listener
|
|
|
|
Admin `/metrics` and `/api/metrics` require the browser/admin session. The optional
|
|
standalone Prometheus listener remains independent, disabled by default, with
|
|
configured source CIDRs and its existing bearer-token policy. Non-loopback export
|
|
requires a token by the existing Rust validation. A loopback exporter can be
|
|
intentionally configured without a browser login. Do not treat it as an overlooked
|
|
admin API exception, and do not place it on an untrusted network without reviewing
|
|
its token, CIDRs and protected transport. This patch does not verify its runtime.
|
|
|
|
## Outstanding acceptance and operational caveats
|
|
|
|
- Build and execute `dev.sh check` / `dev.sh test`; run `admin_audit.py` against
|
|
the actual upgraded service. Compare 401/no-store responses without cookies.
|
|
- Open real `/docs` in a normal browser; verify rendering, actual cookie+Origin+CSRF,
|
|
logout, CSP console output and failure after revocation. Vendor assets were not
|
|
downloaded/rendered here, and build dependency compatibility is unverified.
|
|
- Test real install/update restart/rollback; local MainPID and `/proc` verification
|
|
now fail closed when the expected executable cannot be established.
|
|
- Retain loopback-only administration and use a protected tunnel. Cookie/session
|
|
security does not protect a compromised local account, malicious browser extension,
|
|
an administrator sharing exported configuration, or every possible web attack.
|
|
- No RBAC/read-only administrator role, general API token scopes, dependency CVE
|
|
scan, fuzzing or proof of vulnerability absence is delivered by this small patch.
|
|
- Review a real resolved Cargo.lock and the pinned Swagger artifact before shipping
|
|
binaries. Source review is not a substitute for release acceptance.
|
|
|
|
For the exact exposure matrix and test/build commands, read [API_ACCESS.md](API_ACCESS.md).
|
|
The review uses OWASP REST/session guidance as a checklist, not a certification:
|
|
https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
|