Security
The Python conveniences that are remote-code-execution holes -- pickle, yaml.load, eval/exec, and subprocess shell injection
Security
Several Python conveniences become remote-code-execution vulnerabilities the moment they touch untrusted input. A senior engineer treats pickle, yaml.load, eval/exec, and shell=True as red flags in review -- and knows the safe alternative for each.
Secure Deserialization and Code Execution
Several Python conveniences are remote-code-execution vulnerabilities if fed untrusted input. A senior engineer treats these as red flags in review.
import pickle, yaml, json
# pickle executes arbitrary code on load. NEVER unpickle untrusted data --
# a crafted payload runs os.system on deserialize. Use JSON for data exchange.
pickle.loads(untrusted_bytes) # RCE: full code execution
# yaml.load is equally dangerous with the default loader. Always:
yaml.safe_load(untrusted_yaml) # safe -- only builds basic types
yaml.load(untrusted_yaml) # DANGER -- can instantiate arbitrary objects
# eval / exec on any string influenced by input is code injection:
eval(user_input) # never. There is almost always a real parser.
ast.literal_eval(user_input) # safe: only literals (dict/list/str/num)The same rule applies to shells. subprocess with shell=True and an interpolated string is command injection:
import subprocess
subprocess.run(f"ls {path}", shell=True) # INJECTION if path is hostile
subprocess.run(["ls", path]) # safe: no shell, args are a listDefaults to internalise: json over pickle for any external boundary; yaml.safe_load always; ast.literal_eval instead of eval; argument lists instead of shell=True; and validate at the boundary with Pydantic rather than trusting structure.