# Risk map — pallets/werkzeug

> Canonical page: https://codevetter.com/unpack/werkzeug/risk-map

# Risk map — pallets/werkzeug

Scanned commit 594452f6a4fe4de38a544962fbf04bfc9d37fbc2 (2026-10-01). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

The important trust boundaries are request-body resource consumption, debugger command execution, forwarded headers, filesystem paths, and outbound proxy connections. The observations below describe source behavior and configuration responsibilities, not confirmed vulnerabilities. Compatibility branches and documentation drift also deserve attention during maintenance. The example's persistence race is an explicitly labeled hypothesis requiring separate verification.
- Request.max_content_length defaults to None, get_data reads the body into memory, and URL-encoded parsing does not apply multipart memory/part limits; applications or upstream servers must establish a total-body limit. — [src/werkzeug/wrappers/request.py#L77-L112](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L77-L112) [src/werkzeug/wrappers/request.py#L595-L626](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L595-L626) [src/werkzeug/formparser.py#L318-L328](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/formparser.py#L318-L328)
- The debugger intentionally evaluates Python commands: dispatch requires evalex, a known frame, matching command secret, and PIN trust, then execute_command checks host trust before frame.eval; production deployment docs prohibit the development debugger/server. — [src/werkzeug/debug/__init__.py#L382-L398](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/debug/__init__.py#L382-L398) [src/werkzeug/debug/__init__.py#L547-L565](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/debug/__init__.py#L547-L565) [docs/deployment/index.rst#L4-L16](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/docs/deployment/index.rst#L4-L16)
- ProxyFix's trusted counts select values from the right of forwarded-header lists; trusting client-controlled positions can alter remote address, scheme, host, or mount prefix. — [src/werkzeug/middleware/proxy_fix.py#L15-L23](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/proxy_fix.py#L15-L23) [src/werkzeug/middleware/proxy_fix.py#L43-L67](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/proxy_fix.py#L43-L67) [src/werkzeug/middleware/proxy_fix.py#L111-L130](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/proxy_fix.py#L111-L130)
- safe_join checks path names rather than symlinks or filesystem trust; send_from_directory requires a trusted base directory, while FileStorage.save opens a supplied path directly in write mode. — [src/werkzeug/security.py#L143-L156](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/security.py#L143-L156) [src/werkzeug/utils.py#L570-L593](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/utils.py#L570-L593) [src/werkzeug/datastructures/file_storage.py#L124-L137](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/datastructures/file_storage.py#L124-L137)
- ProxyMiddleware creates outbound HTTP/HTTPS connections to configured targets, forwards filtered request headers and body chunks, and turns OSError into BadGateway; target and TLS configuration are sensitive integration boundaries. — [src/werkzeug/middleware/http_proxy.py#L103-L129](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/http_proxy.py#L103-L129) [src/werkzeug/middleware/http_proxy.py#L145-L198](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/http_proxy.py#L145-L198)
- The reloader spawns the current Python interpreter with inherited environment and descriptors, setting WERKZEUG_RUN_MAIN; run_simple transfers the server descriptor through WERKZEUG_SERVER_FD. — [src/werkzeug/_reloader.py#L213-L229](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/_reloader.py#L213-L229) [src/werkzeug/serving.py#L1094-L1111](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/serving.py#L1094-L1111)
- Hypothesis: concurrent Shortly.insert_url calls for the same URL can both miss the reverse mapping and allocate separate identifiers because GET, INCR, and the two SET operations are separate calls; this was not reproduced. (inferred) — [examples/shortly/shortly.py#L93-L101](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/examples/shortly/shortly.py#L93-L101)
- Security documentation has a concrete default mismatch: generate_password_hash's PBKDF2 description says 600000 iterations, while DEFAULT_PBKDF2_ITERATIONS and test_pbkdf2 use 1000000; callers should rely on the actual stored method string. — [src/werkzeug/security.py#L9-L9](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/security.py#L9-L9) [src/werkzeug/security.py#L85-L102](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/security.py#L85-L102) [tests/test_security.py#L21-L24](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/tests/test_security.py#L21-L24)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
