Flask Bound to All Interfaces

MEDIUM

Detects Flask applications binding the development server to 0.0.0.0, exposing it to every network interface instead of localhost only.

Rule Information

Language
Python
Category
Flask
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythonflasknetworkbindinginterfaceconfigurationmisconfigurationdevelopment-serverCWE-668OWASP-A05
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-FLASK-AUDIT-003 --project .
1
2
3
4
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

About This Rule

Understanding the vulnerability and how it is detected

This rule detects Flask applications configured to bind the development server to 0.0.0.0, which means the server listens on every available network interface -- loopback, LAN, Wi-Fi, and any VPN or container bridge. The Flask built-in server (Werkzeug) is not a production server: it is single-threaded, lacks connection limiting, and was designed for local development only. Exposing it on all interfaces makes it reachable from any machine on the same network, any other container in the same Docker network, or (if no firewall is in place) the public internet.

When combined with debug=True (see PYTHON-FLASK-001), binding to 0.0.0.0 exposes the Werkzeug interactive debugger to the network -- a remote code execution vulnerability accessible to anyone who can reach the port.

The detection uses FlaskApp.method("run").where("host", "0.0.0.0") -- a QueryType-based precise match. FlaskApp declares fqns=["flask"], so only objects imported from the flask package are matched. The .where("host", "0.0.0.0") filter means only calls where the host keyword argument is exactly the string "0.0.0.0" are flagged. Calls with host="127.0.0.1", host="localhost", or a variable are not flagged. This precision delivers zero false positives on correctly configured applications.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Development Server Exposed on Local Network

Binding to 0.0.0.0 makes the Flask development server reachable from any machine on the same network segment. In office or co-working environments this means colleagues can access the app. In containerized environments it means other containers in the same Docker network have direct access to the development server and any admin routes it exposes.

2

Werkzeug Debugger Reachable Over Network

If debug mode is also enabled (app.run(debug=True, host="0.0.0.0")), the Werkzeug interactive debugger becomes reachable from any machine that can route to the port. Any triggered exception opens a Python console to the remote caller -- unauthenticated remote code execution over the network.

3

Unintended Public Exposure Without Firewall

Cloud instances, VMs, and development machines without strict egress/ingress firewall rules will expose the Flask server to the internet when host is set to 0.0.0.0. Developer laptops connected to public Wi-Fi are particularly vulnerable.

4

Sensitive Routes Accessible Without Authentication

Development builds frequently include admin panels, debug endpoints (/debug, /admin), and health-check routes that return internal state. Binding to all interfaces makes these routes accessible to unintended callers without any access control.

How to Fix

Recommended remediation steps

  • 1Bind to 127.0.0.1 (or localhost) for local development so only processes on the same machine can reach the server.
  • 2Never run the Flask built-in development server in production. Use Gunicorn, uWSGI, or Waitress behind a reverse proxy.
  • 3If you need the server reachable from other machines during development (e.g., testing on a mobile device), use a firewall rule or VPN tunnel rather than binding to 0.0.0.0.
  • 4In Docker, use explicit port mapping (-p 127.0.0.1:5000:5000) rather than -p 5000:5000 to avoid binding to all interfaces on the host.
  • 5Audit all app.run() calls in CI with this rule to catch 0.0.0.0 bindings before they reach shared or cloud environments.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

This rule uses a QueryType-based precise match: FlaskApp.method("run").where("host", "0.0.0.0"). FlaskApp declares fqns=["flask"], restricting matches to objects imported from the flask package. The .method("run") step targets the run() method on that object. The .where("host", "0.0.0.0") step filters to calls where the host keyword argument is exactly the string "0.0.0.0". Calls with host="127.0.0.1", host="::", or a variable reference are not flagged. The rule operates at the call-site level without cross-file dataflow analysis.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A05:2021 - Security Misconfiguration: restrict service binding to necessary interfaces
CWE Top 25
CWE-668 Exposure of Resource to Wrong Sphere
NIST SP 800-53
SC-7: Boundary Protection -- limit network reachability of internal services
PCI DSS v4.0
Requirement 1.3 -- restrict inbound and outbound traffic to only that which is necessary

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about Flask Bound to All Interfaces

"Local development" often means a laptop on a shared office network, a VM in a cloud account, or a container in a shared Docker environment. Any of these can expose 0.0.0.0 to other machines. If debug mode is also on, that means remote code execution is available to anyone on the same network. The risk is not theoretical -- it has been exploited in real incidents against developer machines on public Wi-Fi.
Use ngrok or a similar tunnel tool to expose a specific port securely, or configure your machine's firewall to allow connections from your phone's IP only. Both approaches give you external access without permanently binding to 0.0.0.0 in your source code.
No. This rule matches Python source code only, specifically the app.run(host="0.0.0.0") call. Docker-compose port mappings and environment-variable-driven host settings are separate concerns not covered by this rule.
Without .where(), the rule would flag every app.run() call regardless of the host argument -- that would include safe calls with host="127.0.0.1". The .where("host", "0.0.0.0") constraint means only the literal string "0.0.0.0" triggers a finding. If you pass the host from a variable (host=bind_address), the rule does not flag it, since the value is not statically known to be "0.0.0.0".
Yes. Flask's app.run() defaults to host="127.0.0.1" when no host is specified. Omitting the host argument is the safest option for local development, as it binds to localhost only and will not flag this rule.
Run: pathfinder ci --ruleset python/flask/PYTHON-FLASK-AUDIT-003 --project . The rule outputs SARIF, JSON, or CSV and can post inline pull request comments on GitHub.
No. This rule matches the app.run(host="0.0.0.0") call-site pattern only. Configuration via app.config["HOST"] or the FLASK_RUN_HOST environment variable used with flask run is not covered. These are separate patterns that would require a dedicated audit rule.

New feature

Get these findings posted directly on your GitHub pull requests

The Flask Bound to All Interfaces rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works