Skip to content

SEC003: eval-exec

eval, exec, execfile or compile on code built at run time

Code SEC003
Name eval-exec
Category Security (SEC)
Default severity warning
Enabled by default yes
Fix available no
ign-lint equivalent none

Reports calls of the builtins eval, execfile and compile, and the exec statement, when the code (or file name) they receive is not a literal: a parameter, a tag value, a payload field, text built from values, ...

Only the builtins count: a local function or variable that shadows eval is not reported, and neither are methods such as re.compile. Literal code (eval("1 + 2")), names whose every reaching assignment is a literal, and text concatenated from literals are not reported.

The scripts run on the gateway with the gateway's permissions. Code that comes from a tag, a database row, a message payload or a user input field can do anything the gateway can: read files, call other systems, change tags. Even when the source is trusted today, such code escapes review, linting and the Designer's search.

There is almost always a direct alternative: getattr for a name chosen at run time, a dict of functions for a command chosen at run time, system.util.jsonDecode or ast.literal_eval-style parsing for data.

def runAction(self, event):
handler = self.view.params.handler
eval("project.handlers.%s(event)" % handler)

Use instead:

HANDLERS = {"start": handlers.start, "stop": handlers.stop}
def runAction(self, event):
HANDLERS[self.view.params.handler](event)

Generated from the rule metadata by iglint generate-docs; iglint rule SEC003 prints the same page in the terminal. Source: docs/rules/SEC003.md.