Start a security review by searching for a short list of risky calls in each language, then trace where their input comes from. This checklist pairs each pattern with the safer replacement, drawing on the vendor and OWASP documentation linked below.
How to use it
Run the searches, and for each hit ask one question: can any part of this value come from outside the code? That includes requests, files, queues, environment values, archive entries and database fields users can edit. If yes, apply the fix. If no, note why.
Python
pickle.loads,yaml.load(without safe loading: use JSON andyaml.safe_load.subprocesswithshell=True,os.system: pass a list of arguments.randomfor tokens: usesecrets.tarfile.extractall(without a filter: passfilter='data'.
JavaScript and Node.js
eval(andnew Function(: MDN labelsevalan injection sink and says to never use direct eval. PreferJSON.parsefor data and bracket access for dynamic property names.- Deep merge or "set by path" helpers fed request data: guard against
__proto__andconstructorkeys, and useMaporObject.create(null)for lookups. child_processwith string commands: pass an argument array.
Go
text/templatefor HTML: usehtml/template.template.HTML(around dynamic values: remove or sanitize first.math/randfor secrets: usecrypto/rand.filepath.Join(base, name)then open: useos.Rooton Go 1.24 and later.
Java
ObjectInputStream,XMLDecoder,XStream.fromXML: remove, or add allowlist filters.- String built SQL:
PreparedStatementfor values, an allowlist for identifiers.
Rust
unsafeblocks: check for a safety comment, small scope, preconditions in safe code.- Arithmetic on sizes from input: use
checked_*methods, since release builds do not panic on overflow by default.
C# and .NET
BinaryFormatterand related formatters: replace withSystem.Text.Json.FromSqlRaw,ExecuteSqlRaw,SqlQueryRawwith built strings: use the interpolated, parameterizing versions or an allowlist.TypeNameHandlingother thanNonein Json.NET: set toNone.
Across all languages
- Password handling: Argon2id, scrypt or bcrypt, never a plain fast hash. See choosing a password hashing algorithm.
- Secrets in source and logs.
- Dependencies with known advisories that your code reaches.
Turning this into a habit
Put the search list in your pull request template or a CI script that prints hits for reviewers. A search is not a scanner, so it will miss indirect uses and produce some noise. It is still a fast way to focus human attention.
Safeguard covers the dependency side of this list through SBOM and dependency scanning and reachability analysis, so you can see which library advisories your code actually reaches. A free scan is at gold.safeguard.sh/scan.
Quick check
Should every hit be fixed?
No. Fix the ones where outside data can reach the call, and record the reason for the rest.
Can a grep replace a static analysis tool?
No. It is a quick starting point. Use analyzers and tests alongside it.
Sources
- eval(), MDN Web Docs
- Deserialization Cheat Sheet (OWASP)
- Prototype Pollution Prevention Cheat Sheet (OWASP)
- html/template (pkg.go.dev)
- Unsafe Rust (The Rust Book)
Last reviewed: 19 October 2026.