This guide explains how to run CodeQL security analysis locally to detect vulnerabilities like the remote property injection issue we fixed.
chmod +x scripts/setup-codeql.sh
./scripts/setup-codeql.shThis will:
- Download CodeQL CLI for your platform (macOS ARM64/Intel, Linux)
- Install CodeQL query packs
- Set everything up in
/tmp/codeql
chmod +x scripts/run-codeql-analysis.sh
./scripts/run-codeql-analysis.shThis will:
- Create a CodeQL database from your codebase
- Run security and quality checks
- Generate reports in multiple formats
Results are saved in ./codeql-results/:
security-analysis.sarif- Full SARIF format (upload to GitHub or view in VS Code)remote-property-injection.csv- CSV format for spreadsheet analysisanalysis-report.txt- Human-readable text report
Remote property injection (also known as prototype pollution) occurs when:
- User-controlled data is used as property names
- Properties are assigned without validation
- Attackers can inject special properties like
__proto__,constructor, orprototype
// VULNERABLE CODE
for (const [key, value] of Object.entries(payload.envUpdates)) {
environmentUpdates[key] = String(value); // ❌ Dangerous!
}An attacker could send:
{
"envUpdates": {
"__proto__": "malicious",
"constructor": { "polluted": true }
}
}// SECURE CODE
for (const [key, value] of Object.entries(payload.envUpdates)) {
// Validate property names
if (
key === '__proto__' ||
key === 'constructor' ||
key === 'prototype' ||
!Object.prototype.hasOwnProperty.call(payload.envUpdates, key)
) {
safeLog(`Warning: Skipping dangerous property name: ${key}`);
continue;
}
// Use safe assignment
Object.defineProperty(environmentUpdates, key, {
value: String(value),
writable: true,
enumerable: true,
configurable: true,
});
}If you prefer to run commands manually:
/tmp/codeql/codeql database create /tmp/codeql-db \
--language=javascript-typescript \
--source-root=.# Security and quality analysis
/tmp/codeql/codeql database analyze /tmp/codeql-db \
--format=sarif-latest \
--output=results.sarif \
--download \
javascript-typescript-security-and-quality.qls# Check for remote property injection specifically
/tmp/codeql/codeql database analyze /tmp/codeql-db \
--format=text \
--download \
javascript-typescript-security-extended.qls \
| grep -A 10 "remote-property-injection"- Install the SARIF Viewer extension
- Open
codeql-results/security-analysis.sarif - View results with inline code highlighting
For advanced analysis:
- Install CodeQL extension
- Open CodeQL databases directly
- Write custom queries
# Using GitHub CLI
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/OWNER/REPO/code-scanning/sarifs \
-f sarif=@codeql-results/security-analysis.sarif \
-f ref=refs/heads/main \
-f commit_sha=$(git rev-parse HEAD)The existing workflow at .github/workflows/codeql.yml runs automatically on:
- Every push to
main - Every pull request
- Weekly (Sundays at midnight UTC)
Solution: Run ./scripts/setup-codeql.sh first
Solution: Ensure you're in the project root and have write access to /tmp
Solution: This is good! It means no vulnerabilities were detected.
Solution: CodeQL analysis can be slow on large codebases. Consider:
- Running only security queries (not quality)
- Analyzing specific directories
- Using
--threadsflag to parallelize
CodeQL provides different query suites:
security-and-quality- Comprehensive (recommended)security-extended- All security queriessecurity-experimental- Experimental security checkscode-scanning- GitHub Code Scanning default queries
You can write custom CodeQL queries in .ql files:
/**
* @name Custom property injection check
* @kind problem
* @id js/custom-property-injection
*/
import javascript
from PropertyWriteNode write, DataFlow::Node source
where
// Your custom logic here
source.flowsTo(write.getPropertyNameExpr().flow())
select write, "Potential property injection from $@.", source, "user input"To remove CodeQL installation:
rm -rf /tmp/codeql /tmp/codeql-queries /tmp/codeql-db
rm -rf ./codeql-resultsFor issues with:
- CodeQL setup: Check CodeQL CLI releases
- False positives: Review the query logic and consider suppression
- Custom queries: Consult CodeQL query cookbook