From af35135c8cb097e8ff13ce348473725b58bb8781 Mon Sep 17 00:00:00 2001 From: Robin Jarry <robin.jarry@6wind.com> Date: Mon, 1 Aug 2016 09:32:29 +0200 Subject: [PATCH] Prevent namespace pollution Some symbols are "internal" to modules (__all__, __file__, __doc__, __package__, etc.) they should *not* be replaced by the one from other modules. The "from xxx import *" python syntax construct takes this into account and only imports the "public" symbols (i.e., those whose name does not start with an underscore). When a __all__ symbol is defined in a module (it should be a list of strings), the "from xxx import *" construct only imports the names listed in xxx.__all__. Avoid shadowing module specific symbols when dynamically loading layers and other modules by only importing "public" symbols. Fix importing the "tls" layer along the way (remove erroneous __all__ definition). Signed-off-by: Robin Jarry <robin.jarry@6wind.com> --- scapy/config.py | 2 +- scapy/layers/all.py | 22 ++++++++++++++-------- scapy/layers/tls/crypto/__init__.py | 1 - scapy/main.py | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/scapy/config.py b/scapy/config.py index 3f4fe8e6..bd0acda6 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -378,7 +378,7 @@ extensions_paths: path or list of paths where extensions are to be looked for temp_files = [] netcache = NetCache() geoip_city = '/usr/share/GeoIP/GeoLiteCity.dat' - load_layers = ["l2", "inet", "dhcp", "dns", "dot11", "gprs", + load_layers = ["l2", "inet", "dhcp", "dns", "dot11", "gprs", "tls", "hsrp", "inet6", "ir", "isakmp", "l2tp", "mgcp", "mobileip", "netbios", "netflow", "ntp", "ppp", "radius", "rip", "rtp", "skinny", "smb", "snmp", diff --git a/scapy/layers/all.py b/scapy/layers/all.py index d707e0dd..17740494 100644 --- a/scapy/layers/all.py +++ b/scapy/layers/all.py @@ -12,19 +12,25 @@ from scapy.error import log_loading import logging log = logging.getLogger("scapy.loading") +__all__ = [] + def _import_star(m): mod = __import__(m, globals(), locals()) - for k,v in mod.__dict__.iteritems(): - globals()[k] = v + if '__all__' in mod.__dict__: + # only import the exported symbols in __all__ + for name in mod.__dict__['__all__']: + __all__.append(name) + globals()[name] = mod.__dict__[name] + else: + # import all the non-private symbols + for name, sym in mod.__dict__.iteritems(): + if name[0] != '_': + __all__.append(name) + globals()[name] = sym for _l in conf.load_layers: log_loading.debug("Loading layer %s" % _l) try: _import_star(_l) except Exception,e: - log.warning("can't import layer %s: %s" % (_l,e)) - -from scapy.layers.tls import * - - - + log.warning("can't import layer %s: %s" % (_l,e)) diff --git a/scapy/layers/tls/crypto/__init__.py b/scapy/layers/tls/crypto/__init__.py index b30813d2..e69de29b 100644 --- a/scapy/layers/tls/crypto/__init__.py +++ b/scapy/layers/tls/crypto/__init__.py @@ -1 +0,0 @@ -__all__ = ["curves"] diff --git a/scapy/main.py b/scapy/main.py index 4337cdd5..f1d64203 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -60,7 +60,15 @@ from scapy.themes import DefaultTheme def _load(module): try: mod = __import__(module,globals(),locals(),".") - __builtin__.__dict__.update(mod.__dict__) + if '__all__' in mod.__dict__: + # import listed symbols + for name in mod.__dict__['__all__']: + __builtin__.__dict__[name] = mod.__dict__[name] + else: + # only import non-private symbols + for name, sym in mod.__dict__.iteritems(): + if name[0] != '_': + __builtin__.__dict__[name] = sym except Exception,e: log_interactive.error(e) @@ -281,7 +289,9 @@ def interact(mydict=None,argv=None,mybanner=None,loglevel=20): _read_config_file(PRESTART_FILE) scapy_builtins = __import__("all",globals(),locals(),".").__dict__ - __builtin__.__dict__.update(scapy_builtins) + for name, sym in scapy_builtins.iteritems(): + if name [0] != '_': + __builtin__.__dict__[name] = sym globkeys = scapy_builtins.keys() globkeys.append("scapy_session") scapy_builtins=None # XXX replace with "with" statement -- GitLab