When developing applications with Actix-web, developers must assume responsibility for request routing order, input boundary enforcement, and safe error propagation to prevent security bypasses and information leakage. The framework provides default protections for HTTP/1.1 framing validation and basic content typing, but relies on explicit configuration for payload sizing, security headers, authentication middleware ordering, and static file path sandboxing. All security-sensitive boundaries, including authentication wrappers, route-level guards, proxy headers, and resource limits, must be configured securely and fail closed.
Essential implementation rules
Enforce Route-Level Guards and Correct Middleware Order
Attach custom guard functions and authorization middleware using guard = "..." and .wrap() to filter requests before reaching handlers. Register security middleware in reverse order via .wrap() so outermost security checks execute first, and specify endpoint handlers using Route::to() or Route::service() before chaining wrappers.
Use Named Structs for Query Extraction
Define named structs derived with Deserialize for web::Query<T> extraction rather than ordered tuples to prevent panic conditions caused by unordered URL query parameters.
Sanitize Error Responses and Propagate Startup Failures
Implement explicit ResponseError traits or ErrorHandlers middleware to replace raw stack traces and diagnostic details with sanitized JSON payloads. Ensure asynchronous state factories return explicit error variants so application startup fails fast on missing dependencies.
Order Route Registrations and Restrict Dynamic Path Segments
Register specific application routes and API services before mounting broader prefix matching or catch-all static file services to prevent handler shadowing. Restrict custom dynamic segment patterns with regular expressions that explicitly forbid slash characters to avoid path traversal.
Restrict SHA-1 Hashing to WebSocket Handshakes
Use the hash_key function strictly for RFC 6455 WebSocket handshake challenge-response generation and never for general-purpose cryptographic security or credential hashing.
Enforce Content-Type Validation and Strict Multipart Limits
Rely on ClientResponse::json() to enforce automatic application/json Content-Type verification and payload size boundaries. Apply #[multipart(deny_unknown_fields, duplicate_field = "deny")] and byte limits to guard form uploads against parameter pollution and memory exhaustion.
Avoid Unencrypted Transport and Experimental Production Features
Omit the dangerous-h2c feature flag in production deployments to prevent wrapping unencrypted TCP streams as mock TLS connections, and disable experimental-introspection reports.
Isolate Static File Serving and Validate Paths
Mount static file services against dedicated asset directories rather than broad root paths, keep hidden file serving disabled, and use .path_filter() to block symlink traversal.
Differentiate Raw and Decoded Cookie and Match Information
Use raw cookie retrieval methods like cookie_raw() when validating cryptographic HMAC signatures or exact byte sequences that should not be percent-decoded. Explicitly validate and decode req.match_info() parameters before using them in file access or routing logic.
Configure Global and Error-Level Security Headers
Attach standard HTTP security headers globally across apps and scopes using DefaultHeaders middleware, and ensure custom error handlers explicitly inspect and set mandatory security headers on returned error responses.
Rely on Built-in Framing Validation and Secure Tunneling
Rely on Actix Web’s built-in header validation to reject malformed framing, maintain native HTTP/2 framing without manually injecting transfer-encoding headers, and ensure raw socket tunnels are negotiated over HTTP/1.1.
Verify Direct Peer IP Addresses for Access Control
Use req.peer_addr() instead of req.connection_info() for IP-based authorization and rate limiting unless trusted reverse proxy settings are explicitly verified, as upstream forwarding headers can be spoofed.
Encode Dynamic Output and Set Explicit Content Types
Explicitly set attachment dispositions or non-executable content types when serving user files, use structured builders or strict MIME types for non-HTML payloads, and strictly HTML-encode user input when overriding content types to HTML.
Bound Server Timeouts, Connections, and Payload Sizes
Configure explicit request timeouts, connection limits, and handshake rates on HttpServer and awc::Connector to prevent slow client exhaustion. Use web::PayloadConfig, MultipartFormConfig, and WebSocket frame size limits to bound memory consumption.
Redact Sensitive Headers from Logs and Invalidate Sessions Securely
Avoid invoking Debug formatting on request instances containing credentials, and sanitize logger format strings using custom request replacements. Invalidate client-side sessions by constructing removal cookies with matching attributes and invoking add_removal_cookie.
actix-web: All Security Cards
Approximately 7,841 tokens
On this card
Category: access control
Enforce access control using guards, resource constraints, and middleware
Use when
Enforcing access control, permissions, and request filtering across routes, resources, scopes, and middleware handlers in Actix Web.
Secure rules
Rule 1: Restrict access to endpoints using route-level guards and middleware wraps
Attach custom guard functions or authorization middleware directly to route macros using guard = "..." and wrap = "..." to ensure requests are filtered before reaching the handler function.
Rule 2: Enforce request prerequisites uniformly using resource and scope guards
Use Resource::guard() and Scope::guard(...) to enforce security constraints, headers, or policy checks uniformly across all nested resources and services within a path prefix or resource pattern.
Rule 3: Short-circuit unauthorized requests in custom function middleware
Use from_fn middleware to short-circuit unauthorized requests early by returning an error or early response via req.into_response(...) without executing next.call(req).
async fn authorize_request( req: ServiceRequest, next: Next<impl MessageBody + 'static>,) -> Result<ServiceResponse<impl MessageBody>, Error> { if !is_authorized(&req) { return Ok(req.into_response(HttpResponse::Unauthorized().finish()).map_into_right_body()); } let res = next.call(req).await?; Ok(res.map_into_left_body())}
Category: api contract misuse
Avoid order-dependent tuples in web::Query extraction
Use when
Extracting URL query parameters into strongly typed structures within Actix Web request handlers.
Secure rules
Rule 1: Use named structs or map types instead of ordered tuples for web::Query<T> extraction.
Because URL query strings consist of unordered key-value pairs, deserializing into types that rely on positional ordering will cause serde_urlencoded and Actix Web to panic during request handling. Define named structs derived with Deserialize to ensure robust type and ordering handling.
use actix_web::{get, web};use serde::Deserialize;#[derive(Deserialize)]pub struct SearchParams { pub query: String, pub page: Option<u32>,}#[get("/search")]async fn search(info: web::Query<SearchParams>) -> String { format!("Searching for {} on page {:?}", info.query, info.page)}
Manage Actix Web Error Responses and Service Failures Securely
Use when
When handling HTTP errors, custom service failures, default fallback resources, and application state initialization to prevent information leakage and application panics.
Secure rules
Rule 1: Pre-validate dynamic header inputs before passing them to client builders to prevent unhandled process panics.
Always convert dynamic or user-controlled header names and values using fallible parse methods before supplying them to ClientBuilder::add_default_header. This prevents unexpected application panics during client initialization.
use awc::ClientBuilder;use actix_web::http::header::{HeaderName, HeaderValue};fn configure_client(builder: ClientBuilder, key: &str, val: &str) -> Result<ClientBuilder, String> { let name = HeaderName::from_bytes(key.as_bytes()).map_err(|e| e.to_string())?; let value = HeaderValue::from_str(val).map_err(|e| e.to_string())?; Ok(builder.add_default_header((name, value)))}
Rule 2: Sanitize HTTP error response bodies using error handler middleware to avoid leaking internal implementation details.
Use ErrorHandlers middleware to intercept HTTP 4xx and 5xx error responses and replace raw diagnostic details or stack traces with generic, safe payloads.
use actix_web::dev::ServiceResponse;use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};use actix_web::{App, Result};use bytes::Bytes;fn sanitize_server_error<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> { let (req, res) = res.into_parts(); let res = res.set_body(Bytes::from("{\"error\":\"An internal error occurred.\"}")); let res = ServiceResponse::new(req, res) .map_into_boxed_body() .map_into_right_body(); Ok(ErrorHandlerResponse::Response(res))}let app = App::new().wrap( ErrorHandlers::new().default_handler_server(sanitize_server_error));
Rule 3: Implement custom ResponseError mappings for services to prevent raw internal errors from exposing sensitive diagnostics.
When returning errors from custom services passed to Route::service, implement the ResponseError trait explicitly to return sanitized HTTP responses and status codes.
Rule 4: Propagate state initialization errors to ensure application startup fails fast on missing dependencies.
Return explicit error variants from asynchronous state factories used in App::data_factory so Actix Web aborts startup rather than running with uninitialized dependencies.
use actix_web::{web, App, HttpResponse};struct DatabasePool;async fn init_db() -> Result<DatabasePool, String> { Err("Failed to connect to database".to_string())}let app = App::new() .data_factory(|| init_db()) .service(web::resource("/").to(|| HttpResponse::Ok()));
Category: boundary control
Restrict Route Registration Order and Segment Boundaries to Enforce Request Boundaries
Use when
When registering routes, scopes, and dynamic path segments in Actix-web applications to ensure requests are routed through proper security boundaries.
Secure rules
Rule 1: Order specific route and service registrations before broader patterns and static file catch-alls.
Ensure that specific application routes and API services are registered before mounting broader prefix matching or catch-all static file services like Files::new. Registering broad catch-alls or generic scope prefixes first causes request matching to short-circuit prematurely, shadowing specialized handlers and bypassing route-specific security checks.
Rule 2: Restrict custom dynamic segment patterns to prevent path traversal across segments.
When defining custom dynamic segment patterns using the {name:regex} syntax, ensure the regular expression explicitly restricts matched characters and does not inadvertently match slash / characters. Allowing slashes inside custom dynamic segment regexes permits input to cross segment boundaries and bypass route scoping controls.
use actix_router::ResourceDef;let resource = ResourceDef::new(r"/user/{id:\d+}");assert!(resource.is_match("/user/123"));assert!(!resource.is_match("/user/123/details"));
Category: cryptography
Restrict SHA1 hashing strictly to WebSocket handshake verification
Use when
When performing RFC 6455 WebSocket handshake challenge-response generation using hash_key.
Secure rules
Rule 1: Use the hash_key function strictly for WebSocket handshake challenge-response protocol compliance.
Calculate base64(sha1(key + WS_GUID)) solely to perform the RFC 6455 WebSocket handshake challenge-response. Developers must not use hash_key or SHA-1 for general-purpose cryptographic security, data integrity verification, or credential hashing.
use actix_http::ws::hash_key;// Correct: Calculating Sec-WebSocket-Accept response header per RFC 6455let client_key = b"dGhlIHNhbXBsZSBub25jZQ==";let accept_value = hash_key(client_key);assert_eq!(accept_value.len(), 28);
Category: deserialization
Validate response payload limits and format during JSON parsing
Use when
Deserializing structured response data from remote endpoints via ClientResponse::json() where content-type checks and payload limits prevent memory exhaustion or unexpected parsing.
Secure rules
Rule 1: Rely on ClientResponse::json() to enforce an explicit application/json Content-Type check and default payload size limits instead of manually parsing raw bytes.
When deserializing JSON responses using ClientResponse::json(), ensure that responses are handled via built-in parsing methods that enforce content type validation and strict payload length boundaries to prevent memory exhaustion and unexpected parsing behaviors.
#[derive(serde::Deserialize)]struct MyResponse { id: u64,}let mut res = client.get("https://example.com/api") .send() .await?;// json() enforces Content-Type matching and a 2 MiB payload limit by defaultlet data: MyResponse = res.json().await?;
Category: escape hatch
Restrict Unsafe Transport Features and Avoid dangerous-h2c in Production
Use when
Configuring network client transport capabilities and dependencies where transport-layer security features must be enforced instead of unencrypted bypasses.
Secure rules
Rule 1: Do not enable the dangerous-h2c feature flag in production deployments.
Ensure that dangerous-h2c is omitted from Cargo.toml dependencies so that unencrypted TCP streams are not wrapped as mock TLS connections. Only enable standard TLS features such as rustls-0_23-webpki-roots or openssl for network client communication.
[dependencies]awc = { version = "3.5", features = ["rustls-0_23-webpki-roots"] }
Category: file handling
Safely Handle and Restrict File Paths During Static Asset Serving
Use when
Configuring static file serving or processing user-influenced file paths and uploads to prevent unauthorized file access, path traversal, and dotfile disclosure.
Secure rules
Rule 1: Isolate static file services to dedicated asset directories rather than broad root paths.
Avoid mounting file services against broad roots like . or directories containing application source code. Always mount static file services against dedicated, isolated directories specifically intended for public asset distribution.
use actix_web::App;use actix_files::Files;let app = App::new() .service(Files::new("/static", "./public").prefer_utf8(true));
Do not call use_hidden_files() on Files unless serving dotfiles is an explicit requirement, as default configurations properly restrict access to files and directories starting with a dot.
use actix_files::Files;use actix_web::App;let app = App::new() .service( Files::new("/static", "./static") );
Rule 3: Implement path filters to block symbolic links and unauthorized paths.
Use .path_filter() to enforce explicit path constraints and prevent symlink traversal before static files are retrieved from disk.
Enforce Strict Input Boundaries and Reject Unknown Multipart Fields
Use when
Handling structured form and multipart file uploads where unexpected fields or duplicate parameters must be rejected to prevent parameter pollution.
Secure rules
Rule 1: Configure strict rejection attributes on multipart form structs to deny unknown fields and duplicate parameters.
Use the deny_unknown_fields and duplicate_field = "deny" macro attributes on MultipartForm structs to strictly enforce input boundaries, rejecting parameter pollution and unintended field overrides.
Differentiate raw and percent-decoded cookie representations during retrieval
Use when
Retrieving and validating request cookies or path match information where percent-decoding behavior affects security decisions and cryptographic checks.
Secure rules
Rule 1: Use raw cookie retrieval methods when validating unmodified cookie byte sequences
Use cookies_raw() or cookie_raw() when checking HMAC signatures or exact cookie values that should not be percent-decoded. Standard cookie methods automatically percent-decode names and values, which can alter signatures or tokens containing encoded characters.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn token_check_handler(req: HttpRequest) -> impl Responder { if let Some(cookie) = req.cookie_raw("session_sig") { let raw_token = cookie.value(); if is_valid_signature(raw_token) { return HttpResponse::Ok().finish(); } } HttpResponse::Unauthorized().finish();}fn is_valid_signature(_sig: &str) -> bool { true}
Rule 2: Validate raw match info parameters before using them in path operations
Be aware that req.match_info() preserves sequences such as %2F, %25, and %2B without percent-decoding to maintain path boundary integrity. Explicitly decode or validate these values before using them in file access or routing logic.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn get_resource(req: HttpRequest) -> impl Responder { if let Some(param) = req.match_info().get("filename") { if param.contains('/') || param.contains("..") { return HttpResponse::BadRequest().body("Invalid parameter"); } } HttpResponse::Ok().finish();}
Category: interface protocol hardening
Configure and Enforce HTTP Security Headers across Applications, Error Responses, and Routes
Use when
Developing Actix Web applications and defining middleware, error handlers, or routes that require security headers like Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, or Content-Security-Policy.
Secure rules
Rule 1: Attach standard HTTP security headers globally using the DefaultHeaders middleware.
Use Actix Web’s DefaultHeaders middleware exported from the middleware module to attach security headers to all outgoing HTTP responses across an App or Scope.
Rule 2: Explicitly set security headers on HTTP error responses using ErrorHandlers middleware.
When handling HTTP errors with ErrorHandlers middleware, ensure custom error handlers explicitly inspect and set mandatory security headers on the returned ServiceResponse because standard route middleware may not apply to unhandled error paths.
Rule 3: Apply route-level security headers after handler definition using wrap.
When enforcing HTTP security headers on specific routes using middleware like DefaultHeaders via Route::wrap, always call .to() or .service() before .wrap() to avoid runtime panics in Actix Web v4.14.0.
Enforce Strict HTTP Framing and Protocol Rules to Prevent Request Smuggling
Use when
When handling incoming HTTP/1.x requests, configuring HTTP/2 native framing, or managing client connection reuse in Actix Web and awc.
Secure rules
Rule 1: Rely on Actix Web’s built-in header validation to reject conflicting or malformed framing headers.
Actix Web automatically enforces strict HTTP/1.1 framing validation during header decoding to reject requests with multiple Content-Length headers, invalid Content-Length formatting, conflicting Transfer-Encoding and Content-Length headers, or HTTP/1.0 Transfer-Encoding headers. Do not attempt to bypass or alter these standard HTTP protocol constraints.
Rule 2: Use native HTTP/2 framing without manually injecting transfer-encoding headers.
When streaming request bodies over HTTP/2 using awc::ClientRequest::send_stream, rely on awc’s built-in HTTP/2 framing mechanism and do not manually append Transfer-Encoding headers, as HTTP/2 uses native DATA frames and forbids transfer encoding.
Rule 3: Maintain default client mode frame masking when communicating with WebSocket endpoints.
By default, WebsocketsRequest operates in standard client mode, automatically applying payload masking to outbound frames per RFC 6455 §5.3. Refrain from calling server_mode() when acting as a WebSocket client to prevent protocol misinterpretation.
let (_resp, connection) = client .ws("wss://example.com/socket") .connect() .await?;
Rule 4: Maintain connection keep-alive and lifetime configurations to discard tainted pooled connections.
When reusing connections from the pool, awc checks idle HTTP/1 connections for unread data before issuing new requests. Configure connector limits and keep-alive durations on the client builder to allow proper socket recycling and prevent HTTP response smuggling.
Validate WebSocket Subprotocols and Enforce HTTP/1.1 Tunnel Constraints
Use when
When establishing WebSocket connections, setting up subprotocols, or opening socket tunnels in Actix Web and awc.
Secure rules
Rule 1: Specify allowed WebSocket subprotocols explicitly using an explicit allowlist.
Use WsResponseBuilder or handshake_with_protocols with an explicit protocol allowlist to negotiate WebSocket subprotocols safely and prevent application state corruption.
Rule 2: Enforce HTTP/1.1 when opening raw socket tunnels.
When establishing standard HTTP tunnels using Connection::open_tunnel, ensure that the connection is negotiated over HTTP/1.1, as awc explicitly disallows socket tunneling over HTTP/2 connections.
use awc::Client;use actix_http::http::Version;let client = Client::builder() .max_http_version(Version::HTTP_11) .finish();
Category: network boundary
Configure Trusted Reverse Proxies and Direct Peer Verification for Network Boundaries
Use when
When configuring IP-based access controls, rate limiting, or network logging in Actix Web services deployed behind reverse proxies or handling direct client connections.
Secure rules
Rule 1: Use direct peer socket addresses for IP-based access controls and rate limiting.
Prefer req.peer_addr() over req.connection_info() when implementing IP-based authorization or security boundaries unless trusted proxy settings are explicitly verified. Reconstructed connection info relying on Forwarded or X-Forwarded-For headers can be spoofed by untrusted upstream clients.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn restricted_handler(req: HttpRequest) -> impl Responder { match req.peer_addr() { Some(addr) if addr.ip().is_loopback() => HttpResponse::Ok().body("Admin Panel"), _ => HttpResponse::Forbidden().finish(), }}
Rule 2: Avoid trusting remote IP headers in loggers without a trusted reverse proxy.
When configuring the Logger middleware with the %{r}a format specifier, ensure that the application runs behind a trusted reverse proxy that sanitizes or overwrites forwarding headers. Otherwise, use %a for direct TCP peer IP logging.
Prevent Cross-Site Scripting (XSS) by setting explicit content types and encoding output
Use when
Building HTTP responses, serving files, or returning string responders that include dynamic user data in Actix Web applications.
Secure rules
Rule 1: Explicitly set attachment dispositions or non-executable content types when serving user files.
When serving untrusted user files using NamedFile, explicitly force attachment disposition with set_content_disposition or override the content type to a non-executable type like application/octet-stream to prevent browsers from executing inline scripts.
use actix_files::NamedFile;use actix_web::http::header::{ContentDisposition, DispositionType};async fn serve_user_file() -> actix_web::Result<NamedFile> { let file = NamedFile::open_async("./uploads/user_doc.html").await?; Ok(file.set_content_disposition(ContentDisposition { disposition: DispositionType::Attachment, parameters: vec![], }))}
Rule 2: Specify explicit safe content types or structured builders for responses containing dynamic data.
When building responses with HttpResponseBuilder or ResponseBuilder, explicitly specify strict MIME types like mime::APPLICATION_JSON or mime::TEXT_PLAIN_UTF_8 for non-HTML payloads, or use structured builders like .json() to avoid MIME-sniffing vulnerabilities.
Rule 3: HTML-encode user-supplied data before overriding response content types to HTML.
Actix Web default string responders automatically set text/plain, preventing script execution. When using .customize().insert_header(...) or response builders to set text/html, strictly encode all user input using an HTML escaping library to prevent XSS.
use actix_web::{web, Responder, http::header};use html_escape::encode_text;async fn user_profile(username: web::Path<String>) -> impl Responder { let safe_name = encode_text(&username); let html_body = format!("<h1>User Profile</h1><p>Welcome, {}</p>", safe_name); html_body .customize() .insert_header((header::CONTENT_TYPE, "text/html; charset=utf-8"))}
Category: resource exhaustion
Configure HTTP Server and Protocol Timeouts
Use when
Configuring transport protocols, server instances, client connections, and request timeouts to protect against slowloris and resource exhaustion attacks.
Secure rules
Rule 1: Set explicit request and connection timeouts on the HTTP server to prevent slow client exhaustion.
Configure client_request_timeout, tls_handshake_timeout, and keep_alive on HttpServer using Duration parameters to ensure that incomplete requests or slow handshakes are forcefully terminated. Avoid zero or unbounded configurations.
Rule 2: Enforce connection limits and handshake rates to protect CPU and socket resources.
Configure max_connections and max_connection_rate on HttpServer to bound active workloads and mitigate CPU resource exhaustion from TLS handshake bursts.
Rule 3: Configure explicit TLS handshake timeouts on transport acceptors.
When initializing TLS service acceptors, configure an explicit handshake timeout using TlsAcceptorConfig::handshake_timeout to prevent unauthenticated clients from stalling connections.
use std::time::Duration;use actix_http::{HttpService, TlsAcceptorConfig};HttpService::build() .finish(handler) .rustls_0_23_with_config( tls_config, TlsAcceptorConfig::default().handshake_timeout(Duration::from_secs(5)), );
Configure Outbound Client and Worker Operation Timeouts
Use when
Making outbound HTTP requests, configuring client connectors, or executing blocking tasks to prevent thread starvation and hung operations.
Secure rules
Rule 1: Configure explicit timeouts and connection limits on HTTP client connectors.
Use awc::Connector to configure explicit request timeouts, handshake timeouts, and active connection limits to prevent socket starvation and thread hanging.
use std::time::Duration;use awc::Connector;let connector = Connector::new() .timeout(Duration::from_secs(5)) .handshake_timeout(Duration::from_secs(5)) .limit(100) .finish();
Rule 2: Offload synchronous or blocking computations using block tasks.
Offload CPU-intensive calculations or blocking disk/database operations using web::block to prevent blocking the asynchronous event loop worker threads.
use actix_web::{web, HttpResponse, Error};async fn sync_handler() -> Result<HttpResponse, Error> { let result = web::block(|| { std::thread::sleep(std::time::Duration::from_millis(100)); "done" }).await.map_err(|_| actix_web::error::ErrorInternalServerError("Blocking task failed"))?; Ok(HttpResponse::Ok().body(result))}
Limit Payload Sizes and WebSocket Frames
Use when
Handling incoming request bodies, multipart form uploads, and WebSocket frame streaming to bound memory consumption.
Secure rules
Rule 1: Enforce payload size limits for application requests and compressed bodies.
Attach web::PayloadConfig using app_data on resources or routes to explicitly restrict the maximum allowed size in bytes for incoming request bodies.
Rule 3: Enforce strict size limits on multipart form fields and total uploads.
Apply #[multipart(limit = "...")] byte limits to individual struct fields and register MultipartFormConfig with a bounded total_limit to prevent oversized file uploads from exhausting server resources.
Disable experimental features in production builds
Use when
Configuring crate dependencies and feature flags for production deployment
Secure rules
Rule 1: Do not expose experimental-introspection reports in production because they can include sensitive configuration details
Limit experimental-introspection to development or local diagnostic builds, or ensure its reports are not exposed in production.
[dev-dependencies]actix-web = { version = "4.14.0", features = ["experimental-introspection"] }
Category: secret handling
Redact Sensitive Headers and Credentials from Logs and Debug Output
Use when
When logging HTTP requests, client requests, or WebSocket connections containing sensitive credentials, bearer tokens, cookies, or authorization headers in Actix-web and awc applications.
Secure rules
Rule 1: Avoid formatting or printing raw request objects or using unsafe logger format strings that expose sensitive headers
Do not invoke Debug formatting on ClientRequest or WebsocketsRequest instances when they contain credentials or authorization headers, as this outputs raw sensitive tokens into log files. HttpRequest redacts Authorization, Proxy-Authorization, and Cookie header values, but prints other headers and the query string. Similarly, avoid configuring Logger format strings to directly print sensitive request headers or environment secrets, and use custom_request_replace to sanitize log output instead.
Register Middleware in Correct Order and Configure Fail-Closed Security Checks
Use when
When registering security middleware, conditional wrappers, or route handlers in Actix Web applications to ensure security controls execute properly and do not fail open.
Secure rules
Rule 1: Register security middleware in reverse order using .wrap() so that outermost security checks execute first on incoming requests.
Actix Web executes middleware in reverse order of registration via .wrap(). Ensure that authentication and authorization middleware are registered last in the builder chain so they act as the outermost layer and intercept requests before they reach inner handlers or middleware.
Rule 2: Ensure boolean runtime conditions guarding security middleware fail closed by defaulting to enabled.
When using Condition::new(bool, middleware) to conditionally apply security controls, ensure that the boolean flag defaults to true in production environments so that a missing or unvalidated configuration does not silently bypass the middleware.
use actix_web::{middleware::Condition, App};let enable_auth = std::env::var("DISABLE_AUTH") .map(|val| val != "1") .unwrap_or(true);let app = App::new() .wrap(Condition::new(enable_auth, my_auth_middleware));
Rule 3: Specify endpoint handlers before applying middleware wrappers on routes.
Always specify the endpoint handler using Route::to() or Route::service() before chaining middleware using Route::wrap(). Actix Web v4.14.0 panics at runtime if handler methods are called after wrap() to prevent accidentally dropping route-level middleware.
Invalidate Client-Side Sessions Safely with add_removal_cookie
Use when
Clearing session cookies or authentication state from the client browser during logout or session termination
Secure rules
Rule 1: Use add_removal_cookie instead of del_cookie to properly invalidate stored cookies on the client browser.
When logging a user out or clearing session tokens, calling del_cookie only removes Set-Cookie headers from the in-memory response struct without instructing the browser to clear stored cookies. To ensure the client browser deletes the session cookie, construct a cookie with matching path and domain attributes and invoke add_removal_cookie.
use actix_web::HttpResponse;use cookie::Cookie;let mut res = HttpResponse::Ok().finish();let cookie = Cookie::build("session_id", "") .path("/") .finish();res.add_removal_cookie(&cookie).expect("valid header value");
Enforce access control using guards, resource constraints, and middleware
Approximately 497 tokens
Use when
Enforcing access control, permissions, and request filtering across routes, resources, scopes, and middleware handlers in Actix Web.
Secure rules
Rule 1: Restrict access to endpoints using route-level guards and middleware wraps
Attach custom guard functions or authorization middleware directly to route macros using guard = "..." and wrap = "..." to ensure requests are filtered before reaching the handler function.
Rule 2: Enforce request prerequisites uniformly using resource and scope guards
Use Resource::guard() and Scope::guard(...) to enforce security constraints, headers, or policy checks uniformly across all nested resources and services within a path prefix or resource pattern.
Rule 3: Short-circuit unauthorized requests in custom function middleware
Use from_fn middleware to short-circuit unauthorized requests early by returning an error or early response via req.into_response(...) without executing next.call(req).
async fn authorize_request( req: ServiceRequest, next: Next<impl MessageBody + 'static>,) -> Result<ServiceResponse<impl MessageBody>, Error> { if !is_authorized(&req) { return Ok(req.into_response(HttpResponse::Unauthorized().finish()).map_into_right_body()); } let res = next.call(req).await?; Ok(res.map_into_left_body())}
Avoid order-dependent tuples in web::Query extraction
Approximately 1,007 tokens
Use when
Extracting URL query parameters into strongly typed structures within Actix Web request handlers.
Secure rules
Rule 1: Use named structs or map types instead of ordered tuples for web::Query<T> extraction.
Because URL query strings consist of unordered key-value pairs, deserializing into types that rely on positional ordering will cause serde_urlencoded and Actix Web to panic during request handling. Define named structs derived with Deserialize to ensure robust type and ordering handling.
use actix_web::{get, web};use serde::Deserialize;#[derive(Deserialize)]pub struct SearchParams { pub query: String, pub page: Option<u32>,}#[get("/search")]async fn search(info: web::Query<SearchParams>) -> String { format!("Searching for {} on page {:?}", info.query, info.page)}
Manage Actix Web Error Responses and Service Failures Securely
Use when
When handling HTTP errors, custom service failures, default fallback resources, and application state initialization to prevent information leakage and application panics.
Secure rules
Rule 1: Pre-validate dynamic header inputs before passing them to client builders to prevent unhandled process panics.
Always convert dynamic or user-controlled header names and values using fallible parse methods before supplying them to ClientBuilder::add_default_header. This prevents unexpected application panics during client initialization.
use awc::ClientBuilder;use actix_web::http::header::{HeaderName, HeaderValue};fn configure_client(builder: ClientBuilder, key: &str, val: &str) -> Result<ClientBuilder, String> { let name = HeaderName::from_bytes(key.as_bytes()).map_err(|e| e.to_string())?; let value = HeaderValue::from_str(val).map_err(|e| e.to_string())?; Ok(builder.add_default_header((name, value)))}
Rule 2: Sanitize HTTP error response bodies using error handler middleware to avoid leaking internal implementation details.
Use ErrorHandlers middleware to intercept HTTP 4xx and 5xx error responses and replace raw diagnostic details or stack traces with generic, safe payloads.
use actix_web::dev::ServiceResponse;use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};use actix_web::{App, Result};use bytes::Bytes;fn sanitize_server_error<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> { let (req, res) = res.into_parts(); let res = res.set_body(Bytes::from("{\"error\":\"An internal error occurred.\"}")); let res = ServiceResponse::new(req, res) .map_into_boxed_body() .map_into_right_body(); Ok(ErrorHandlerResponse::Response(res))}let app = App::new().wrap( ErrorHandlers::new().default_handler_server(sanitize_server_error));
Rule 3: Implement custom ResponseError mappings for services to prevent raw internal errors from exposing sensitive diagnostics.
When returning errors from custom services passed to Route::service, implement the ResponseError trait explicitly to return sanitized HTTP responses and status codes.
Rule 4: Propagate state initialization errors to ensure application startup fails fast on missing dependencies.
Return explicit error variants from asynchronous state factories used in App::data_factory so Actix Web aborts startup rather than running with uninitialized dependencies.
use actix_web::{web, App, HttpResponse};struct DatabasePool;async fn init_db() -> Result<DatabasePool, String> { Err("Failed to connect to database".to_string())}let app = App::new() .data_factory(|| init_db()) .service(web::resource("/").to(|| HttpResponse::Ok()));
Restrict Route Registration Order and Segment Boundaries to Enforce Request Boundaries
Approximately 382 tokens
Use when
When registering routes, scopes, and dynamic path segments in Actix-web applications to ensure requests are routed through proper security boundaries.
Secure rules
Rule 1: Order specific route and service registrations before broader patterns and static file catch-alls.
Ensure that specific application routes and API services are registered before mounting broader prefix matching or catch-all static file services like Files::new. Registering broad catch-alls or generic scope prefixes first causes request matching to short-circuit prematurely, shadowing specialized handlers and bypassing route-specific security checks.
Rule 2: Restrict custom dynamic segment patterns to prevent path traversal across segments.
When defining custom dynamic segment patterns using the {name:regex} syntax, ensure the regular expression explicitly restricts matched characters and does not inadvertently match slash / characters. Allowing slashes inside custom dynamic segment regexes permits input to cross segment boundaries and bypass route scoping controls.
use actix_router::ResourceDef;let resource = ResourceDef::new(r"/user/{id:\d+}");assert!(resource.is_match("/user/123"));assert!(!resource.is_match("/user/123/details"));
Restrict SHA1 hashing strictly to WebSocket handshake verification
Approximately 225 tokens
Use when
When performing RFC 6455 WebSocket handshake challenge-response generation using hash_key.
Secure rules
Rule 1: Use the hash_key function strictly for WebSocket handshake challenge-response protocol compliance.
Calculate base64(sha1(key + WS_GUID)) solely to perform the RFC 6455 WebSocket handshake challenge-response. Developers must not use hash_key or SHA-1 for general-purpose cryptographic security, data integrity verification, or credential hashing.
use actix_http::ws::hash_key;// Correct: Calculating Sec-WebSocket-Accept response header per RFC 6455let client_key = b"dGhlIHNhbXBsZSBub25jZQ==";let accept_value = hash_key(client_key);assert_eq!(accept_value.len(), 28);
Validate response payload limits and format during JSON parsing
Approximately 240 tokens
Use when
Deserializing structured response data from remote endpoints via ClientResponse::json() where content-type checks and payload limits prevent memory exhaustion or unexpected parsing.
Secure rules
Rule 1: Rely on ClientResponse::json() to enforce an explicit application/json Content-Type check and default payload size limits instead of manually parsing raw bytes.
When deserializing JSON responses using ClientResponse::json(), ensure that responses are handled via built-in parsing methods that enforce content type validation and strict payload length boundaries to prevent memory exhaustion and unexpected parsing behaviors.
#[derive(serde::Deserialize)]struct MyResponse { id: u64,}let mut res = client.get("https://example.com/api") .send() .await?;// json() enforces Content-Type matching and a 2 MiB payload limit by defaultlet data: MyResponse = res.json().await?;
Restrict Unsafe Transport Features and Avoid dangerous-h2c in Production
Approximately 201 tokens
Use when
Configuring network client transport capabilities and dependencies where transport-layer security features must be enforced instead of unencrypted bypasses.
Secure rules
Rule 1: Do not enable the dangerous-h2c feature flag in production deployments.
Ensure that dangerous-h2c is omitted from Cargo.toml dependencies so that unencrypted TCP streams are not wrapped as mock TLS connections. Only enable standard TLS features such as rustls-0_23-webpki-roots or openssl for network client communication.
[dependencies]awc = { version = "3.5", features = ["rustls-0_23-webpki-roots"] }
Safely Handle and Restrict File Paths During Static Asset Serving
Approximately 411 tokens
Use when
Configuring static file serving or processing user-influenced file paths and uploads to prevent unauthorized file access, path traversal, and dotfile disclosure.
Secure rules
Rule 1: Isolate static file services to dedicated asset directories rather than broad root paths.
Avoid mounting file services against broad roots like . or directories containing application source code. Always mount static file services against dedicated, isolated directories specifically intended for public asset distribution.
use actix_web::App;use actix_files::Files;let app = App::new() .service(Files::new("/static", "./public").prefer_utf8(true));
Do not call use_hidden_files() on Files unless serving dotfiles is an explicit requirement, as default configurations properly restrict access to files and directories starting with a dot.
use actix_files::Files;use actix_web::App;let app = App::new() .service( Files::new("/static", "./static") );
Rule 3: Implement path filters to block symbolic links and unauthorized paths.
Use .path_filter() to enforce explicit path constraints and prevent symlink traversal before static files are retrieved from disk.
Enforce Strict Input Boundaries and Reject Unknown Multipart Fields
Approximately 183 tokens
Use when
Handling structured form and multipart file uploads where unexpected fields or duplicate parameters must be rejected to prevent parameter pollution.
Secure rules
Rule 1: Configure strict rejection attributes on multipart form structs to deny unknown fields and duplicate parameters.
Use the deny_unknown_fields and duplicate_field = "deny" macro attributes on MultipartForm structs to strictly enforce input boundaries, rejecting parameter pollution and unintended field overrides.
Differentiate raw and percent-decoded cookie representations during retrieval
Approximately 410 tokens
Use when
Retrieving and validating request cookies or path match information where percent-decoding behavior affects security decisions and cryptographic checks.
Secure rules
Rule 1: Use raw cookie retrieval methods when validating unmodified cookie byte sequences
Use cookies_raw() or cookie_raw() when checking HMAC signatures or exact cookie values that should not be percent-decoded. Standard cookie methods automatically percent-decode names and values, which can alter signatures or tokens containing encoded characters.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn token_check_handler(req: HttpRequest) -> impl Responder { if let Some(cookie) = req.cookie_raw("session_sig") { let raw_token = cookie.value(); if is_valid_signature(raw_token) { return HttpResponse::Ok().finish(); } } HttpResponse::Unauthorized().finish();}fn is_valid_signature(_sig: &str) -> bool { true}
Rule 2: Validate raw match info parameters before using them in path operations
Be aware that req.match_info() preserves sequences such as %2F, %25, and %2B without percent-decoding to maintain path boundary integrity. Explicitly decode or validate these values before using them in file access or routing logic.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn get_resource(req: HttpRequest) -> impl Responder { if let Some(param) = req.match_info().get("filename") { if param.contains('/') || param.contains("..") { return HttpResponse::BadRequest().body("Invalid parameter"); } } HttpResponse::Ok().finish();}
Configure and Enforce HTTP Security Headers across Applications, Error Responses, and Routes
Approximately 1,492 tokens
Use when
Developing Actix Web applications and defining middleware, error handlers, or routes that require security headers like Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, or Content-Security-Policy.
Secure rules
Rule 1: Attach standard HTTP security headers globally using the DefaultHeaders middleware.
Use Actix Web’s DefaultHeaders middleware exported from the middleware module to attach security headers to all outgoing HTTP responses across an App or Scope.
Rule 2: Explicitly set security headers on HTTP error responses using ErrorHandlers middleware.
When handling HTTP errors with ErrorHandlers middleware, ensure custom error handlers explicitly inspect and set mandatory security headers on the returned ServiceResponse because standard route middleware may not apply to unhandled error paths.
Rule 3: Apply route-level security headers after handler definition using wrap.
When enforcing HTTP security headers on specific routes using middleware like DefaultHeaders via Route::wrap, always call .to() or .service() before .wrap() to avoid runtime panics in Actix Web v4.14.0.
Enforce Strict HTTP Framing and Protocol Rules to Prevent Request Smuggling
Use when
When handling incoming HTTP/1.x requests, configuring HTTP/2 native framing, or managing client connection reuse in Actix Web and awc.
Secure rules
Rule 1: Rely on Actix Web’s built-in header validation to reject conflicting or malformed framing headers.
Actix Web automatically enforces strict HTTP/1.1 framing validation during header decoding to reject requests with multiple Content-Length headers, invalid Content-Length formatting, conflicting Transfer-Encoding and Content-Length headers, or HTTP/1.0 Transfer-Encoding headers. Do not attempt to bypass or alter these standard HTTP protocol constraints.
Rule 2: Use native HTTP/2 framing without manually injecting transfer-encoding headers.
When streaming request bodies over HTTP/2 using awc::ClientRequest::send_stream, rely on awc’s built-in HTTP/2 framing mechanism and do not manually append Transfer-Encoding headers, as HTTP/2 uses native DATA frames and forbids transfer encoding.
Rule 3: Maintain default client mode frame masking when communicating with WebSocket endpoints.
By default, WebsocketsRequest operates in standard client mode, automatically applying payload masking to outbound frames per RFC 6455 §5.3. Refrain from calling server_mode() when acting as a WebSocket client to prevent protocol misinterpretation.
let (_resp, connection) = client .ws("wss://example.com/socket") .connect() .await?;
Rule 4: Maintain connection keep-alive and lifetime configurations to discard tainted pooled connections.
When reusing connections from the pool, awc checks idle HTTP/1 connections for unread data before issuing new requests. Configure connector limits and keep-alive durations on the client builder to allow proper socket recycling and prevent HTTP response smuggling.
Validate WebSocket Subprotocols and Enforce HTTP/1.1 Tunnel Constraints
Use when
When establishing WebSocket connections, setting up subprotocols, or opening socket tunnels in Actix Web and awc.
Secure rules
Rule 1: Specify allowed WebSocket subprotocols explicitly using an explicit allowlist.
Use WsResponseBuilder or handshake_with_protocols with an explicit protocol allowlist to negotiate WebSocket subprotocols safely and prevent application state corruption.
Rule 2: Enforce HTTP/1.1 when opening raw socket tunnels.
When establishing standard HTTP tunnels using Connection::open_tunnel, ensure that the connection is negotiated over HTTP/1.1, as awc explicitly disallows socket tunneling over HTTP/2 connections.
use awc::Client;use actix_http::http::Version;let client = Client::builder() .max_http_version(Version::HTTP_11) .finish();
Configure Trusted Reverse Proxies and Direct Peer Verification for Network Boundaries
Approximately 363 tokens
Use when
When configuring IP-based access controls, rate limiting, or network logging in Actix Web services deployed behind reverse proxies or handling direct client connections.
Secure rules
Rule 1: Use direct peer socket addresses for IP-based access controls and rate limiting.
Prefer req.peer_addr() over req.connection_info() when implementing IP-based authorization or security boundaries unless trusted proxy settings are explicitly verified. Reconstructed connection info relying on Forwarded or X-Forwarded-For headers can be spoofed by untrusted upstream clients.
use actix_web::{HttpRequest, HttpResponse, Responder};pub async fn restricted_handler(req: HttpRequest) -> impl Responder { match req.peer_addr() { Some(addr) if addr.ip().is_loopback() => HttpResponse::Ok().body("Admin Panel"), _ => HttpResponse::Forbidden().finish(), }}
Rule 2: Avoid trusting remote IP headers in loggers without a trusted reverse proxy.
When configuring the Logger middleware with the %{r}a format specifier, ensure that the application runs behind a trusted reverse proxy that sanitizes or overwrites forwarding headers. Otherwise, use %a for direct TCP peer IP logging.
Prevent Cross-Site Scripting (XSS) by setting explicit content types and encoding output
Approximately 565 tokens
Use when
Building HTTP responses, serving files, or returning string responders that include dynamic user data in Actix Web applications.
Secure rules
Rule 1: Explicitly set attachment dispositions or non-executable content types when serving user files.
When serving untrusted user files using NamedFile, explicitly force attachment disposition with set_content_disposition or override the content type to a non-executable type like application/octet-stream to prevent browsers from executing inline scripts.
use actix_files::NamedFile;use actix_web::http::header::{ContentDisposition, DispositionType};async fn serve_user_file() -> actix_web::Result<NamedFile> { let file = NamedFile::open_async("./uploads/user_doc.html").await?; Ok(file.set_content_disposition(ContentDisposition { disposition: DispositionType::Attachment, parameters: vec![], }))}
Rule 2: Specify explicit safe content types or structured builders for responses containing dynamic data.
When building responses with HttpResponseBuilder or ResponseBuilder, explicitly specify strict MIME types like mime::APPLICATION_JSON or mime::TEXT_PLAIN_UTF_8 for non-HTML payloads, or use structured builders like .json() to avoid MIME-sniffing vulnerabilities.
Rule 3: HTML-encode user-supplied data before overriding response content types to HTML.
Actix Web default string responders automatically set text/plain, preventing script execution. When using .customize().insert_header(...) or response builders to set text/html, strictly encode all user input using an HTML escaping library to prevent XSS.
use actix_web::{web, Responder, http::header};use html_escape::encode_text;async fn user_profile(username: web::Path<String>) -> impl Responder { let safe_name = encode_text(&username); let html_body = format!("<h1>User Profile</h1><p>Welcome, {}</p>", safe_name); html_body .customize() .insert_header((header::CONTENT_TYPE, "text/html; charset=utf-8"))}
Configure HTTP Server and Protocol Timeouts
Approximately 1,236 tokens
Use when
Configuring transport protocols, server instances, client connections, and request timeouts to protect against slowloris and resource exhaustion attacks.
Secure rules
Rule 1: Set explicit request and connection timeouts on the HTTP server to prevent slow client exhaustion.
Configure client_request_timeout, tls_handshake_timeout, and keep_alive on HttpServer using Duration parameters to ensure that incomplete requests or slow handshakes are forcefully terminated. Avoid zero or unbounded configurations.
Rule 2: Enforce connection limits and handshake rates to protect CPU and socket resources.
Configure max_connections and max_connection_rate on HttpServer to bound active workloads and mitigate CPU resource exhaustion from TLS handshake bursts.
Rule 3: Configure explicit TLS handshake timeouts on transport acceptors.
When initializing TLS service acceptors, configure an explicit handshake timeout using TlsAcceptorConfig::handshake_timeout to prevent unauthenticated clients from stalling connections.
use std::time::Duration;use actix_http::{HttpService, TlsAcceptorConfig};HttpService::build() .finish(handler) .rustls_0_23_with_config( tls_config, TlsAcceptorConfig::default().handshake_timeout(Duration::from_secs(5)), );
Configure Outbound Client and Worker Operation Timeouts
Use when
Making outbound HTTP requests, configuring client connectors, or executing blocking tasks to prevent thread starvation and hung operations.
Secure rules
Rule 1: Configure explicit timeouts and connection limits on HTTP client connectors.
Use awc::Connector to configure explicit request timeouts, handshake timeouts, and active connection limits to prevent socket starvation and thread hanging.
use std::time::Duration;use awc::Connector;let connector = Connector::new() .timeout(Duration::from_secs(5)) .handshake_timeout(Duration::from_secs(5)) .limit(100) .finish();
Rule 2: Offload synchronous or blocking computations using block tasks.
Offload CPU-intensive calculations or blocking disk/database operations using web::block to prevent blocking the asynchronous event loop worker threads.
use actix_web::{web, HttpResponse, Error};async fn sync_handler() -> Result<HttpResponse, Error> { let result = web::block(|| { std::thread::sleep(std::time::Duration::from_millis(100)); "done" }).await.map_err(|_| actix_web::error::ErrorInternalServerError("Blocking task failed"))?; Ok(HttpResponse::Ok().body(result))}
Limit Payload Sizes and WebSocket Frames
Use when
Handling incoming request bodies, multipart form uploads, and WebSocket frame streaming to bound memory consumption.
Secure rules
Rule 1: Enforce payload size limits for application requests and compressed bodies.
Attach web::PayloadConfig using app_data on resources or routes to explicitly restrict the maximum allowed size in bytes for incoming request bodies.
Rule 3: Enforce strict size limits on multipart form fields and total uploads.
Apply #[multipart(limit = "...")] byte limits to individual struct fields and register MultipartFormConfig with a bounded total_limit to prevent oversized file uploads from exhausting server resources.
Disable experimental features in production builds
Approximately 143 tokens
Use when
Configuring crate dependencies and feature flags for production deployment
Secure rules
Rule 1: Do not expose experimental-introspection reports in production because they can include sensitive configuration details
Limit experimental-introspection to development or local diagnostic builds, or ensure its reports are not exposed in production.
[dev-dependencies]actix-web = { version = "4.14.0", features = ["experimental-introspection"] }
Redact Sensitive Headers and Credentials from Logs and Debug Output
Approximately 281 tokens
Use when
When logging HTTP requests, client requests, or WebSocket connections containing sensitive credentials, bearer tokens, cookies, or authorization headers in Actix-web and awc applications.
Secure rules
Rule 1: Avoid formatting or printing raw request objects or using unsafe logger format strings that expose sensitive headers
Do not invoke Debug formatting on ClientRequest or WebsocketsRequest instances when they contain credentials or authorization headers, as this outputs raw sensitive tokens into log files. HttpRequest redacts Authorization, Proxy-Authorization, and Cookie header values, but prints other headers and the query string. Similarly, avoid configuring Logger format strings to directly print sensitive request headers or environment secrets, and use custom_request_replace to sanitize log output instead.
Register Middleware in Correct Order and Configure Fail-Closed Security Checks
Approximately 467 tokens
Use when
When registering security middleware, conditional wrappers, or route handlers in Actix Web applications to ensure security controls execute properly and do not fail open.
Secure rules
Rule 1: Register security middleware in reverse order using .wrap() so that outermost security checks execute first on incoming requests.
Actix Web executes middleware in reverse order of registration via .wrap(). Ensure that authentication and authorization middleware are registered last in the builder chain so they act as the outermost layer and intercept requests before they reach inner handlers or middleware.
Rule 2: Ensure boolean runtime conditions guarding security middleware fail closed by defaulting to enabled.
When using Condition::new(bool, middleware) to conditionally apply security controls, ensure that the boolean flag defaults to true in production environments so that a missing or unvalidated configuration does not silently bypass the middleware.
use actix_web::{middleware::Condition, App};let enable_auth = std::env::var("DISABLE_AUTH") .map(|val| val != "1") .unwrap_or(true);let app = App::new() .wrap(Condition::new(enable_auth, my_auth_middleware));
Rule 3: Specify endpoint handlers before applying middleware wrappers on routes.
Always specify the endpoint handler using Route::to() or Route::service() before chaining middleware using Route::wrap(). Actix Web v4.14.0 panics at runtime if handler methods are called after wrap() to prevent accidentally dropping route-level middleware.
Invalidate Client-Side Sessions Safely with add_removal_cookie
Approximately 229 tokens
Use when
Clearing session cookies or authentication state from the client browser during logout or session termination
Secure rules
Rule 1: Use add_removal_cookie instead of del_cookie to properly invalidate stored cookies on the client browser.
When logging a user out or clearing session tokens, calling del_cookie only removes Set-Cookie headers from the in-memory response struct without instructing the browser to clear stored cookies. To ensure the client browser deletes the session cookie, construct a cookie with matching path and domain attributes and invoke add_removal_cookie.
use actix_web::HttpResponse;use cookie::Cookie;let mut res = HttpResponse::Ok().finish();let cookie = Cookie::build("session_id", "") .path("/") .finish();res.add_removal_cookie(&cookie).expect("valid header value");