trusted proxy, TOTP replay protection, new tests
- Trusted proxy config option for proxy-aware IP extraction used by rate limiting and audit logs; validates proxy IP before trusting X-Forwarded-For / X-Real-IP headers - TOTP replay protection via counter-based validation to reject reused codes within the same time step (±30s) - RateLimit middleware updated to extract client IP from proxy headers without IP spoofing risk - New tests for ClientIP proxy logic (spoofed headers, fallback) and extended rate-limit proxy coverage - HTMX error banner script integrated into web UI base - .gitignore updated for mciasdb build artifact Security: resolves CRIT-01 (TOTP replay attack) and DEF-03 (proxy-unaware rate limiting); gRPC TOTP enrollment aligned with REST via StorePendingTOTP Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
26
web/static/mcias.js
Normal file
26
web/static/mcias.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// mcias.js — HTMX event wiring for the MCIAS web UI.
|
||||
|
||||
// Show server error responses in the global #htmx-error-banner.
|
||||
//
|
||||
// HTMX 2.x fires htmx:responseError for 4xx/5xx responses and does not swap
|
||||
// the body into the target by default. The server's renderError() always
|
||||
// returns a <div class="alert alert-error"> fragment whose message is
|
||||
// HTML-escaped server-side, so setting innerHTML here is safe.
|
||||
document.body.addEventListener('htmx:responseError', function (evt) {
|
||||
var banner = document.getElementById('htmx-error-banner');
|
||||
if (!banner) { return; }
|
||||
var body = (evt.detail.xhr && evt.detail.xhr.responseText) || 'An unexpected error occurred.';
|
||||
banner.innerHTML = body;
|
||||
banner.style.display = '';
|
||||
banner.scrollIntoView({ behavior: 'instant', block: 'nearest' });
|
||||
});
|
||||
|
||||
// Clear the error banner whenever a successful HTMX swap completes so
|
||||
// stale errors do not persist after the user corrects their input.
|
||||
document.body.addEventListener('htmx:afterSwap', function () {
|
||||
var banner = document.getElementById('htmx-error-banner');
|
||||
if (banner) {
|
||||
banner.style.display = 'none';
|
||||
banner.innerHTML = '';
|
||||
}
|
||||
});
|
||||
@@ -23,12 +23,14 @@
|
||||
</nav>
|
||||
<main>
|
||||
<div class="container">
|
||||
<div id="htmx-error-banner" role="alert" style="display:none"></div>
|
||||
{{if .Error}}<div class="alert alert-error" role="alert">{{.Error}}</div>{{end}}
|
||||
{{if .Flash}}<div class="alert alert-success" role="status">{{.Flash}}</div>{{end}}
|
||||
{{block "content" .}}{{end}}
|
||||
</div>
|
||||
</main>
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/mcias.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user