Technologies
Flask
Flask is recognisable from outside only through strong evidence, and the strongest is a `Server: Werkzeug` header — which is itself a finding. Werkzeug's server is Flask's development server, and Flask's documentation says not to use it, or its built-in debugger, in production: the debugger allows executing arbitrary Python code from the browser. The session cookie defaults to the name `session` without the Secure flag.
How the engine recognises it
`Server: Werkzeug` header — weight 90, the only signal strong enough on its own.
A signed session cookie in Flask's format — weight 30; a static URL with a `?v=` cache-buster — weight 20. Neither reaches the threshold alone.
A Flask application behind a production server does not send the Werkzeug header, and is usually not recognised — which is the correct outcome.
The dedicated check states the rule: Python or a generic session cookie is not enough.
The development server in production
Flask's deployment guide says the built-in development server, debugger and reloader should not be used in production, and recommends a dedicated WSGI server instead.
The development server page repeats it: do not use the development server when deploying to production.
A `Server: Werkzeug` header on a live site therefore means the development server is answering the public.
The version the header often includes is extracted and listed; it is the Werkzeug version, not Flask's.
The debugger
The debugging guide is explicit: do not run the development server or enable the built-in debugger in production.
The debugger allows executing arbitrary Python code from the browser. It is protected by a PIN, and the guide says that should not be relied on for security.
An audit does not try to reach the debugger. It reports the development server, which is the precondition.
Moving to a production WSGI server removes both at once.
Session cookie defaults
`SESSION_COOKIE_NAME` defaults to `session`.
`SESSION_COOKIE_SECURE` defaults to `False`, so the cookie is sent over plain HTTP unless configured otherwise.
Flask's default session is a signed cookie: the documentation notes that the user can look at its contents but not modify them, so nothing secret belongs in it.
An audit reads the flags the cookie actually carries.
Which checks apply
`technology.flask` reports Flask only from strong public evidence, with the Werkzeug version when present.
`technology.versions` lists the Werkzeug version published in the header.
`security.server_disclosure` reports the header as a product and version disclosure.
`cookies.secure` and `cookies.httponly` report the session cookie's flags.
Other session defaults
`SESSION_COOKIE_HTTPONLY` defaults to `True`, so script cannot read the session cookie.
`SESSION_COOKIE_SAMESITE` defaults to `None`, meaning the attribute is not set; the documentation recommends `'Lax'` or `'Strict'`.
`PERMANENT_SESSION_LIFETIME` defaults to 31 days, and applies when a session is marked permanent.
`SECRET_KEY` signs the session cookie; the documentation asks for a long random value and shows how to generate one.
A weak or leaked secret key is not observable from outside, but its consequence is: anyone holding it can forge a valid session.
Security headers are left to the application
Flask's security documentation recommends reviewing a list of security headers for each application, rather than setting them for you.
It shows how to set headers such as Strict-Transport-Security and Content-Security-Policy on responses, and points to the Flask-Talisman extension for managing HTTPS and security headers.
A Flask site with no security headers is therefore the default state, not a regression.
Frequently asked questions
- Why is my Flask site not detected?
- Most likely because it runs behind a production WSGI server, which does not send the Werkzeug header. That is the configuration you want.
- Is a Werkzeug header dangerous?
- It means the development server is serving the public, which Flask's documentation says not to do. If the debugger is enabled too, arbitrary code can run from the browser.
- Can visitors read my Flask session?
- The default session cookie is signed, not encrypted: it cannot be altered, and its contents can be decoded. Keep secrets out of it.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website