Insecurely generated cookies - Secure
Need
Transmission of session cookies over encrypted connections only
Context
• Usage of Rust 1.75+ for building application services
• Usage of the actix-web crate for handling HTTP requests
• Usage of the actix-session crate for cookie-based sessions
Description
1. Non compliant code
use actix_session::storage::CookieSessionStore;
use actix_session::SessionMiddleware;
use actix_web::cookie::Key;
fn session_middleware(key: Key) -> SessionMiddleware<CookieSessionStore> {
// The session cookie is also sent over plain HTTP
SessionMiddleware::builder(CookieSessionStore::default(), key)
.cookie_secure(false)...The `session_middleware` function below configures `actix-session` with `cookie_secure(false)`, so the session cookie is issued without the `Secure` attribute. Without `Secure`, the browser also sends the cookie over plain HTTP. An attacker on the same network, such as a public Wi-Fi hotspot, can make the browser send a request to `http://` for the same domain, for example with an image tag on any page, and read the session cookie from the unencrypted traffic. With it, the attacker takes over the session. This setting is often introduced to make local development work over HTTP and then ships to production unchanged. The same flaw appears when a cookie is built with `Cookie::build` without `.secure(true)`, or with `.secure(false)`.
2. Steps
• Keep `cookie_secure(true)`, the default, in `actix_session::SessionMiddleware`, and remove every `cookie_secure(false)`.
• Call `.secure(true)` on every `Cookie::build` chain that creates a session or authentication cookie.
• Do not disable the `Secure` attribute for local development in code that reaches production; use a local HTTPS setup instead.
• Serve the application only over HTTPS and redirect plain HTTP requests.
• Send a `Strict-Transport-Security` header so browsers never make the first request over HTTP.
3. Secure code example
use actix_session::storage::CookieSessionStore;
use actix_session::SessionMiddleware;
use actix_web::cookie::{Key, SameSite};
fn session_middleware(key: Key) -> SessionMiddleware<CookieSessionStore> {
// Secure: the browser only sends the session cookie over HTTPS
SessionMiddleware::builder(CookieSessionStore::default(), key)
.cookie_secure(true)...The corrected function sets `cookie_secure(true)`, which is also the default of `SessionMiddleware`. The browser only sends the session cookie over HTTPS, so it never travels in clear text. The configuration also keeps `cookie_http_only(true)` and sets `SameSite::Strict`, so the same cookie is protected from scripts and from cross-site requests. For local development over HTTP, the correct approach is to run a local TLS proxy or to read the flag from a configuration that defaults to secure, never to disable it in the code that is deployed. `Secure` protects the cookie, but the whole site should also be served only over HTTPS and send a `Strict-Transport-Security` header, so browsers do not make the first request in clear text.
References
• 130. Insecurely generated cookies - Secure