WCAG 2.2 AA compliance, ARIA patterns, keyboard navigation, screen reader optimization
日本語の概要は準備中です。原文の説明を表示しています。
Static Application Security Testing patterns, OWASP Top 10 checklist, language-specific vulnerability patterns, Semgrep rule writing guide, and CI/CD integration. Use when scanning code for security vulnerabilities or writing custom SAST rules.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Comprehensive vulnerability pattern library for static application security testing. Covers OWASP Top 10, language-specific patterns, Semgrep custom rules, and CI/CD pipeline integration.
What to Look For:
Detection Patterns:
// VULNERABLE: No authorization check
app.get('/api/users/:id', async (req, res) => {
const user = await db.users.findById(req.params.id)
res.json(user) // Anyone can access any user
})
// SECURE: Authorization verified
app.get('/api/users/:id', authenticate, async (req, res) => {
if (req.user.id !== req.params.id && !req.user.isAdmin) {
return res.status(403).json({ error: 'Forbidden' })
}
const user = await db.users.findById(req.params.id)
res.json(user)
})
# VULNERABLE: No permission check
@app.route('/admin/delete/<user_id>', methods=['DELETE'])
def delete_user(user_id):
db.session.delete(User.query.get(user_id))
db.session.commit()
# SECURE: Permission verified
@app.route('/admin/delete/<user_id>', methods=['DELETE'])
@login_required
@admin_required
def delete_user(user_id):
db.session.delete(User.query.get(user_id))
db.session.commit()
Semgrep Rules:
rules:
- id: missing-auth-check
patterns:
- pattern: |
app.$METHOD($PATH, async (req, res) => {
...
$DB.$QUERY(...)
...
})
- pattern-not: |
app.$METHOD($PATH, authenticate, ...)
message: "Endpoint missing authentication middleware"
severity: ERROR
What to Look For:
Detection Patterns:
// VULNERABLE: Weak password hashing
const hash = crypto.createHash('md5').update(password).digest('hex')
// SECURE: Strong password hashing
const hash = await bcrypt.hash(password, 12)
# VULNERABLE: Hardcoded secret
SECRET_KEY = "my-super-secret-key-123"
# SECURE: Environment variable
SECRET_KEY = os.environ.get('SECRET_KEY')
if not SECRET_KEY:
raise ValueError("SECRET_KEY environment variable required")
Regex Patterns for Detection:
# API Keys
(?:api[_-]?key|apikey)\s*[:=]\s*['"][A-Za-z0-9_\-]{20,}['"]
# AWS Keys
(?:AKIA|ASIA)[A-Z0-9]{16}
# Generic Secrets
(?:password|passwd|pwd|secret|token)\s*[:=]\s*['"][^'"]{8,}['"]
# Private Keys
-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----
# JWT Tokens
eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+
What to Look For:
Detection Patterns:
// SQL Injection
const query = `SELECT * FROM users WHERE id = ${userId}` // VULNERABLE
const query = 'SELECT * FROM users WHERE id = $1' // SECURE
// Command Injection
exec(`ping ${hostname}`) // VULNERABLE
execFile('ping', [hostname]) // SECURE
// NoSQL Injection (MongoDB)
db.users.find({ email: req.body.email }) // VULNERABLE if email = {"$gt": ""}
db.users.find({ email: String(req.body.email) }) // SECURE: type coercion
# SQL Injection
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") # VULNERABLE
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) # SECURE
# Command Injection
os.system(f"convert {filename} output.png") # VULNERABLE
subprocess.run(['convert', filename, 'output.png'], check=True) # SECURE
// SQL Injection
db.Query("SELECT * FROM users WHERE id = " + userID) // VULNERABLE
db.Query("SELECT * FROM users WHERE id = $1", userID) // SECURE
// Command Injection
exec.Command("sh", "-c", userInput) // VULNERABLE
exec.Command("ping", "-c", "1", hostname) // SECURE
// SQL Injection
stmt.executeQuery("SELECT * FROM users WHERE id = " + id); // VULNERABLE
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
ps.setString(1, id); // SECURE
What to Look For:
Detection Patterns:
// VULNERABLE: No rate limiting on login
app.post('/login', async (req, res) => {
const user = await authenticate(req.body)
res.json({ token: generateToken(user) })
})
// SECURE: Rate limited login
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Too many login attempts'
})
app.post('/login', loginLimiter, async (req, res) => {
const user = await authenticate(req.body)
res.json({ token: generateToken(user) })
})
# VULNERABLE: Race condition in balance check
balance = get_balance(user_id)
if balance >= amount:
withdraw(user_id, amount) # Another request could drain first
# SECURE: Atomic transaction
with db.transaction():
balance = db.query("SELECT balance FROM accounts WHERE id = %s FOR UPDATE", user_id)
if balance >= amount:
db.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", amount, user_id)
What to Look For:
Detection Patterns:
// VULNERABLE: Debug mode
app.set('env', 'development') // In production config
// VULNERABLE: Missing security headers
// No helmet or manual headers
// SECURE: Security headers
import helmet from 'helmet'
app.use(helmet())
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
}
}))
# VULNERABLE: Debug in production
DEBUG = True # In production settings
# VULNERABLE: Default secret key
SECRET_KEY = 'django-insecure-change-me'
# SECURE
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
Security Headers Checklist:
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Detection Commands:
# Node.js
npm audit
npm audit --json
npm outdated
# Python
pip-audit
safety check
pip list --outdated
# Go
go list -m -u all
govulncheck ./...
# Java
mvn dependency-check:check
gradle dependencyCheckAnalyze
# Ruby
bundle audit check
What to Look For:
Detection Patterns:
// VULNERABLE: Plaintext password comparison
if (password === user.password) { /* login */ }
// SECURE: Hashed comparison
const isValid = await bcrypt.compare(password, user.passwordHash)
// VULNERABLE: Weak session management
app.use(session({ secret: 'secret' }))
// SECURE: Strong session
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'strict',
maxAge: 3600000
}
}))
What to Look For:
Detection Patterns:
<!-- VULNERABLE: No SRI -->
<script src="https://cdn.example.com/lib.js"></script>
<!-- SECURE: With SRI -->
<script src="https://cdn.example.com/lib.js"
integrity="sha384-abc123..."
crossorigin="anonymous"></script>
# VULNERABLE: Insecure deserialization
import pickle
data = pickle.loads(user_input)
# SECURE: Use JSON
import json
data = json.loads(user_input)
What to Look For:
Detection Patterns:
// VULNERABLE: No logging
app.post('/login', async (req, res) => {
const user = await authenticate(req.body)
if (!user) return res.status(401).json({ error: 'Invalid' })
res.json({ token: generateToken(user) })
})
// SECURE: Audit logging
app.post('/login', async (req, res) => {
const user = await authenticate(req.body)
if (!user) {
logger.warn('Failed login attempt', {
email: req.body.email,
ip: req.ip,
timestamp: new Date().toISOString()
})
return res.status(401).json({ error: 'Invalid credentials' })
}
logger.info('Successful login', { userId: user.id, ip: req.ip })
res.json({ token: generateToken(user) })
})
// VULNERABLE: Sensitive data in logs
console.log('Login:', { email, password, token })
// SECURE: Redacted logs
console.log('Login:', { email, passwordProvided: !!password })
What to Look For:
Detection Patterns:
// VULNERABLE: SSRF
const response = await fetch(req.query.url)
// SECURE: URL whitelist
const ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com']
const url = new URL(req.query.url)
if (!ALLOWED_DOMAINS.includes(url.hostname)) {
throw new Error('Domain not allowed')
}
// Also block internal IPs
const ip = await dns.resolve(url.hostname)
if (isPrivateIP(ip)) {
throw new Error('Internal addresses not allowed')
}
const response = await fetch(url.toString())
# VULNERABLE: SSRF
response = requests.get(user_url)
# SECURE: URL validation
from urllib.parse import urlparse
parsed = urlparse(user_url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError("Domain not allowed")
if is_private_ip(socket.gethostbyname(parsed.hostname)):
raise ValueError("Internal addresses blocked")
response = requests.get(user_url, allow_redirects=False)
rules:
- id: rule-unique-id
pattern: |
eval($USER_INPUT)
message: "eval() with dynamic input detected - potential RCE"
languages: [javascript, typescript]
severity: ERROR
metadata:
cwe:
- CWE-94
owasp:
- A03:2021
category: security
confidence: HIGH
# pattern: match exactly
- pattern: eval($X)
# pattern-not: exclude matches
- pattern-not: eval("static-string")
# patterns: AND (all must match)
- patterns:
- pattern: $DB.query($SQL)
- pattern-not: $DB.query($SQL, $PARAMS)
# pattern-either: OR (any can match)
- pattern-either:
- pattern: eval($X)
- pattern: new Function($X)
# pattern-inside: match within a context
- pattern-inside: |
app.$METHOD($PATH, (req, res) => {
...
})
# pattern-not-inside: exclude context
- pattern-not-inside: |
app.$METHOD($PATH, authenticate, ...)
# pattern-regex: regex in code
- pattern-regex: "password\s*=\s*['\"][^'\"]{3,}['\"]"
rules:
- id: weak-hash-for-passwords
patterns:
- pattern: crypto.createHash($ALG).update($INPUT)
- metavariable-regex:
metavariable: $ALG
regex: "('md5'|'sha1')"
- metavariable-regex:
metavariable: $INPUT
regex: ".*password.*"
message: "Weak hash algorithm used for password: $ALG"
languages: [javascript, typescript]
severity: ERROR
rules:
- id: sql-injection-taint
mode: taint
pattern-sources:
- pattern: req.body.$PARAM
- pattern: req.query.$PARAM
- pattern: req.params.$PARAM
pattern-sinks:
- pattern: $DB.query($SQL)
pattern-sanitizers:
- pattern: $DB.escape($X)
- pattern: sanitize($X)
message: "User input flows to SQL query without sanitization"
languages: [javascript]
severity: ERROR
rules:
- id: no-hardcoded-secrets
pattern-regex: |
(?:api[_-]?key|secret|password|token)\s*[:=]\s*['"][A-Za-z0-9+/=_\-]{16,}['"]
paths:
exclude:
- "*.test.*"
- "*.spec.*"
- "__tests__/*"
- "*.example"
message: "Potential hardcoded secret detected"
languages: [generic]
severity: ERROR
- id: no-console-log-sensitive
patterns:
- pattern: console.log(..., $DATA, ...)
- metavariable-regex:
metavariable: $DATA
regex: ".*(?:password|secret|token|key|credential).*"
message: "Sensitive data in console.log"
languages: [javascript, typescript]
severity: WARNING
- id: require-input-validation
patterns:
- pattern: |
app.post($PATH, async (req, res) => {
...
$DB.$METHOD(req.body)
...
})
- pattern-not: |
app.post($PATH, async (req, res) => {
...
$SCHEMA.parse(...)
...
})
message: "POST endpoint without input validation"
languages: [javascript, typescript]
severity: WARNING
name: SAST Security Scan
on:
pull_request:
branches: [main, develop]
push:
branches: [main]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep Scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/secrets
p/typescript
generateSarif: "1"
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
if: always()
- name: Dependency Audit
run: npm audit --audit-level=high
- name: Check for Secrets
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified
# .pre-commit-config.yaml
repos:
- repo: https://github.com/semgrep/semgrep
rev: 'v1.60.0'
hooks:
- id: semgrep
args: ['--config', 'auto', '--error', '--severity', 'ERROR']
sast:
stage: test
image: semgrep/semgrep
script:
- semgrep --config auto --config "p/secrets" --json --output gl-sast-report.json .
artifacts:
reports:
sast: gl-sast-report.json
rules:
- if: $CI_MERGE_REQUEST_ID
# Full scan with auto rules
semgrep --config auto .
# OWASP + Secrets
semgrep --config "p/owasp-top-ten" --config "p/secrets" .
# Only errors (for CI gates)
semgrep --config auto --error --severity ERROR .
# JSON output for processing
semgrep --config auto --json --output report.json .
# Scan specific files
semgrep --config auto src/api/ src/auth/
# Diff-aware (only changed code)
semgrep --config auto --baseline-commit origin/main
# Custom rules
semgrep --config .semgrep.yml .
# Exclude test files
semgrep --config auto --exclude="*test*" --exclude="*spec*" .
# With metrics disabled (privacy)
semgrep --config auto --metrics=off .
| Severity | Criteria | Action | SLA |
|---|---|---|---|
| CRITICAL | Exploitable RCE, SQLi, auth bypass, data breach | Fix IMMEDIATELY, block deploy | < 1 hour |
| HIGH | XSS, SSRF, IDOR, missing auth, weak crypto | Fix before production | < 24 hours |
| MEDIUM | Missing validation, verbose errors, weak headers | Fix in current sprint | < 1 week |
| LOW | Debug mode, outdated lib (no known CVE), info leak | Fix in backlog | < 1 month |
Is user input involved?
YES -> Does it reach a dangerous sink (DB, exec, DOM)?
YES -> Is it sanitized/validated?
NO -> CRITICAL (injection)
YES -> Check sanitizer adequacy -> MEDIUM if weak
NO -> MEDIUM (missing validation)
NO -> Is it a configuration issue?
YES -> Affects security posture?
YES -> HIGH (misconfiguration)
NO -> LOW (best practice)
NO -> Is it a dependency issue?
YES -> Known CVE?
YES -> Match CVE severity
NO -> LOW (outdated)
NO -> Informational
Remember: SAST catches patterns, not intent. Always verify findings with manual review. A finding is only a vulnerability if it can be exploited in the application's specific context.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
WCAG 2.2 AA compliance, ARIA patterns, keyboard navigation, screen reader optimization
日本語の概要は準備中です。原文の説明を表示しています。
axe-core integration, WCAG 2.2 AA checklist, keyboard navigation testing, screen reader testing, and ARIA pattern validation.
日本語の概要は準備中です。原文の説明を表示しています。
Steam-style achievement system with XP, levels, streaks, and skill trees. Gamifies the development workflow. 25 achievements across 5 categories.
日本語の概要は準備中です。原文の説明を表示しています。
Framework for measuring and tracking agent response quality over time. Detects regressions before they reach production. Use when evaluating agent changes, auditing quality, or establishing performance baselines.
日本語の概要は準備中です。原文の説明を表示しています。
Agent Context Isolation
日本語の概要は準備中です。原文の説明を表示しています。
Agent ve skill dosyalarinin yapisal dogrulamasi. Frontmatter kontrol, naming convention, zorunlu bolum kontrolu, tutarlilik denetimi. Yeni agent/skill eklendiginde veya mevcut dosyalar duzenlediginde otomatik calistirilir.
日本語の概要は準備中です。原文の説明を表示しています。