salvo-csrf
CSRF support for salvo web server framework.
0.95.2
4.7M downloads/mo
#4647 most downloaded on crates.io
salvo-rs/salvo
What this package is like to depend on
Last release 18 days ago
06 Aug 2026
Release timing varies
gaps range from 8 days to 2 months
Rarely documented
notes for 10 of 125 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
125 releases · first in 2022
25 releases in the last 12 months
see the full history below
Release timeline
125 releases · Sep 2022 to Aug 2026Releases
latest 60 of 125-
0.95.206 Aug 2026Release notes
Open source →What's Changed
- Add baseline OpenAPI 3.2 support by @chrislearn in #1686
- Add QUERY method routing support by @chrislearn in #1687
Full Changelog: v0.95.1...v0.95.2
-
0.95.129 Jul 2026Release notes
Open source →What's Changed
- build(deps): update ulid requirement from 2 to 3 by @dependabot[bot] in #1675
- build(deps): update base64 requirement from 0.22 to 0.23 by @dependabot[bot] in #1677
- Document JWT crypto provider features by @chrislearn in #1679
- build(deps): update jsonwebtoken requirement from 10 to 11 by @dependabot[bot] in #1678
- build(deps): update serial_test requirement from 3 to 4 by @dependabot[bot] in #1680
- build(deps): update syn requirement from 2 to 3 by @dependabot[bot] in #1676
- chore(oapi): update Swagger UI to v5.32.11 by @chrislearn in #1681
- Document core HTTP types and validate ranges by @chrislearn in #1682
- Apply nightly rustfmt to HTTP docs by @chrislearn in #1683
Full Changelog: v0.95.0...v0.95.1
-
0.95.015 Jul 2026Release notes
Open source →What's Changed
- Add support for OsString and PathBuf by @eythaann in #1666
- Resolve duplicate Vary header and improve HEAD request preformance for
StaticDirby @cnlancehu in #1663 - Fix JWT crypto provider feature selection by @chrislearn in #1667
- build(deps): update tokio-tungstenite requirement from 0.29 to 0.30 by @dependabot[bot] in #1668
- build(deps): update compact_str requirement from 0.9 to 0.10 by @dependabot[bot] in #1670
- build(deps): update ulid requirement from 1 to 2 by @dependabot[bot] in #1669
- Fix WebTransport session handoff by @chrislearn in #1671
- Skip duplicate WebTransport response writes by @chrislearn in #1672
- build(deps): update saysion requirement from 0.1 to 0.2 by @dependabot[bot] in #1673
- chore(oapi): update Swagger UI to v5.32.8 by @chrislearn in #1674
New Contributors
Full Changelog: v0.94.0...v0.95.0
-
0.94.007 Jul 2026Release notes
Open source →v0.94.0
Salvo 0.94.0 focuses on security hardening, OpenAPI 3.1 correctness, lower runtime overhead in core routing/dispatch paths, and API naming cleanup. This release also raises the Rust MSRV to 1.94.
Highlights
- Rust MSRV is now
1.94. - Core routing and dispatch were reworked to reduce per-request allocations and improve path parameter rollback.
- Server lifecycle control is clearer, with
Server::max_connections,ConnCtrl, improved graceful/forceful shutdown behavior, and safer default connection fuse protection. - OpenAPI generation is closer to OpenAPI 3.1:
jsonSchemaDialect, webhooks, reusable components, PathItem refs, parameter content/examples/allowEmptyValue, and stricter required path parameters. - Security hardening landed across proxying, CORS, CSRF, static files, default error pages, JWT/OIDC, WebSocket upgrades, tus uploads, cookies, and ACME.
- Response rendering semantics are documented and tightened: text-like scribes append, while
Json<T>now replaces previously buffered body bytes because JSON is a complete document. salvo-tusexposes storage/locking types, addsTus::storage_root, and addsTus::absolute_locationfor safe absolute Location URLs.
Migration Guide
Rust
Update your toolchain to Rust 1.94 or newer.
rustup update stable
Core API naming
Several old names remain as deprecated aliases, but new code should use the clearer names:
Old New Depot::inject(value)Depot::insert_typed(value)Depot::obtain::<T>()Depot::get_typed::<T>()Depot::obtain_mut::<T>()Depot::get_typed_mut::<T>()Depot::contains::<T>()Depot::contains_typed::<T>()Depot::scrape::<T>()Depot::remove_typed::<T>()Depot::delete(key)Depot::remove(key).is_some()Response::stuff(status, value)Response::render_with_status(status, value)Server::stop_forcible()Server::stop_forceful()ServerHandle::stop_forcible()ServerHandle::stop_forceful()SchemeFilter::lack(...)SchemeFilter::fallback(...)HostFilter::lack(...)HostFilter::fallback(...)PortFilter::lack(...)PortFilter::fallback(...)StatusError::request_header_fields_toolarge()StatusError::request_header_fields_too_large()StatusError::unavailable_for_legalreasons()StatusError::unavailable_for_legal_reasons()AcmeListener::get_directory(...)AcmeListener::directory(...)Depotnow has separate named and type-keyed storage. Useinsert/get/removefor string keys andinsert_typed/get_typed/remove_typedfor type keys. Capacity andinner()refer to named storage.Response body rendering
Response::write_bodyappends to buffered bodies.Json<T>now replaces existing buffered bytes instead of appending, because concatenated JSON documents are invalid. If you intentionally emit NDJSON or another appendable format, serialize each record yourself and callwrite_body.salvo-tus builder methods
The tus builder API was aligned with Rust API naming guidelines. Update call sites:
Old New with_store(...)store(...)with_locker(...)locker(...)with_upload_id_naming_function(...)upload_id_naming_function(...)with_generate_url_function(...)generate_url_function(...)with_on_incoming_request(...)on_incoming_request(...)with_on_incoming_request_sync(...)on_incoming_request_sync(...)with_on_upload_create(...)on_upload_create(...)with_on_upload_finish(...)on_upload_finish(...)Also prefer
MaybeUploadIdover the deprecatedUploadIdalias.TusOptions::extract_file_id_from_requestreplaces the old file-id helper naming.For absolute tus
Locationheaders, prefer:let tus = Tus::new().absolute_location("https://uploads.example.com");
Avoid
relative_location(false)without a canonical origin on public services, because that derives absolute URLs from request host/forwarded headers.OpenAPI changes
- Top-level
$schemaoutput was corrected tojsonSchemaDialectfor OpenAPI 3.1. Parameter::parameter_in(...)is deprecated; useParameter::location(...).ToParametersnow defaults generated parameters to query location, so required query parameters are represented correctly.- Path parameters are now always serialized as
required: true. - Routes without an HTTP method filter are skipped during OpenAPI generation instead of being fanned out to every method.
#[derive(Extractible)]now rejects#[serde(flatten)]on fields. Use#[salvo(extract(flatten))]for Salvo request extraction flattening.
CORS, proxy, JWT/OIDC, and cookies
- CORS now rejects or strips unsafe combinations of
Access-Control-Allow-Credentials: truewith wildcard CORS response headers. Use explicit allowed origins, headers, and methods for credentialed APIs. ForwardedHeaderIssueris deprecated because it trusts client-controlled forwarded headers unconditionally. UseTrustedProxyIssuer::new([...])behind known proxies, orRemoteIpIssuerfor direct client IPs.Proxynow uses the standards-compliant host header getter by default, including non-default upstream ports. If you need the old bare-host behavior, configuredefault_host_header_getter.- OIDC JWKS symmetric keys (
kty: "oct"/ HS*) are rejected by default. Opt in withallow_symmetric_jwks(true)only for issuers that intentionally publish trusted symmetric keys. SecureCookiePolicyis available for CSRF, flash, and session cookies. If TLS terminates before Salvo and the request scheme appears as HTTP, force secure cookies with the relevantsecure_cookie(true)or policy API.
Notable Changes
Core and server
- Added
Server::max_connectionsto bound concurrent accepted connections. - Reworked connection protection, lifecycle control, and router matching for lower overhead and clearer shutdown behavior.
- Added
ConnCtrlto the prelude and public exports. - Improved routing parameter rollback, wildcard capture handling, host/port filtering for IPv6, and matched-path handling.
- Added response render API clarity and deprecated awkward or misleading names.
OpenAPI
- Completed several OpenAPI 3.1 reusable component types.
- Added top-level webhooks and PathItem
$refsupport. - Added Parameter Object
content,examples, andallowEmptyValue. - Fixed schema generation for inline generic schemas, request body refs, generic
Extractiblebounds, number equality, macro diagnostics, and several user-triggerable macro panics. - Added endpoint attribute aliases and accepted singular/plural parameter keys interchangeably.
Security hardening
- Escaped the default error page and Swagger UI/static directory generated output to reduce reflected XSS risk.
- Switched CSRF token verification to constant-time comparison.
- Hardened proxy path normalization, upgrade handling, host headers, body error propagation, and optional authorization forwarding.
- Added WebSocket Origin checking APIs to mitigate CSWSH on cookie-authenticated WebSocket endpoints.
- Hardened StaticDir root boundary checks and precompressed file handling.
- Tightened tus CORS handling, upload id validation, expiration handling, offset overflow checks, finalized-file protection, and absolute Location URL guidance.
- Bounded OIDC/JWKS fetch sizes and cache behavior, improved OIDC revalidation races, and avoided leaking sensitive panic/error payloads.
- Added safer secure-cookie policy handling for session, flash, and CSRF cookies.
Fixes
- Fixed
Set-Cookieparsing/round-tripping and tower-compatible response conversion. - Fixed cache behavior that could swallow requests or cache non-success responses.
- Fixed conditional request ordering, multi-range response handling, IPv6 authority parsing, ETag formatting, and range streaming.
- Fixed multipart parsing edge cases, missing boundary handling, file-part detection, temp-file cleanup, and panic paths.
- Fixed sliding-window rate limiting and normalized quota behavior.
- Fixed OIDC HTTP/2 negotiation and clock-skew panic paths.
- Fixed
RequestId, caching headers, basic auth multi-header fallthrough, and logging path/address behavior. - Fixed multiple tus protocol and storage edge cases.
Performance
- Reduced allocations in routing/path matching, WebSocket upgrade, proxy path encoding, JSON response rendering, CORS header joining, compression Accept-Encoding parsing,
Acceptparsing,text_nonce, andwrite_body. - Added a pass-through hasher for Depot type-keyed storage.
- Bounded cache in-flight miss coalescing and improved sliding-window rate limiter bookkeeping.
- Added criterion benchmarks for routing and dispatch hot paths.
Contributors
Thanks to everyone who contributed to this release:
- @chrislearn
- @cnlancehu — connection/lifecycle/router rework (#1622),
FlowCtrlperformance (#1608),auto_alt_svc_headerforquinn::Builder(#1585), code quality cleanups (#1544, #1524),salvo-corsrefactor (#1525), anddocs.rsbuild fixes (#1523) - @dashitongzhi — JWT audience claim handling docs (#1610)
- @dependabot — dependency updates (#1659, #1466)
- @Copilot — multipart file-part detection fix (#1486)
New Contributors
- @dashitongzhi made their first contribution in #1610
Full Changelog: v0.93.0...v0.94.0
- Rust MSRV is now
-
0.93.030 Apr 2026Release notes
Open source →What's Changed
- Add strict proxy path normalization by @chrislearn in #1434
- Enforce bcrypt CSRF token size floor by @chrislearn in #1436
- feat: implement atomic guard verification in MokaStore by @chrislearn in #1437
- Fix tus disk store path validation by @chrislearn in #1438
Full Changelog: v0.92.2...v0.93.0
-
0.92.224 Apr 2026Release notes
Open source →What's Changed
- Implement timeout management with Mutex and CancellationToken for FlexFusewire by @chrislearn in #1426
- Enhance cache middleware with concurrent miss coalescing by @chrislearn in #1427
- Refactor string handling for improved UTF-8 compatibility by @chrislearn in #1428
- fix: sanitize TUS filetype extensions by @chrislearn in #1429
- fix: honor TUS CORS options by @chrislearn in #1430
- fix: enforce TUS max size on streamed writes by @chrislearn in #1431
- fix: strip hop-by-hop proxy headers by @chrislearn in #1432
- fix: require OIDC issuer and audience validation by @chrislearn in #1433
Full Changelog: v0.92.1...v0.92.2
-
0.92.122 Apr 2026Release notes
Open source →What's Changed
- Add path filter handling for invalid patterns and try_with_path method by @chrislearn in #1422
- Add fuzzing targets and configuration for Salvo by @chrislearn in #1423
- refactor fuzz targets to use get method for payload extraction by @chrislearn in #1424
Full Changelog: v0.92.0...v0.92.1
-
0.92.017 Apr 2026Release notes
Open source →What's Changed
- feat(schema): implement ToSchema and ComposeSchema for serde_json::value::RawValue by @chrislearn in #1396
- Add configurable CSRF rotation policy by @chrislearn in #1399
- Harden crates release workflow by @chrislearn in #1400
- Add contributor guide by @chrislearn in #1401
- Expand security policy by @chrislearn in #1402
- Add changelog skeleton by @chrislearn in #1403
- fix: prevent panic on empty Range header in NamedFile and ReadSeeker by @iruizsalinas in #1405
- perf: reduce allocations during route matching by @iruizsalinas in #1406
- fix: clean up unused memory locker entries by @iruizsalinas in #1407
- Reload TLS configs in background by @chrislearn in #1404
- replace string clones with to_owned by @chrislearn in #1408
- swagger_ui v5.32.4 by @chrislearn in #1409
- Run cargo clippy for code linting by @chrislearn in #1410
- [codex] improve proxy host header copy by @chrislearn in #1416
- [codex] fix csrf session store missing session by @chrislearn in #1414
- [codex] improve writing string copy by @chrislearn in #1413
- [codex] fix request id invalid header by @chrislearn in #1411
- [codex] fix proxy native roots fallback by @chrislearn in #1415
- [codex] fix oidc custom client roots by @chrislearn in #1412
- Normalize error and log message style by @chrislearn in #1417
- Add targeted regression tests by @chrislearn in #1418
- Document message style and doctest checks by @chrislearn in #1420
- Improve documentation examples by @chrislearn in #1419
New Contributors
- @iruizsalinas made their first contribution in #1405
Full Changelog: v0.91.1...v0.92.0
-
0.91.103 Apr 2026Release notes
Open source →What's Changed
- Improve file handling and metadata retrieval in NamedFileBuilder by @chrislearn in #1378
- Optimize file handling and metadata retrieval for performance by @chrislearn in #1380
- feat: add WebSocket protocol selection by @18o in #1381
- perf(core): optimize allocations and minimize Arc clones in hot path by @chrislearn in #1382
- perf(core): cache SALVO_STATUS_ERROR env var parsing by @chrislearn in #1383
- perf(core): optimize encode_url_path and fix redirect panic by @chrislearn in #1384
- fix(core): strip response body for HEAD requests per RFC 9110 by @chrislearn in #1385
- perf(core): simplify Response::is_stamped with is_some_and by @chrislearn in #1386
- perf(core): avoid String allocation in is_windows_reserved_name by @chrislearn in #1387
- perf(core): use async metadata check in Response::send_file by @chrislearn in #1388
- perf(csrf): use matches! macro in default_skipper by @chrislearn in #1389
- fix(cache): call ctrl.call_next() when skipper triggers by @chrislearn in #1390
- perf(cache): pre-allocate String in RequestIssuer::issue by @chrislearn in #1391
- perf(rate-limiter): use HeaderValue::from for numeric headers by @chrislearn in #1392
- perf(serve-static): cache metadata, fix list_text, reduce allocs by @chrislearn in #1394
- perf(compression): optimize negotiate, add Vary header, fix bugs by @chrislearn in #1393
Full Changelog: v0.90.1...v0.91.1
-
0.91.003 Apr 2026Nothing published for this version
-
0.90.102 Apr 2026Release notes
Open source →What's Changed
- Replace salvo-acme with certon for enhanced ACME support by @chrislearn in #1339
- chore(deps): update sha2 requirement from 0.10 to 0.11 by @dependabot[bot] in #1343
- chore(deps): update chardetng requirement from 0.1 to 1.0 by @dependabot[bot] in #1344
- fix(oapi): replace utoipa:: path references with correct salvo crate paths by @chrislearn in #1346
- fix(oapi): preserve doc comment indentation and split summary by paragraph by @chrislearn in #1347
- fix(oapi): parse serde with attribute for double_option detection by @chrislearn in #1348
- fix(oapi): make enum_values and Content.schema optional per OpenAPI spec by @chrislearn in #1349
- fix(oapi): propagate serde attribute parsing errors instead of silently ignoring by @chrislearn in #1350
- fix(oapi): handle tagged enum variants with flattened fields by @chrislearn in #1351
- fix(oapi): wrap $ref schemas in allOf when title or description is needed by @chrislearn in #1352
- fix(oapi): support nullable values in Map types by @chrislearn in #1354
- feat(oapi): add discriminator schema attribute for enum types by @chrislearn in #1369
- feat(oapi): add missing KnownFormat variants and Array content fields by @chrislearn in #1359
- feat(oapi): use $ref for non-primitive generic type parameters by @chrislearn in #1367
- feat(oapi): use prefixItems for tuple schema representation by @chrislearn in #1362
- feat(oapi): add ToSchema impls for collections and smart pointers by @chrislearn in #1358
- fix(oapi): Option in parameters means optional, not nullable by @chrislearn in #1355
- feat(oapi): add encoding support for multipart request bodies by @chrislearn in #1366
- fix(oapi): restore uint16 format and remove debug eprintln in test by @chrislearn in #1370
- fix(oapi): support negative values in schema validation attributes by @chrislearn in #1353
- feat(oapi): support description and title on unit struct schemas by @chrislearn in #1368
- feat(oapi): add nest() method for prefixing and merging OpenApi documents by @chrislearn in #1365
- feat(oapi): add extensions field to all OpenAPI types per specification by @chrislearn in #1364
- feat(oapi): add property_names support for typed map keys by @chrislearn in #1360
- feat(oapi): support conditional field ignore with bool or function path by @chrislearn in #1363
- feat(oapi): add Number type for correct integer serialization by @chrislearn in #1356
- feat(oapi): add License.identifier field (OpenAPI 3.1) by @chrislearn in #1357
- feat(oapi): add no_recursion attribute to prevent infinite schema recursion by @chrislearn in #1361
- feat(oapi): add ComposeSchema trait and real generics support by @chrislearn in #1371
- [codex] fix(oapi): compose defaults for flattened schemas by @chrislearn in #1372
- fix(oapi): add example/examples methods to AllOf/OneOf/AnyOf schemas by @chrislearn in #1373
- fix(core): support unicode characters in Redirect URLs by @chrislearn in #1374
- fix(oapi): handle ref keyword in PathType parsing for all contexts by @chrislearn in #1375
- docs(cors): clarify that CORS handler must be on Service, not Router by @chrislearn in #1376
- fix: update multer references to multra for compatibility by @chrislearn in #1377
Full Changelog: v0.89.3...v0.90.1
-
0.90.003 Apr 2026Nothing published for this version
-
0.89.318 Mar 2026Nothing published for this version
-
0.89.228 Feb 2026Nothing published for this version
-
0.89.103 Feb 2026Nothing published for this version
-
0.89.028 Jan 2026Nothing published for this version
-
0.88.108 Jan 2026Nothing published for this version
-
0.88.003 Jan 2026Nothing published for this version
-
0.87.131 Dec 2025Nothing published for this version
-
0.87.031 Dec 2025Nothing published for this version
-
0.86.022 Dec 2025Nothing published for this version
-
0.85.024 Nov 2025Nothing published for this version
-
0.84.219 Oct 2025Nothing published for this version
-
0.84.129 Sep 2025Nothing published for this version
-
0.84.011 Sep 2025Nothing published for this version
-
0.83.027 Aug 2025Nothing published for this version
-
0.82.015 Aug 2025Nothing published for this version
-
0.81.019 Jul 2025Nothing published for this version
-
0.80.010 Jul 2025Nothing published for this version
-
0.79.027 May 2025Nothing published for this version
-
0.78.012 Apr 2025Nothing published for this version
-
0.77.121 Mar 2025Nothing published for this version
-
0.77.005 Mar 2025Nothing published for this version
-
0.76.204 Feb 2025Nothing published for this version
-
0.76.124 Jan 2025Nothing published for this version
-
0.76.013 Jan 2025Nothing published for this version
-
0.75.030 Dec 2024Nothing published for this version
-
0.74.312 Dec 2024Nothing published for this version
-
0.74.211 Nov 2024Nothing published for this version
-
0.74.105 Nov 2024Nothing published for this version
-
0.74.028 Oct 2024Nothing published for this version
-
0.73.001 Oct 2024Nothing published for this version
-
0.72.425 Sep 2024Nothing published for this version
-
0.72.323 Sep 2024Nothing published for this version
-
0.72.219 Sep 2024Nothing published for this version
-
0.72.119 Sep 2024Nothing published for this version
-
0.72.013 Sep 2024Nothing published for this version
-
0.71.118 Aug 2024Nothing published for this version
-
0.71.018 Aug 2024Nothing published for this version
-
0.70.013 Aug 2024Nothing published for this version
-
0.69.007 Aug 2024Nothing published for this version
-
0.68.509 Jul 2024Nothing published for this version
-
0.68.424 Jun 2024Nothing published for this version
-
0.68.320 Jun 2024Nothing published for this version
-
0.68.214 Jun 2024Nothing published for this version
-
0.68.105 Jun 2024Nothing published for this version
-
0.68.030 May 2024Nothing published for this version
-
0.67.207 May 2024Nothing published for this version
-
0.67.126 Apr 2024Nothing published for this version
-
0.67.008 Apr 2024Nothing published for this version