docs(web/guides): correct reload-password behavior claims in security-hardening guide - #3064
Conversation
…-hardening guide Audit-verified corrections against current develop: - empty reloadPassword does NOT disable plain ?reload=true (refs #3062) - wrong password is served normally (200), not 403 - reload logging/rate-limit only fires on cold start; refresh stale line cites - CSRF helper line cites updated ($verifyAuthenticityToken 59, $isVerifiedRequest 78) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com>
There was a problem hiding this comment.
Wheels Bot — Reviewer
TL;DR: This PR corrects four false or stale claims about the reload-password contract in the security-hardening guide (empty password ≠ disabled reload, no 403 on wrong password, cold-start-only logging/rate-limiting, refreshed CSRF line cites), tracking the framework-side drift in #3062. I re-verified every line citation in the diff against current source and all of them are accurate; the behavioral claims match the gate code in public/Application.cfc and vendor/wheels/events/onapplicationstart.cfc. Verdict: comment — one minor residual docs nit below, nothing blocking.
Verified
public/Application.cfc:268-288— warm-reload gate fires on!Len(application.wheels.reloadPassword)(line 273), so empty password leaves plain?reload=trueopen; a set-but-wrong password fails the condition and falls through to normal serving (no 403). Matches the new lines 155 and 170 of the guide.vendor/wheels/events/onapplicationstart.cfc:188— env-switch leg requiresLen(application.$wheels.reloadPassword); rate limit at 160-178 (5 failures / 5 min); rejected log at 219; accepted log at 227; boot warning at 371-374. All cited line numbers in the new text are correct, and the cold-start-only scoping caveat is accurate (the whole block lives inonapplicationstart).vendor/wheels/controller/csrf.cfc—$runCsrfProtection37,$verifyAuthenticityToken59,$isVerifiedRequest78 ✓.vendor/wheels/view/csrf.cfc—csrfMetaTags10,authenticityTokenField26 ✓.vendor/wheels/events/init/security.cfm:3(csrfStore = "session") ✓.- "the only
403s on this surface live on the CLI command gate invendor/wheels/Public.cfc" — confirmed atPublic.cfc:90/95/106/111; no other 403 on the reload path. - Commit
b401edbfconforms to commitlint (87-chardocs(web/guides)header) and carries a matching DCO sign-off. No changelog fragment required fordocstype.
Docs
security-hardening.mdx:157— "accepted attempts log … (lines 219 and 227)" is slightly overgeneral. Line 227's "Reload accepted" log only fires whenreloadPasswordMatchedis true, and that flag is set exclusively inside the environment-switch branch (!IsBoolean(URL.reload),onapplicationstart.cfc:185-192). A correct-password plain?reload=truethat happens to arrive during a cold start instead satisfies the failed-attempt tracker at lines 208-222 (both URL keys present,reloadPasswordMatchedfalse) — it logs "Reload password rejected" and increments the per-IP rate-limit counter. So on the only path where this logging runs at all, the "accepted" log covers environment switches only, and plain reloads can be mislabeled as rejected. Suggested tweak: scope the sentence, e.g. "rejected attempts log at line 219; accepted environment switches at line 227". The mislabeled rejected-log/rate-limit bump for correct-password boolean reloads is itself framework-bug material worth appending to #3062, since fixing it would change what the guide should say here.
Nice work overall — this is exactly the kind of live-verified docs correction the audit is for, and pointing the prose at #3062 instead of papering over the gate's behavior is the right call.
Guide behavioral audit follow-up for
web/sites/guides/src/content/docs/v4-0-0/deployment/security-hardening.mdx. Each correction was live-verified against current develop (post #3036/#3037/#3038/#3057/#3058) and re-cited against today's source.Corrections
"If it's empty, both are disabled" — false. With
set(reloadPassword=""), plain?reload=truefrom any anonymous client still firesapplicationStop()— the warm-reload gate inpublic/Application.cfclines 268-288 explicitly passes when the password has no length; only the environment-switch leg (vendor/wheels/events/onapplicationstart.cfcline 188) requires a non-empty password. The guide now states that empty disables URL environment switching only, that plain reload stays open, and links the tracking issue Reload-password contract drift: empty password leaves?reload=trueopen to anonymous restarts, warm-app wrong-password attempts are never logged or rate-limited, and the boot warning misstates behavior #3062 (the boot warning atonapplicationstart.cfc371-374 repeats the same false "disabled" claim)."those URLs return 403 unless the attacker also knows the secret" — false. A missing/wrong password is served normally (HTTP 200, no reload, no 403) — the gate in
public/Application.cfclines 268-288 simply falls through to normal request serving. The only 403s on this surface are the CLI command gate invendor/wheels/Public.cfclines 90-111. Sentence replaced accordingly.Logging/rate-limit claim overstated + stale line cites. Rejected attempts log at
vendor/wheels/events/onapplicationstart.cfcline 219, accepted at line 227, IP rate-limit (5 failures / 5 min) at lines 160-178 — the guide cited 189/197/135. More importantly, that code only runs on application cold start: a wrong-password?reload=trueagainst a warm app produces nowheels_security.logentry and no rate-limit count. The guide now scopes the claim and updates the cites. Boot-warning cite updated 287-290 → 371-374.CSRF line cites refreshed.
$verifyAuthenticityToken()is atvendor/wheels/controller/csrf.cfcline 59 (guide said 63);$isVerifiedRequest()at line 78 (guide said 82).$runCsrfProtection()line 37 and the view-helper cites (csrfMetaTags10,authenticityTokenField26) were verified still correct and left unchanged.No change needed for
?reload=productionswitching itself: #3058 (merged today) fixed the$locationcrash, so switching into production/maintenance now sticks.Verification
pnpm verify:docs src/content/docs/v4-0-0/deployment/security-hardening.mdx→ 11 tagged blocks, 11 passed, exit 0.Refs #3062
🤖 Generated with Claude Code