Safeguard
Security Guides•

Secure code review checklist: dangerous calls by language

A grep friendly checklist of risky calls to search for in Python, JavaScript, Go, Java, Rust and C#, with the safer replacement for each in code review.

Safeguard Security Team
3 min read

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 and yaml.safe_load.
  • subprocess with shell=True, os.system: pass a list of arguments.
  • random for tokens: use secrets.
  • tarfile.extractall( without a filter: pass filter='data'.

JavaScript and Node.js

  • eval( and new Function(: MDN labels eval an injection sink and says to never use direct eval. Prefer JSON.parse for data and bracket access for dynamic property names.
  • Deep merge or "set by path" helpers fed request data: guard against __proto__ and constructor keys, and use Map or Object.create(null) for lookups.
  • child_process with string commands: pass an argument array.

Go

  • text/template for HTML: use html/template.
  • template.HTML( around dynamic values: remove or sanitize first.
  • math/rand for secrets: use crypto/rand.
  • filepath.Join(base, name) then open: use os.Root on Go 1.24 and later.

Java

  • ObjectInputStream, XMLDecoder, XStream.fromXML: remove, or add allowlist filters.
  • String built SQL: PreparedStatement for values, an allowlist for identifiers.

Rust

  • unsafe blocks: 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

  • BinaryFormatter and related formatters: replace with System.Text.Json.
  • FromSqlRaw, ExecuteSqlRaw, SqlQueryRaw with built strings: use the interpolated, parameterizing versions or an allowlist.
  • TypeNameHandling other than None in Json.NET: set to None.

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

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.