seb1n/static-application-security-testing
Analyze source code for security vulnerabilities using static analysis tools, custom rules, and CI-integrated scanning pipelines.
npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill static-application-security-testing
This skill enables the agent to perform Static Application Security Testing (SAST) on source code repositories to detect security vulnerabilities without executing the application. The agent selects appropriate analysis tools based on the project's language, runs scans with relevant rule sets, triages findings to separate true positives from false positives, and integrates results into CI/CD pipelines. SAST catches issues such as SQL injection, cross-site scripting, hardcoded secrets, insecure deserialization, and cryptographic misuse early in the development lifecycle.
.semgrep.yml, codeql query packs, or .bandit config files.Provide the agent with the path to a source code repository. Optionally specify target languages, custom rule files, or a CI platform for pipeline integration. The agent will run the appropriate SAST tools and deliver a prioritized findings report.
Prompt example:
Run SAST on the Python application in /app using Semgrep and Bandit. Flag any SQL injection, hardcoded secrets, and insecure deserialization. Output results in SARIF format for GitHub Code Scanning.
Command:
semgrep scan --config=p/owasp-top-ten --config=p/python --json --output=semgrep-results.json /app
Findings (excerpt):
┌─────────────────────────────────────────────────────────────────┐
│ python.flask.security.injection.sql-injection-with-format-string │
│ Severity: ERROR │ CWE-89 │ OWASP A03:2021 │
├─────────────────────────────────────────────────────────────────┤
│ /app/routes/users.py:42 │
│ │
│ 40│ def search_users(name): │
│ 41│ query = f"SELECT * FROM users WHERE name = '{name}'"│
│ 42│ result = db.execute(query) │
│ │
│ Fix: Use parameterized queries instead of string formatting. │
├─────────────────────────────────────────────────────────────────┤
│ python.lang.security.audit.hardcoded-password │
│ Severity: WARNING │ CWE-798 │ OWASP A07:2021 │
├─────────────────────────────────────────────────────────────────┤
│ /app/config.py:11 │
│ │
│ 10│ class Config: │
│ 11│ DB_PASSWORD = "SuperSecret123!" │
│ 12│ JWT_SECRET = "my-jwt-secret" │
│ │
│ Fix: Load secrets from environment variables or a secrets │
│ manager, never hardcode them in source files. │
└─────────────────────────────────────────────────────────────────┘
Fixed code for the SQL injection finding:
# BEFORE — vulnerable to SQL injection
def search_users(name):
query = f"SELECT * FROM users WHERE name = '{name}'"
result = db.execute(query)
return result
# AFTER — parameterized query
def search_users(name):
query = "SELECT * FROM users WHERE name = :name"
result = db.execute(text(query), {"name": name})
return result
Custom CodeQL query (insecure-deserialization.ql):
/**
* @name Insecure deserialization of untrusted data
* @description Deserializing data from an untrusted source without validation
* can lead to remote code execution.
* @kind path-problem
* @problem.severity error
* @id java/insecure-deserialization
* @tags security
* cwe-502
* owasp-a08
*/
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.UnsafeDeserializationQuery
from UnsafeDeserializationConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"Untrusted data from $@ is deserialized here without validation.", source.getNode(),
"user-controlled input"
Running the query:
codeql database create java-db --language=java --source-root=/app
codeql database analyze java-db insecure-deserialization.ql --format=sarif-latest --output=codeql-results.sarif
Sample finding:
/app/src/main/java/com/example/api/ImportController.java:35
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object obj = ois.readObject(); // CWE-502: untrusted deserialization
Fix: Replace ObjectInputStream with a safe alternative like JSON deserialization
with explicit type binding, or use an allowlist-based ObjectInputFilter.
p/owasp-top-ten) rather than enabling all rules. Add suppressions for confirmed false positives with documented justification..semgrepignore or CodeQL path filters to avoid noise.Take seb1n/static-application-security-testing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.