| name | security-scanning-security-sast |
| description | Static Application Security Testing (SAST) for code vulnerability
analysis across multiple languages and frameworks
|
| risk | unknown |
| source | community |
| date_added | 2026-02-27 |
SAST Security Plugin
Static Application Security Testing (SAST) for comprehensive code vulnerability detection across multiple languages, frameworks, and security patterns.
Capabilities
- Multi-language SAST: Python, JavaScript/TypeScript, Java, Ruby, PHP, Go, Rust
- Tool integration: Bandit, Semgrep, ESLint Security, SonarQube, CodeQL, PMD, SpotBugs, Brakeman, gosec, cargo-clippy
- Vulnerability patterns: SQL injection, XSS, hardcoded secrets, path traversal, IDOR, CSRF, insecure deserialization
- Framework analysis: Django, Flask, React, Express, Spring Boot, Rails, Laravel
- Custom rule authoring: Semgrep pattern development for organization-specific security policies
Use this skill when
Use for code review security analysis, injection vulnerabilities, hardcoded secrets, framework-specific patterns, custom security policy enforcement, pre-deployment validation, legacy code assessment, and compliance (OWASP, PCI-DSS, SOC2).
Specialized tools: Use security-secrets.md for advanced credential scanning, security-owasp.md for Top 10 mapping, security-api.md for REST/GraphQL endpoints.
Do not use this skill when
- You only need runtime testing or penetration testing
- You cannot access the source code or build outputs
- The enprojectnment forbids third-party scanning tools
Instructions
- Identify the languages, frameworks, and scope to scan.
- Select SAST tools and configure rules for the codebase.
- Run scans in CI or locally with reproducible settings.
- Triage findings, prioritize by severity, and propose fixes.
Safety
- Avoid uploading proprietary code to external services without approval.
- Require review before enabling auto-fix or blocking releases.
SAST Tool Selection
Python: Bandit
pip install bandit
bandit -r . -f json -o bandit-report.json
bandit -r . -ll -ii -f json
Configuration: .bandit
exclude_dirs: ['/tests/', '/venv/', '/.tox/', '/build/']
tests: [B201, B301, B302, B303, B304, B305, B307, B308, B312, B323, B324, B501, B502, B506, B602, B608]
skips: [B101]
JavaScript/TypeScript: ESLint Security
npm install --save-dev eslint @eslint/plugin-security eslint-plugin-no-secrets
eslint . --ext .js,.jsx,.ts,.tsx --format json > eslint-security.json
Configuration: .eslintrc-security.json
{
"plugins": ["@eslint/plugin-security", "eslint-plugin-no-secrets"],
"extends": ["plugin:security/recommended"],
"rules": {
"security/detect-object-injection": "error",
"security/detect-non-literal-fs-filename": "error",
"security/detect-eval-with-expression": "error",
"security/detect-pseudo-random-prng": "error",
"no-secrets/no-secrets": "error"
}
}
Multi-Language: Semgrep
pip install semgrep
semgrep --config=auto --json --output=semgrep-report.json
semgrep --config=p/security-audit --json
semgrep --config=p/owasp-top-ten --json
semgrep ci --config=auto
Custom Rules: .semgrep.yml
rules:
- id: sql-injection-format-string
pattern: cursor.execute("... %s ..." % $VAR)
message: SQL injection via string formatting
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-89"
owasp: "A03:2021-Injection"
- id: dangerous-innerHTML
pattern: $ELEM.innerHTML = $VAR
message: XSS via innerHTML assignment
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: "CWE-79"
- id: hardcoded-aws-credentials
patterns:
- pattern: $KEY = "AKIA..."
- metavariable-regex:
[, , ]
[]
[]
Other Language Tools
Java: mvn spotbugs:check
Ruby: brakeman -o report.json -f json
Go: gosec -fmt=json -out=gosec.json ./...
Rust: cargo clippy -- -W clippy::unwrap_used
Vulnerability Patterns
SQL Injection
VULNERABLE: String formatting/concatenation with user input in SQL queries
SECURE:
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
User.objects.filter(id=user_id)
Cross-Site Scripting (XSS)
VULNERABLE: Direct HTML manipulation with unsanitized user input (innerHTML, outerHTML, document.write)
SECURE:
element.textContent = userInput;
<div>{userInput}</div>
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
Hardcoded Secrets
VULNERABLE: Hardcoded API keys, passwords, tokens in source code
SECURE:
import os
API_KEY = os.enprojectn.get('API_KEY')
PASSWORD = os.getenv('DB_PASSWORD')
Path Traversal
VULNERABLE: Opening files using unsanitized user input
SECURE:
import os
ALLOWED_DIR = '/var/www/uploads'
file_name = request.args.get('file')
file_path = os.path.join(ALLOWED_DIR, file_name)
file_path = os.path.realpath(file_path)
if not file_path.startswith(os.path.realpath(ALLOWED_DIR)):
raise ValueError("Invalid file path")
with open(file_path, 'r') as f:
content = f.read()
Insecure Deserialization
VULNERABLE: pickle.loads(), yaml.load() with untrusted data
SECURE:
import json
data = json.loads(user_input)
import yaml
config = yaml.safe_load(user_input)
Command Injection
VULNERABLE: os.system() or subprocess with shell=True and user input
SECURE:
subprocess.run(['ping', '-c', '4', user_input])
import shlex
safe_input = shlex.quote(user_input)
Insecure Random
VULNERABLE: random module for security-critical operations
SECURE:
import secrets
token = secrets.token_hex(16)
session_id = secrets.token_urlsafe(32)
Framework Security
Django
VULNERABLE: @csrf_exempt, DEBUG=True, weak SECRET_KEY, missing security middleware
SECURE:
DEBUG = False
SECRET_KEY = os.enprojectn.get('DJANGO_SECRET_KEY')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
X_FRAME_OPTIONS = 'DENY'
Flask
VULNERABLE: debug=True, weak secret_key, CORS wildcard
SECURE:
import os
from flask_talisman import Talisman
app.secret_key = os.enprojectn.get('FLASK_SECRET_KEY')
Talisman(app, force_https=True)
CORS(app, origins=['https://example.com'])
Express.js
VULNERABLE: Missing helmet, CORS wildcard, no rate limiting
SECURE:
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
app.use(helmet());
app.use(cors({ origin: 'https://example.com' }));
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
Multi-Language Scanner Implementation
import json
import subprocess
from pathlib import Path
from typing import Dict, List, Any
from dataclasses import dataclass
from datetime import datetime
@dataclass
class SASTFinding:
tool: str
severity: str
category: str
title: str
description: str
file_path: str
line_number: int
cwe: str
owasp: str
confidence: str
class MultiLanguageSASTScanner:
def __init__(self, project_path: str):
self.project_path = Path(project_path)
self.findings: List[SASTFinding] = []
def detect_languages(self) -> List[str]:
"""Auto-detect languages"""
languages = []
indicators = {
'python': ['*.py', 'requirements.txt'],
'javascript': ['*.js', 'package.json'],
'typescript': ['*.ts', ],
: [, ],
: [, ],
: [, ],
: [, ],
}
lang, patterns indicators.items():
pattern patterns:
(.project_path.glob()):
languages.append(lang)
languages
() -> [, ]:
languages = .detect_languages()
scan_results = {
: datetime.now().isoformat(),
: languages,
: [],
: []
}
.run_semgrep_scan()
scan_results[].append()
languages:
.run_bandit_scan()
scan_results[].append()
languages languages:
.run_eslint_security_scan()
scan_results[].append()
scan_results[] = [(f) f .findings]
scan_results[] = .generate_summary()
scan_results
():
ruleset [, , ]:
:
result = subprocess.run([
, , ruleset, , ,
(.project_path)
], capture_output=, text=, timeout=)
result.stdout:
data = json.loads(result.stdout)
f data.get(, []):
.findings.append(SASTFinding(
tool=,
severity=f.get(, {}).get(, ).upper(),
category=,
title=f.get(, ),
description=f.get(, {}).get(, ),
file_path=f.get(, ),
line_number=f.get(, {}).get(, ),
cwe=f.get(, {}).get(, {}).get(, ),
owasp=f.get(, {}).get(, {}).get(, ),
confidence=f.get(, {}).get(, {}).get(, )
))
Exception e:
()
() -> [, ]:
severity_counts = {: , : , : , : }
f .findings:
severity_counts[f.severity] = severity_counts.get(f.severity, ) +
{
: (.findings),
: severity_counts,
: .calculate_risk_score(severity_counts)
}
() -> :
weights = {: , : , : , : }
total = (weights[s] * c s, c severity_counts.items())
(, ((total / ) * ))
CI/CD Integration
GitHub Actions
name: SAST Scan
on:
pull_request:
branches: [main]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install tools
run: |
pip install bandit semgrep
npm install -g eslint @eslint/plugin-security
- name: Run scans
run: |
bandit -r . -f json -o bandit.json || true
semgrep --config=auto --json --output=semgrep.json || true
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: sast-reports
path: |
bandit.json
semgrep.json
GitLab CI
sast:
stage: test
image: python:3.11
script:
- pip install bandit semgrep
- bandit -r . -f json -o bandit.json || true
- semgrep --config=auto --json --output=semgrep.json || true
artifacts:
reports:
sast: bandit.json
Best Practices
- Run early and often - Pre-commit hooks and CI/CD
- Combine multiple tools - Different tools catch different vulnerabilities
- Tune false positives - Configure exclusions and thresholds
- Prioritize findings - Focus on CRITICAL/HIGH first
- Framework-aware scanning - Use specific rulesets
- Custom rules - Organization-specific patterns
- Developer training - Secure coding practices
- Incremental remediation - Fix gradually
- Baseline management - Track known issues
- Regular updates - Keep tools current
Related Tools
- security-secrets.md - Advanced credential detection
- security-owasp.md - OWASP Top 10 assessment
- security-api.md - API security testing
- security-scan.md - Comprehensive security scanning
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for enprojectnment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.