Add security warning when dev server binds to non-localhost

Warn users when Flask's development server is bound to a
non-localhost address, which exposes the Werkzeug debugger
to the network. The debugger allows arbitrary code execution
and should never be exposed on untrusted networks.

- Raises RuntimeWarning when host is not 127.0.0.1/localhost/::1
- Raises an additional RuntimeWarning when debug mode is also enabled
- Uses warnings.warn() so the warning is visible but doesn't prevent
  the server from starting (existing behavior preserved)
This commit is contained in:
zinc-builds 2026-05-11 00:38:20 +01:00
parent 7374c85dde
commit 3599ac28be

View file

@ -14,6 +14,7 @@ from types import TracebackType
from urllib.parse import quote as _url_quote from urllib.parse import quote as _url_quote
import click import click
import warnings
from werkzeug.datastructures import Headers from werkzeug.datastructures import Headers
from werkzeug.datastructures import ImmutableDict from werkzeug.datastructures import ImmutableDict
from werkzeug.exceptions import BadRequestKeyError from werkzeug.exceptions import BadRequestKeyError
@ -740,6 +741,25 @@ class Flask(App):
options.setdefault("use_debugger", self.debug) options.setdefault("use_debugger", self.debug)
options.setdefault("threaded", True) options.setdefault("threaded", True)
if host not in {"127.0.0.1", "localhost", "::1"}:
warnings.warn(
f"The Flask development server is binding to '{host}', which "
"makes it accessible on the network. The development server "
"is not intended for production use and the Werkzeug debugger "
"can execute arbitrary code if exposed.",
RuntimeWarning,
stacklevel=2,
)
if self.debug:
warnings.warn(
"Debug mode is enabled while the development server is "
"accessible on the network. The Werkzeug debugger allows "
"arbitrary code execution — do NOT use this configuration "
"in production or on untrusted networks.",
RuntimeWarning,
stacklevel=2,
)
cli.show_server_banner(self.debug, self.name) cli.show_server_banner(self.debug, self.name)
from werkzeug.serving import run_simple from werkzeug.serving import run_simple