Keywords: Python | HTTP | SimpleHTTPServer
Abstract: This article explains how to restrict Python SimpleHTTPServer to bind only to localhost for enhanced security. It covers custom implementations and alternative methods.
Problem Background
Many developers use Python's SimpleHTTPServer module to quickly start an HTTP server for local development or testing. However, by default, the server binds to all network interfaces (0.0.0.0), meaning it can be accessed via localhost and external IP. When users are connected via VPN, this can pose security risks, such as being scanned by malicious bots. Therefore, restricting the server to bind only to localhost (127.0.0.1) is necessary.
Custom Implementation Method
In Python 2.x, the test() function of the SimpleHTTPServer module hardcodes binding to 0.0.0.0. To change the host, a custom implementation is required. Below is a custom code example based on the best answer.
import sys
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer
def test(HandlerClass=SimpleHTTPRequestHandler,
ServerClass=BaseHTTPServer.HTTPServer):
protocol = "HTTP/1.0"
host = ''
port = 8000
if len(sys.argv) > 1:
arg = sys.argv[1]
if ':' in arg:
host, port = arg.split(':')
port = int(port)
else:
try:
port = int(sys.argv[1])
except:
host = sys.argv[1]
server_address = (host, port)
HandlerClass.protocol_version = protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
if __name__ == "__main__":
test()This code allows specifying the host and port via command-line arguments. For example:
> python server.py 127.0.0.1
Serving HTTP on 127.0.0.1 port 8000 ...
> python server.py 127.0.0.1:9000
Serving HTTP on 127.0.0.1 port 9000 ...
> python server.py 8080
Serving HTTP on 0.0.0.0 port 8080 ...By setting the host to 127.0.0.1, the server binds only to localhost, ensuring external access is blocked.
Other Solutions
For Python 3.4 and higher, the http.server module provides a --bind parameter to directly specify the binding address in the command line. For example:
python -m http.server 8000 --bind 127.0.0.1This simplifies the process but is only applicable to Python 3. For Python 2, a command-line one-liner can be used:
python -c 'import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer(("127.0.0.1", 8888), shs.SimpleHTTPRequestHandler).serve_forever()'This method is convenient but not easy to remember and relies on specific syntax.
Conclusion
To ensure Python HTTP servers are accessible only locally, developers can choose different solutions based on the Python version. Python 2 users are recommended to use custom implementations, while Python 3 users can directly utilize built-in parameters. This helps enhance the security of local development environments.