Security
Security is one of Ultimo's two core pillars (with performance). The framework
is secure by default, follows defense in depth, and aims to be
provable (audited, no unsafe, public disclosure policy).
100% Safe Rust
The framework enforces #![forbid(unsafe_code)] — there is zero unsafe in
Ultimo. Combined with Rust's guarantees, that rules out memory-safety bugs
(buffer overflows, use-after-free, data races) in the framework itself.
Security headers
Add secure-by-default response headers with one line:
use ultimo::middleware::builtin::security_headers;
app.use_middleware(security_headers());Sets HSTS, X-Content-Type-Options: nosniff, X-Frame-Options: DENY,
Referrer-Policy, and a restrictive Permissions-Policy. Content-Security-Policy
is opt-in (a wrong CSP breaks more than it protects). Headers are applied only if
the handler didn't already set them, so per-route overrides win. Customize:
use ultimo::middleware::builtin::SecurityHeaders;
app.use_middleware(
SecurityHeaders::new()
.csp("default-src 'self'")
.frame_options("SAMEORIGIN")
.build(),
);Request body-size limit
Cap request bodies to reject oversized payloads (DoS protection) with 413:
app.max_body_size(2 * 1024 * 1024); // 2 MBOn the live server an oversized body is never fully buffered. No limit by default — set one in production.
Client IP & trusted proxies
let ip = ctx.client_ip(); // Option<IpAddr> — best-effort originating client
let peer = ctx.peer_addr(); // Option<SocketAddr> — direct connection peerBy default client_ip() returns the connection peer. Behind a trusted
proxy/load balancer, enable header trust so it honors X-Forwarded-For (leftmost)
then Forwarded: for=:
app.trust_proxy(true); // ONLY behind a trusted proxySessions & cookies
Cookie-based sessions are secure by default (HttpOnly, Secure, SameSite, 256-bit ids, anti session-fixation, server-side storage). See Sessions.
CSRF protection
The csrf feature provides double-submit cookie CSRF protection. The
middleware issues a random token in a (non-HttpOnly) cookie; on unsafe methods
(POST/PUT/PATCH/DELETE) the request must echo that token in a header, and the two
are compared in constant time (mismatch → 403). Safe methods are exempt.
// Cargo.toml: ultimo = { version = "0.3", features = ["csrf"] }
app.use_middleware(ultimo::csrf::csrf());
// or customized:
app.use_middleware(
ultimo::csrf::Csrf::new()
.header_name("x-csrf-token")
.same_site(ultimo::cookie::SameSite::Strict)
.build(),
);The frontend reads the csrf_token cookie and sends it back as the
x-csrf-token header:
const token = document.cookie.split('; ')
.find((c) => c.startsWith('csrf_token='))?.split('=')[1];
await fetch('/api/action', { method: 'POST', headers: { 'x-csrf-token': token } });See the session-auth example
for a working login flow with CSRF.
Supply chain
cargo audit(RUSTSEC advisories) runs in CI on every PR.cargo denygates advisories, banned/duplicate deps, and source pinning.Cargo.lockis committed for reproducible builds.cargo-semver-checksguards the public API against accidental breakage.- Minimal dependency surface (the WebSocket layer is zero-dependency).
Defense in depth
For production, deploy Ultimo behind a managed WAF/CDN (Cloudflare, AWS WAF, …) for full WAF rules, DDoS mitigation, and geo controls. Ultimo provides the in-app building blocks; the edge handles volumetric and signature-based threats.
Reporting a vulnerability
Please report privately — see SECURITY.md (GitHub Security Advisories). Do not open a public issue for vulnerabilities.
Roadmap
Planned for v0.4.0: auth middleware (JWT / API keys), authorization guards, IP allow/deny, request guards, and geo-blocking hooks. See the roadmap.