Code search is one of the highest-leverage security techniques available, because it lets one person sweep an entire codebase for a dangerous pattern in seconds instead of reading files by hand. When a new CVE drops or a class of bug is discovered in one place, the first question is always "where else do we do this?" Good code search answers that question fast. It is not a replacement for deep review, but as a way to find the obvious problems and scope the non-obvious ones, nothing else has the same return on effort.
Why search beats reading, for this
You cannot manually read a million lines of code looking for a vulnerable pattern. You can search all of it. The insight behind security-oriented code search is that most classes of bug have a textual signature: a dangerous function name, a specific API call, a config key, a hardcoded credential shape. If you can describe the pattern, you can find every instance of it across every repository at once.
This is why incident response leans so heavily on search. When a widely used dependency turns out to be vulnerable, or a bad code pattern is found in one service, search tells you the blast radius before you spend a day investigating manually.
Start with ripgrep and good regex
For a single repository, the workhorse is grep, and specifically ripgrep (rg), which is fast and respects .gitignore. A few practical hunts:
Find potential command-injection sinks in a Node codebase:
rg -n --type js "child_process|exec\(|execSync|spawn"
Find raw SQL string concatenation, a SQL-injection smell:
rg -n "query\(.*\+|SELECT .*\" \+|f\"SELECT" --type py --type js
Find disabled TLS verification, a common insecure-default mistake:
rg -n "verify=False|rejectUnauthorized:\s*false|InsecureSkipVerify"
The skill here is writing a pattern specific enough to cut noise but loose enough to catch variants. Start broad, read the hits, then tighten. rg -n gives line numbers so you can jump straight to context.
Hunting for leaked secrets
One of the most valuable uses of code search is finding credentials committed to source. Secrets in a repo are a direct, high-severity exposure, and they hide in test fixtures, old config files, and commit history.
Search for common secret shapes:
rg -n "AKIA[0-9A-Z]{16}" # AWS access key IDs
rg -n "-----BEGIN (RSA |EC )?PRIVATE KEY" # private keys
rg -n -i "password\s*=\s*['\"][^'\"]{6,}" # hardcoded passwords
Two caveats. First, a secret you find in the working tree may also be in history, so git log -p -S<value> matters for full cleanup, and any exposed secret must be rotated, not just deleted. Second, this manual approach is a starting point; dedicated secret scanners with entropy analysis and hundreds of provider-specific patterns catch far more than ad hoc regex. Use search to understand the problem, then automate it.
Searching across many repositories
Grep works on one checkout. Organizations with dozens or hundreds of repositories need code search that indexes everything: GitHub's code search, Sourcegraph, or a self-hosted indexed search engine. These let you run one query across the whole org and get results ranked and grouped.
This is where code search becomes a security program rather than a personal habit. When an advisory lands for a library, a single org-wide query tells you every service that imports it. When you find a bad pattern in one place, one query tells you everywhere else it appears. The ability to ask "show me every call to this deprecated crypto function across all our code" and get an answer in seconds changes how quickly a team can respond.
Semantic and structural search
Plain text search has a ceiling: it does not understand code structure. Searching for password misses a variable named pw, and a regex for SQL concatenation cannot tell a safe parameterized query from a dangerous one that happens to look similar.
Structural search tools (Semgrep, GitHub's CodeQL, comby) close that gap by matching on the parsed syntax tree instead of raw text. A Semgrep rule can say "find exec() called with a variable that traces back to user input" with far fewer false positives than any regex. This is the bridge from code search into full static analysis (SAST): the same "find the pattern everywhere" mindset, but pattern-matching on meaning rather than strings.
Where code search stops
Search is a discovery tool, not a verdict. It has clear limits:
- It finds patterns, not reasoning. A business-logic authorization flaw has no textual signature. No query finds "this endpoint forgot to check ownership."
- It sees your first-party code, not your dependencies' internals. A vulnerability deep in a transitive package will not show up in a grep of your repo. That is the job of Software Composition Analysis, which reasons about the dependency graph rather than your source text.
- False positives and negatives are inherent. A clean search result means the pattern you looked for is absent, not that the code is secure.
Use code search for what it is unbeatable at: rapidly locating known-bad patterns, scoping incidents, and finding low-hanging fruit like leaked secrets. Then hand the deeper questions to SAST, dependency scanning, and human review. The teams that use it best treat search as the first move in every investigation, not the last word.
FAQ
What is the fastest tool for code search on my machine?
ripgrep (rg) is the standard: it is fast, recursive by default, and respects .gitignore. For structural queries that understand syntax rather than raw text, Semgrep or comby go further than plain regex.
Can code search find security vulnerabilities?
It can find pattern-based ones: dangerous function calls, insecure defaults, and leaked secrets. It cannot find flaws that lack a textual signature, such as broken authorization logic, and it does not see into your dependencies. Pair it with SAST and dependency scanning.
How do I search across many repositories at once?
Use an indexed code search engine such as GitHub code search, Sourcegraph, or a self-hosted equivalent. These index every repo so a single query returns results org-wide, which is essential for scoping the blast radius of a new advisory.
Is grepping for secrets enough to catch leaked credentials?
It is a good start but not sufficient. Dedicated secret scanners use entropy analysis and hundreds of provider-specific patterns, and they check commit history, not just the working tree. Any secret you find must be rotated, since deletion alone does not undo the exposure.