Docs
Cross-origin and CSRF
Reject forged cross-origin writes, and add the CSRF defense Proa does not.
FrameworkBuilder::build() rejects browser-issued unsafe cross-origin requests, POST, PUT, PATCH, DELETE, before they reach a handler. They return 403.
Safe methods pass. Non-browser clients pass. You do not turn this on.
let app = FrameworkBuilder::new(manifest)
.with_trusted_origin("https://admin.example.com")
.build();
Add a trusted origin when a browser on another origin legitimately needs to write to your app.
What else is on by default
The same outer hardening applies to pages and endpoints alike:
| Default | Effect |
|---|---|
| Cross-origin protection | Browser-issued cross-origin unsafe requests return 403 unless trusted |
| Body limit | Requests capped at 1 MiB unless overridden |
| Request timeout | Handlers must respond within 30 seconds by default |
| Security headers | Framework responses get baseline hardening headers |
Raise the body limit deliberately, per route, when a handler accepts file uploads. A global raise removes the protection everywhere.
This is not a CSRF-token service
The distinction matters and it is easy to miss.
Cross-origin protection rejects a request based on its shape, the method and the originating origin. A CSRF token proves the request came from a form your app rendered, to a user you authenticated.
| Attack | Blocked by origin checks? |
|---|---|
A form on evil.example POSTs to your app | Yes |
A fetch() from another origin issues a DELETE | Yes |
| A replayed request with a stolen session cookie | No |
| A forged request from a same-origin XSS foothold | No |
If you migrated from Rails or Django, this is the gap where csrf_meta_tags and {% csrf_token %} used to sit. Proa does not issue or validate tokens. Configure that in Axum middleware, and keep the token check on every unsafe browser-issued method.
For browser-facing mutations, keep using same-origin forms or same-origin fetch. For cross-origin API clients, configure trusted origins deliberately, or mount a separately configured Axum router outside the framework builder.
Good to know: Disable the layer only for a router that implements an equivalent defense. Turning it off to fix a
403during development usually means an origin needs adding, not that the layer is wrong.
Next steps
- Security
- What Proa hardens by default, and what stays your job.
- Headers and CSP
- Set frame policy, HSTS, and a nonce-based Content Security Policy.
- Forms and actions
- Build HTML forms, handle submissions with Axum, and attach typed actions.
- Route handlers
- Build JSON, form, and webhook endpoints with Route::endpoint.
- From Rails
- Migrate from Rails ERB templates to Proa, run Proa as a rendering service alongside your Rails app.