-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
I found some FN in the BindToAllInterfaces rule. While the rule successfully catches direct literal bindings like s.bind(('0.0.0.0', 8080)), but I identified that it sometimes doesn't match some common real-world usage patterns.
First, the rule relies on tracking string literals directly into the bind() call. However, it misses cases where the address is stored in an object attribute or derived from environment variable defaults. The DataFlow::TypeTrackingNode configuration doesn't seem to propagate the taint through instance attributes or library default arguments. I am not sure whether this can be solved by configuring the dataflow tracking.
For example, storing the address in self.bind_addr bypasses the check:
class Server:
def __init__(self):
self.bind_addr = '0.0.0.0' # Taint lost here
self.port = 31137
def start(self):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((self.bind_addr, self.port)) # Rule misses thisSimilarly, using os.environ.get with an insecure default value isn't flagged:
import os
import socket
# The default '0.0.0.0' is not tracked as a taint source
host = os.environ.get('APP_HOST', '0.0.0.0')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, 8080)) # Rule misses thisSecond,
The rule is hardcoded to check API::moduleImport("socket"). This excludes widely used alternatives like gevent.socket and high-level framework runners that perform binding internally.
For instance, using gevent.socket evades the module check:
from gevent import socket # Not 'import socket.'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 31137)) # Rule misses thisHigh-level framework methods like Sanic.run or aiohttp.web.run_app also bind sockets but aren't modeled as sinks:
from sanic import Sanic
app = Sanic(__name__)
if __name__ == "__main__":
# Internally binds to 0.0.0.0, but doesn't call socket.bind() directly
app.run(host='0.0.0.0', port=31137) # Rule misses thisBut I am not sure if there is another rule to handle these framework cases.