SEC006: os-command
Script starts an operating system process
| Code | SEC006 |
| Name | os-command |
| Category | Security (SEC) |
| Default severity | warning |
| Enabled by default | yes |
| Fix available | no |
| ign-lint equivalent | none |
What it does
Section titled “What it does”Reports calls that start operating system processes:
os.system,os.popen,os.popen2/3/4,os.exec*,os.spawn*,os.startfile;subprocess.call,check_call,check_outputandPopen;commands.getoutput,getstatusoutputandgetstatus, thepopen2module,platform.popen;java.lang.Runtime.getRuntime().exec(...), also throughfrom java.lang import Runtimeor a variable holding the runtime;java.lang.ProcessBuilder(...);- Ignition's
system.util.execute.
Calls are recognised through imports and aliases (import os as o,
from subprocess import Popen, rt = Runtime.getRuntime()), never by
the function name alone: a library function named system or a method
exec of another object is not reported.
Why is this bad?
Section titled “Why is this bad?”The process runs on the gateway (or the client) with the operating system
account of the Ignition service. A command line built from tag values,
payloads or user input lets that input run arbitrary commands. Even fixed
commands make the project depend on the server's operating system, its
PATH and installed tools, and block a gateway thread while they run.
Prefer Ignition's own functions (system.file.*, system.net.*) or a
service with its own API. When a process is really needed, use a fixed program with a
list of arguments, never a shell command line, and suppress the finding
with # iglint: ignore[SEC006] on that line.
Example
Section titled “Example”import os
def onMessageReceived(self, payload): os.system("ping -c 1 " + payload["host"])Use instead:
def onMessageReceived(self, payload): reachable = system.net.httpClient().get(payload["url"]).goodGenerated from the rule metadata by iglint generate-docs; iglint rule SEC006 prints the same page in the terminal. Source: docs/rules/SEC006.md.