VNX-1125: Excessive Attack Surface
Reports Python RPC servers configured to expose far more than their own handlers: XML-RPC register_instance with allow_dotted_names=True, RPyC classic services or allow_all_attrs/allow_setattr/allow_delattr, Pyro4 REQUIRE_EXPOSE = False, and eval, exec, open, os.system or subprocess functions registered as remote procedures, directly or wrapped in a lambda.
| Field | Value |
|---|---|
| Rule ID | VNX-1125 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Python |
| CWE | CWE-1125 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | excessive-attack-surface cwe-1125 rpc |
| Source | internal/sast/rules/vnx-1125.rego |
Overview
VNX-1125 maps to CWE-1125: Excessive Attack Surface. Most attack surface is intended: a web route is an endpoint someone chose to publish. This rule reports the configurations where a Python remote-procedure server publishes far more than the functions it was written to serve:
- XML-RPC
register_instance(obj, allow_dotted_names=True)(orTrueas the second argument): every attribute reachable through dotted names, including module globals, is callable remotely, a documented route to code execution; - RPyC
ThreadedServer/ForkingServer/ThreadPoolServer/OneShotServerservingSlaveService,ClassicServiceorMasterService: the whole Python runtime of the process is remote-callable; - RPyC protocol settings
allow_all_attrs,allow_setattrorallow_delattrset toTrue; - Pyro4
config.REQUIRE_EXPOSE = False: every method of every registered object becomes remote-callable; register_function(eval),exec,compile,__import__,open,os.system,os.popenor asubprocessfunction registered as a remote procedure.
Not reported: register_instance without dotted names, custom rpyc.Service subclasses with exposed_ methods, Pyro objects marked @expose, register_function of the application’s own handlers, web routes, comments, strings and test files.
What Gets Flagged
server.register_instance(Inventory(), allow_dotted_names=True) # FLAGGED
t = ThreadedServer(SlaveService, hostname="0.0.0.0", port=18812) # FLAGGED
Pyro4.config.REQUIRE_EXPOSE = False # FLAGGED
server.register_function(os.system, "run") # FLAGGED
class CalcService(rpyc.Service): # NOT FLAGGED: only exposed_ methods
def exposed_add(self, a, b):
return a + b
server.register_instance(Calculator()) # NOT FLAGGED
Remediation
- Register only the functions clients need, by name, with
register_function; never passallow_dotted_names=True. - Serve a custom
rpyc.Servicethat definesexposed_methods instead of the classic service, and leaveallow_all_attrs,allow_setattrandallow_delattrat their defaults. - Keep Pyro’s
REQUIRE_EXPOSEon and mark remote methods with@Pyro4.expose. - Bind RPC servers to localhost or a private interface and require authentication.
References
- CWE-1125: Excessive Attack Surface
- Python xmlrpc.server: register_instance security warning
- RPyC security
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-1125
// nosec vnx-1125
Or record an ignore rule: vulnetix ignore add --rule vnx-1125 --reason "...". See Suppressing findings.