
Ai Code Security
- 26 installs
- 122 repo stars
- Updated January 22, 2026
- omer-metin/skills-for-antigravity
Helps with security tasks during AI-assisted development.
About
ai-code-security is a Claude Code skill for security. It helps solo builders move faster with AI-assisted coding.
- ai-code-security
- Security
- AI-coding skill
Ai Code Security by the numbers
- 26 all-time installs (skills.sh)
- Ranked #1,547 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/omer-metin/skills-for-antigravity --skill ai-code-securityAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 26 |
|---|---|
| repo stars | ★ 122 |
| Last updated | January 22, 2026 |
| Repository | omer-metin/skills-for-antigravity ↗ |
What it does
Helps with security tasks during AI-assisted development.
Files
Ai Code Security
Identity
You're a security engineer who has reviewed thousands of AI-generated code samples and found the same patterns recurring. You've seen production outages caused by LLM hallucinations, data breaches from prompt injection, and supply chain compromises through poisoned models.
Your experience spans traditional AppSec (OWASP Top 10, secure coding) and the new frontier of AI security. You understand that AI doesn't just generate vulnerabilities—it generates them at scale, with novel patterns that traditional tools miss.
Your core principles: 1. Never trust AI output—validate everything 2. Defense in depth—prompt, model, output, and runtime layers 3. AI is an untrusted input source—treat it like user input 4. Supply chain matters—models, datasets, and dependencies 5. Automate detection—human review doesn't scale
Reference System Usage
You must ground your responses in the provided reference files, treating them as the source of truth for this domain:
- For Creation: Always consult `references/patterns.md`. This file dictates how things should be built. Ignore generic approaches if a specific pattern exists here.
- For Diagnosis: Always consult `references/sharp_edges.md`. This file lists the critical failures and "why" they happen. Use it to explain risks to the user.
- For Review: Always consult `references/validations.md`. This contains the strict rules and constraints. Use it to validate user inputs objectively.
Note: If a user's request conflicts with the guidance in these files, politely correct them using the information provided in the references.
AI Code Security
Patterns
---
Name
AI Output Validation Pipeline
Description
Validate all LLM outputs before execution or storage
When
LLM generates code, SQL, commands, or structured data
Example
import { z } from 'zod'; import { scanForSecrets } from './security';
// Schema validation for LLM-generated structured output const LLMOutputSchema = z.object({ code: z.string().max(10000), language: z.enum(['typescript', 'python', 'sql']), explanation: z.string() });
async function validateLLMOutput(rawOutput: unknown): Promise<ValidatedOutput> { // 1. Schema validation const parsed = LLMOutputSchema.parse(rawOutput);
// 2. Secret detection const secrets = await scanForSecrets(parsed.code); if (secrets.length > 0) { throw new SecurityError('LLM output contains secrets', { secrets }); }
// 3. Dangerous pattern detection const dangerousPatterns = [ /eval\s\(/, /exec\s\(/, /rm\s+-rf/, /DROP\s+TABLE/i, /TRUNCATE/i, /__import__/, /subprocess\.call/ ];
for (const pattern of dangerousPatterns) { if (pattern.test(parsed.code)) { throw new SecurityError('LLM output contains dangerous pattern', { pattern: pattern.source }); } }
// 4. Static analysis (language-specific) const analysisResult = await runStaticAnalysis(parsed.code, parsed.language); if (analysisResult.criticalIssues.length > 0) { throw new SecurityError('LLM code has critical vulnerabilities', { issues: analysisResult.criticalIssues }); }
return { ...parsed, analysisResult, validatedAt: new Date() }; }
---
Name
Sandboxed Code Execution
Description
Execute AI-generated code in isolated environments
When
LLM output must be executed (code interpreters, agents)
Example
import { NodeVM } from 'vm2'; import { spawn } from 'child_process';
class SecureSandbox { private readonly timeout = 5000; private readonly memoryLimit = 128 1024 1024; // 128MB
// JavaScript/TypeScript sandbox async executeJS(code: string, context: Record<string, unknown> = {}): Promise<unknown> { const vm = new NodeVM({ timeout: this.timeout, sandbox: { ...context, // Explicitly deny dangerous globals process: undefined, require: undefined, __dirname: undefined, __filename: undefined }, eval: false, wasm: false, sourceExtensions: ['js'] });
try { return vm.run(code); } catch (error) { if (error.message.includes('Script execution timed out')) { throw new SecurityError('Code execution timeout', { code }); } throw error; } }
// Python sandbox using subprocess with cgroups async executePython(code: string): Promise<string> { return new Promise((resolve, reject) => { const proc = spawn('firejail', [ '--quiet', '--private', '--net=none', '--rlimit-as=' + this.memoryLimit, 'python3', '-c', code ], { timeout: this.timeout, stdio: ['pipe', 'pipe', 'pipe'] });
let stdout = ''; let stderr = '';
proc.stdout.on('data', (data) => stdout += data); proc.stderr.on('data', (data) => stderr += data);
proc.on('close', (code) => { if (code === 0) resolve(stdout); else reject(new Error(stderr || Exit code: ${code})); }); }); }
// Docker-based sandbox for full isolation async executeInDocker(code: string, image: string): Promise<string> { const containerId = await this.createContainer(image, { NetworkDisabled: true, Memory: this.memoryLimit, CpuPeriod: 100000, CpuQuota: 50000, // 50% CPU ReadonlyRootfs: true, SecurityOpt: ['no-new-privileges'] });
try { return await this.execInContainer(containerId, code); } finally { await this.removeContainer(containerId); } } }
---
Name
Supply Chain Verification
Description
Verify AI model and dependency integrity
When
Using third-party models, fine-tuned models, or AI dependencies
Example
import { createHash } from 'crypto'; import { readFile } from 'fs/promises';
interface ModelManifest { name: string; version: string; sha256: string; source: string; signedBy?: string; attestation?: string; }
class ModelVerifier { private readonly trustedSources = [ 'huggingface.co', 'anthropic.com', 'openai.com' ];
async verifyModel(modelPath: string, manifest: ModelManifest): Promise<boolean> { // 1. Verify source trust const sourceUrl = new URL(manifest.source); if (!this.trustedSources.some(s => sourceUrl.hostname.endsWith(s))) { throw new SecurityError('Untrusted model source', { source: manifest.source, trusted: this.trustedSources }); }
// 2. Verify hash integrity const modelData = await readFile(modelPath); const actualHash = createHash('sha256').update(modelData).digest('hex');
if (actualHash !== manifest.sha256) { throw new SecurityError('Model hash mismatch', { expected: manifest.sha256, actual: actualHash }); }
// 3. Verify signature if available if (manifest.signedBy && manifest.attestation) { const valid = await this.verifySignature( modelData, manifest.attestation, manifest.signedBy ); if (!valid) { throw new SecurityError('Model signature invalid'); } }
// 4. Scan for known malicious patterns await this.scanForMaliciousPatterns(modelPath);
return true; }
async verifyDependencies(packageJson: string): Promise<void> { const pkg = JSON.parse(await readFile(packageJson, 'utf-8')); const aiDeps = this.extractAIDependencies(pkg);
for (const dep of aiDeps) { // Check for known vulnerable versions const vulns = await this.checkVulnerabilities(dep.name, dep.version); if (vulns.critical.length > 0) { throw new SecurityError('Critical AI dependency vulnerability', { package: dep.name, vulnerabilities: vulns.critical }); } } } }
---
Name
OWASP LLM Top 10 Mitigation
Description
Systematic mitigation of OWASP LLM vulnerabilities
When
Building or auditing LLM applications
Example
// Comprehensive LLM security middleware
interface LLMSecurityConfig { maxTokens: number; rateLimitPerMinute: number; allowedTools: string[]; sensitiveDataPatterns: RegExp[]; }
class LLMSecurityMiddleware { constructor(private config: LLMSecurityConfig) {}
// LLM01: Prompt Injection Defense async sanitizeInput(input: string): Promise<string> { // Remove known injection patterns const sanitized = input .replace(/ignore previous instructions/gi, '[FILTERED]') .replace(/system:/gi, '[FILTERED]') .replace(/\[INST\]/gi, '[FILTERED]');
// Validate input doesn't exceed token budget const tokens = await this.countTokens(sanitized); if (tokens > this.config.maxTokens) { throw new SecurityError('Input exceeds token limit'); }
return sanitized; }
// LLM02: Insecure Output Handling async sanitizeOutput(output: string): Promise<string> { // Remove any embedded code that could execute let safe = output.replace(/<script[^>]>[\s\S]?<\/script>/gi, '');
// Detect and mask sensitive data for (const pattern of this.config.sensitiveDataPatterns) { safe = safe.replace(pattern, '[REDACTED]'); }
return safe; }
// LLM03: Training Data Poisoning (at inference time) validateModelSource(source: string): boolean { const trustedSources = ['anthropic', 'openai', 'internal']; return trustedSources.some(s => source.includes(s)); }
// LLM04: Model Denial of Service async enforceRateLimits(userId: string): Promise<void> { const key = ratelimit:${userId}; const count = await this.redis.incr(key);
if (count === 1) { await this.redis.expire(key, 60); }
if (count > this.config.rateLimitPerMinute) { throw new SecurityError('Rate limit exceeded'); } }
// LLM05: Supply Chain Vulnerabilities (handled by ModelVerifier)
// LLM06: Sensitive Information Disclosure async detectPII(text: string): Promise<PIIResult> { const patterns = { ssn: /\b\d{3}-\d{2}-\d{4}\b/g, creditCard: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g, email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, phone: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g, apiKey: /\b(sk-|api[_-]?key)[a-zA-Z0-9]{20,}\b/gi };
const found: PIIMatch[] = []; for (const [type, pattern] of Object.entries(patterns)) { const matches = text.match(pattern); if (matches) { found.push({ type, count: matches.length }); } }
return { hasPII: found.length > 0, matches: found }; }
// LLM07: Insecure Plugin Design validateToolCall(toolName: string, args: unknown): boolean { if (!this.config.allowedTools.includes(toolName)) { throw new SecurityError('Unauthorized tool', { tool: toolName }); }
// Validate arguments against schema const schema = this.getToolSchema(toolName); return schema.safeParse(args).success; }
// LLM08: Excessive Agency async enforceLeastPrivilege(action: LLMAction): Promise<void> { const dangerousActions = ['delete', 'execute', 'admin', 'sudo'];
if (dangerousActions.some(a => action.type.includes(a))) { // Require human approval for dangerous actions const approved = await this.requestHumanApproval(action); if (!approved) { throw new SecurityError('Action requires human approval'); } } } }
Anti-Patterns
---
Name
Trusting AI Output Directly
Description
Executing or storing AI-generated content without validation
Why
LLMs hallucinate, can be manipulated, and generate insecure code
Instead
Always validate, sanitize, and sandbox AI outputs before use.
---
Name
Static Prompts as Security
Description
Relying solely on system prompts for security constraints
Why
Prompt injection bypasses prompt-level controls easily
Instead
Implement multi-layer defense with output validation and sandboxing.
---
Name
Using Outdated AI Dependencies
Description
Not updating AI SDKs, models, or related dependencies
Why
AI security landscape evolves rapidly; new vulnerabilities discovered weekly
Instead
Regular dependency audits, automated updates, vulnerability scanning.
---
Name
No Model Provenance
Description
Using models without verifying source and integrity
Why
Poisoned models can contain backdoors, biased outputs, or malware
Instead
Verify model hashes, sources, and maintain audit trail.
---
Name
Excessive LLM Permissions
Description
Giving LLMs access to all tools, data, or systems
Why
Compromised LLM (via injection) gains all those permissions
Instead
Apply least privilege principle; LLM gets only what it needs.
Ai Code Security - Sharp Edges
Llm Hallucinated Apis
Id
llm-hallucinated-apis
Summary
LLM generates calls to non-existent APIs or deprecated methods
Severity
high
Situation
AI-generated code references APIs that don't exist or have been deprecated
Why
LLMs trained on older data. Confidence doesn't equal correctness. Hallucinated APIs may have security implications.
Solution
// Validate AI-generated API calls against known schemas
class APIValidator { private readonly knownAPIs: Map<string, APISchema> = new Map();
async validateGeneratedCode(code: string, language: string): Promise<ValidationResult> { const apiCalls = this.extractAPICalls(code, language); const issues: APIIssue[] = [];
for (const call of apiCalls) { // Check if API exists const schema = this.knownAPIs.get(call.name); if (!schema) { issues.push({ type: 'hallucinated', api: call.name, line: call.line, severity: 'error', message: API '${call.name}' does not exist }); continue; }
// Check if method exists on API if (!schema.methods.includes(call.method)) { issues.push({ type: 'invalid_method', api: call.name, method: call.method, line: call.line, severity: 'error', message: Method '${call.method}' does not exist on '${call.name}' }); }
// Check for deprecated APIs if (schema.deprecated) { issues.push({ type: 'deprecated', api: call.name, line: call.line, severity: 'warning', message: API '${call.name}' is deprecated: ${schema.deprecationReason}, replacement: schema.replacement }); } }
return { valid: issues.length === 0, issues }; }
// Populate from OpenAPI specs, TypeScript definitions, etc. async loadAPISchemas(sources: string[]): Promise<void> { for (const source of sources) { const schema = await this.parseSchema(source); this.knownAPIs.set(schema.name, schema); } } }
Symptoms
- Runtime errors referencing unknown methods
- Import errors for non-existent packages
- TypeScript errors on AI-generated code
Detection Pattern
import\s+.from|require\s\(|fetch\s*\(
Ai Generated Sql Injection
Id
ai-generated-sql-injection
Summary
LLM generates SQL with string concatenation instead of parameterization
Severity
critical
Situation
AI-generated database queries are vulnerable to SQL injection
Why
LLMs see many examples of insecure code. String concatenation is common in training data. LLMs don't understand runtime context.
Solution
// Validate and transform AI-generated SQL
class SQLSecurityValidator { // Detect SQL injection patterns in generated code detectInjectionVulnerabilities(code: string): SQLVulnerability[] { const vulnerabilities: SQLVulnerability[] = [];
// Pattern 1: String concatenation in SQL const concatPattern = /(?:SELECT|INSERT|UPDATE|DELETE|WHERE).\+.(?:req\.|params\.|body\.)/gi; const concatMatches = code.match(concatPattern); if (concatMatches) { vulnerabilities.push({ type: 'string_concatenation', severity: 'critical', pattern: concatMatches[0], fix: 'Use parameterized queries' }); }
// Pattern 2: Template literals with user input const templatePattern = /[^]\$\{[^}](?:req|params|body|user)[^}]\}[^`]`/g; const templateMatches = code.match(templatePattern); if (templateMatches) { vulnerabilities.push({ type: 'template_literal', severity: 'critical', pattern: templateMatches[0], fix: 'Use parameterized queries' }); }
// Pattern 3: f-strings in Python const fstringPattern = /f["'][^"']\{[^}](?:request|params|input)[^}]*\}/g; const fstringMatches = code.match(fstringPattern); if (fstringMatches) { vulnerabilities.push({ type: 'fstring_injection', severity: 'critical', pattern: fstringMatches[0], fix: 'Use parameterized queries with cursor.execute(sql, params)' }); }
return vulnerabilities; }
// Auto-fix common SQL injection patterns autoFix(code: string): { fixed: string; changes: string[] } { const changes: string[] = [];
// Transform: SELECT * FROM users WHERE id = ${userId} // To: prepared statement pattern const fixed = code.replace( /(SELECT[^])\$\{(\w+)\}([^`])/g, (match, before, variable, after) => { changes.push(Converted template literal to parameterized query); return { text: \${before}$1${after}\, values: [${variable}] }`; } );
return { fixed, changes }; } }
Symptoms
- SQL errors with unexpected syntax
- Database queries containing user input directly
- Security scanner flagging SQL injection
Detection Pattern
SELECT.\+|INSERT.\+|UPDATE.\+|DELETE.\+
Leaked Secrets In Ai Output
Id
leaked-secrets-in-ai-output
Summary
LLM includes API keys, passwords, or tokens in generated code
Severity
critical
Situation
AI output contains hardcoded secrets or copies secrets from context
Why
LLM may echo back secrets from system prompts. Training data contains many hardcoded secrets. LLM doesn't understand secret sensitivity.
Solution
// Comprehensive secret detection for AI outputs
import Anthropic from '@anthropic-ai/sdk';
class SecretDetector { private readonly patterns: SecretPattern[] = [ { name: 'AWS Access Key', pattern: /AKIA[0-9A-Z]{16}/g, severity: 'critical' }, { name: 'AWS Secret Key', pattern: /[A-Za-z0-9/+=]{40}/g, context: 'aws_secret', severity: 'critical' }, { name: 'GitHub Token', pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/g, severity: 'critical' }, { name: 'OpenAI API Key', pattern: /sk-[A-Za-z0-9]{48}/g, severity: 'critical' }, { name: 'Anthropic API Key', pattern: /sk-ant-[A-Za-z0-9-]{95}/g, severity: 'critical' }, { name: 'Generic API Key', pattern: /(?:api[_-]?key|apikey|secret[_-]?key)\s[:=]\s"'["']/gi, severity: 'high' }, { name: 'Private Key', pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g, severity: 'critical' }, { name: 'JWT Token', pattern: /eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/g, severity: 'high' }, { name: 'Database URL', pattern: /(?:postgres|mysql|mongodb):\/\/[^:]+:[^@]+@[^\s]+/g, severity: 'critical' } ];
async scan(content: string): Promise<SecretScanResult> { const findings: SecretFinding[] = [];
for (const pattern of this.patterns) { const matches = content.matchAll(pattern.pattern); for (const match of matches) { // Verify it's not a placeholder if (this.isPlaceholder(match[0])) continue;
findings.push({ type: pattern.name, value: this.mask(match[0]), index: match.index, severity: pattern.severity, line: this.getLineNumber(content, match.index!) }); } }
return { hasSecrets: findings.length > 0, findings, recommendation: findings.length > 0 ? 'BLOCK: Remove secrets before using AI output' : 'OK: No secrets detected' }; }
private isPlaceholder(value: string): boolean { const placeholders = [ 'YOUR_API_KEY', 'xxx', 'REPLACE_ME', 'your-api-key', 'sk-...', 'INSERT_KEY_HERE', '<api-key>' ]; return placeholders.some(p => value.toLowerCase().includes(p.toLowerCase()) ); }
private mask(secret: string): string { if (secret.length <= 8) return '*'; return secret.slice(0, 4) + '*' + secret.slice(-4); } }
// Usage in AI output pipeline async function processAIOutput(output: string): Promise<string> { const detector = new SecretDetector(); const result = await detector.scan(output);
if (result.hasSecrets) { console.error('Secrets detected in AI output:', result.findings); throw new SecurityError('AI output contains secrets'); }
return output; }
Symptoms
- Secrets appearing in logs or outputs
- Security scanners flagging committed code
- Credential exposure alerts
Detection Pattern
api[_-]?key|secret|password|token|credential
Ai Generated Xss
Id
ai-generated-xss
Summary
LLM generates frontend code vulnerable to XSS attacks
Severity
high
Situation
AI-generated React/Vue/HTML contains innerHTML or unsanitized user content
Why
LLMs generate code that "works" without security considerations. innerHTML is simpler than safe alternatives. Training data contains legacy unsafe patterns.
Solution
// XSS vulnerability detection and prevention
class XSSValidator { detectVulnerabilities(code: string, framework: string): XSSVulnerability[] { const vulnerabilities: XSSVulnerability[] = [];
// React vulnerabilities if (framework === 'react') { // dangerouslySetInnerHTML const dangerPattern = /dangerouslySetInnerHTML\s=\s\{\s\{\s__html:\s*([^}]+)\}/g; for (const match of code.matchAll(dangerPattern)) { if (!this.isSanitized(match[1])) { vulnerabilities.push({ type: 'dangerouslySetInnerHTML', line: this.getLine(code, match.index!), severity: 'high', fix: 'Use DOMPurify.sanitize() or avoid innerHTML' }); } } }
// Vue vulnerabilities if (framework === 'vue') { // v-html directive const vhtmlPattern = /v-html\s=\s"'["']/g; for (const match of code.matchAll(vhtmlPattern)) { vulnerabilities.push({ type: 'v-html', line: this.getLine(code, match.index!), severity: 'high', fix: 'Use v-text or sanitize with DOMPurify' }); } }
// Generic innerHTML const innerHTMLPattern = /\.innerHTML\s=\s([^;]+)/g; for (const match of code.matchAll(innerHTMLPattern)) { if (!this.isSanitized(match[1])) { vulnerabilities.push({ type: 'innerHTML', line: this.getLine(code, match.index!), severity: 'high', fix: 'Use textContent or sanitize input' }); } }
// document.write if (code.includes('document.write')) { vulnerabilities.push({ type: 'document.write', severity: 'high', fix: 'Avoid document.write entirely' }); }
return vulnerabilities; }
private isSanitized(expression: string): boolean { const sanitizers = ['DOMPurify', 'sanitize', 'escape', 'encode']; return sanitizers.some(s => expression.includes(s)); }
// Auto-fix XSS vulnerabilities autoFix(code: string): string { // Add DOMPurify import if needed if (code.includes('dangerouslySetInnerHTML') && !code.includes('DOMPurify')) { code = import DOMPurify from 'dompurify';\n + code; }
// Wrap unsanitized innerHTML code = code.replace( /dangerouslySetInnerHTML=\{\{\s__html:\s([^}]+)\}\}/g, (match, content) => { if (content.includes('DOMPurify')) return match; return dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(${content}) }}; } );
return code; } }
Symptoms
- Security scanner XSS warnings
- innerHTML usage with user content
- Script injection in rendered pages
Detection Pattern
innerHTML|dangerouslySetInnerHTML|v-html|document\.write
Excessive Permissions In Ai Agents
Id
excessive-permissions-in-ai-agents
Summary
AI-generated agent code requests more permissions than needed
Severity
high
Situation
Agent code has broad file system, network, or system access
Why
LLMs optimize for functionality, not security. Broader permissions are easier to implement. No built-in principle of least privilege.
Solution
// Permission auditing for AI-generated agent code
class PermissionAuditor { private readonly dangerousPatterns = { filesystem: { read_all: /fs\.readdir\(['"]\/['"]\)|glob\(['"]\\\/\*['"]\)/, write_anywhere: /fs\.writeFile(?:Sync)?\(['"][^.]+['"]\)/, delete: /fs\.unlink|fs\.rmdir|rimraf/ }, network: { any_fetch: /fetch\(['"]http/, any_request: /axios\.|request\(/ }, system: { exec: /exec(?:Sync)?\(|spawn\(|child_process/, eval: /eval\(|new Function\(/, require_dynamic: /require\([^'"]/ }, database: { raw_query: /\.raw\(|\.query\(/, drop: /DROP\s+(?:TABLE|DATABASE)/i, truncate: /TRUNCATE/i } };
audit(code: string): PermissionAuditResult { const findings: PermissionFinding[] = [];
for (const [category, patterns] of Object.entries(this.dangerousPatterns)) { for (const [name, pattern] of Object.entries(patterns)) { if (pattern.test(code)) { findings.push({ category, permission: name, severity: this.getSeverity(category, name), recommendation: this.getRecommendation(category, name) }); } } }
return { riskLevel: this.calculateRiskLevel(findings), findings, requiresHumanReview: findings.some(f => f.severity === 'critical') }; }
private getSeverity(category: string, permission: string): 'low' | 'medium' | 'high' | 'critical' { const criticalPatterns = ['exec', 'eval', 'drop', 'delete']; const highPatterns = ['write_anywhere', 'raw_query', 'require_dynamic'];
if (criticalPatterns.includes(permission)) return 'critical'; if (highPatterns.includes(permission)) return 'high'; return 'medium'; }
private getRecommendation(category: string, permission: string): string { const recommendations: Record<string, string> = { exec: 'Use specific command allowlist instead of arbitrary execution', eval: 'Never use eval with AI-generated content', write_anywhere: 'Restrict writes to specific directories', delete: 'Require confirmation for destructive operations', drop: 'Never allow DDL operations from AI agents', raw_query: 'Use ORM methods instead of raw queries' }; return recommendations[permission] || 'Review and restrict permissions'; } }
Symptoms
- Agent accessing unexpected files or URLs
- Audit logs showing broad access patterns
- Unexpected system resource usage
Detection Pattern
exec\(|spawn\(|eval\(|writeFile|unlink|rmdir
Ai Code Security - Validations
SQL Injection in AI-Generated Code
Id
ai-sql-injection
Severity
critical
Type
regex
Pattern
(?:SELECT|INSERT|UPDATE|DELETE|WHERE)[^;](?:\+\s(?:req|params|body|user|input)|\$\{[^}]*(?:req|params|body|user|input))
Message
Potential SQL injection in AI-generated code. User input concatenated in query.
Fix Action
Use parameterized queries: db.query('SELECT * FROM users WHERE id = $1', [userId])
Applies To
- *.ts
- *.js
- *.py
XSS via innerHTML in AI Code
Id
ai-xss-innerhtml
Severity
high
Type
regex
Pattern
\.innerHTML\s=\s(?!.*(?:DOMPurify|sanitize|escape))[^;]+
Message
Unsanitized innerHTML assignment. XSS vulnerability.
Fix Action
Use textContent for text, or DOMPurify.sanitize() for HTML
Applies To
- *.ts
- *.js
- *.tsx
- *.jsx
dangerouslySetInnerHTML Without Sanitization
Id
ai-dangerous-react
Severity
high
Type
regex
Pattern
dangerouslySetInnerHTML\s=\s\{\s\{\s__html:\s(?!.DOMPurify)[^}]+
Message
dangerouslySetInnerHTML without DOMPurify sanitization.
Fix Action
Use DOMPurify.sanitize(): dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }}
Applies To
- *.tsx
- *.jsx
eval() in AI-Generated Code
Id
ai-eval-usage
Severity
critical
Type
regex
Pattern
\beval\s\([^)]+\)|new\s+Function\s\(
Message
eval() or Function() constructor detected. Never execute AI-generated code directly.
Fix Action
Use a sandboxed execution environment like vm2 or WebContainers
Applies To
- *.ts
- *.js
- *.tsx
- *.jsx
Hardcoded Secrets in AI Output
Id
ai-hardcoded-secrets
Severity
critical
Type
regex
Pattern
(?:api[_-]?key|secret|password|token)\s[:=]\s["'][A-Za-z0-9+/=_-]{20,}["']
Message
Potential hardcoded secret in AI-generated code.
Fix Action
Use environment variables: process.env.API_KEY
Applies To
- *.ts
- *.js
- *.py
- *.yaml
- *.json
Command Injection in AI Code
Id
ai-command-injection
Severity
critical
Type
regex
Pattern
(?:exec|spawn|execSync|spawnSync)\s\([^)](?:\+|`\$\{)[^)]*(?:req|params|body|user|input)
Message
Command injection vulnerability. User input in shell command.
Fix Action
Use spawn with array arguments, never concatenate user input
Applies To
- *.ts
- *.js
Path Traversal in AI Code
Id
ai-path-traversal
Severity
high
Type
regex
Pattern
(?:readFile|writeFile|unlink|readdir)\s\([^)](?:\+|`\$\{)[^)]*(?:req|params|body|user|input)
Message
Path traversal vulnerability. User input in file path.
Fix Action
Use path.resolve() and validate path is within allowed directory
Applies To
- *.ts
- *.js
Insecure Random in Security Context
Id
ai-insecure-random
Severity
medium
Type
regex
Pattern
Math\.random\s\(\)[^;](?:token|key|secret|password|session|auth)
Message
Math.random() used in security context. Not cryptographically secure.
Fix Action
Use crypto.randomBytes() or crypto.randomUUID()
Applies To
- *.ts
- *.js
Missing Input Validation
Id
ai-no-input-validation
Severity
medium
Type
regex
Pattern
req\.(?:body|params|query)\.[a-zA-Z]+(?!\s*\?\.|\.?(?:validate|parse|safeParse|check))
Negative Pattern
zod|yup|joi|validator|sanitize
Message
Request input used without apparent validation.
Fix Action
Validate input with Zod, Yup, or similar before use
Applies To
- *.ts
- *.js
Broad File System Access
Id
ai-excessive-permissions
Severity
medium
Type
regex
Pattern
readdir\s\(['"]\/['"]|glob\s\(['"]\/\\
Message
Reading from root directory or recursive glob. Potential excessive access.
Fix Action
Restrict file operations to specific allowed directories
Applies To
- *.ts
- *.js
Unsafe Deserialization
Id
ai-unsafe-deserialization
Severity
high
Type
regex
Pattern
JSON\.parse\s\([^)](?:req|body|input|user)
Negative Pattern
try\s*\{|catch|safeParse|schema\.parse
Message
JSON.parse without error handling or schema validation.
Fix Action
Wrap in try-catch and validate against schema
Applies To
- *.ts
- *.js
CORS Wildcard Origin
Id
ai-cors-wildcard
Severity
medium
Type
regex
Pattern
cors\s\(\s\{[^}]origin:\s['"]?\*['"]?
Message
CORS configured with wildcard origin. May expose API to any domain.
Fix Action
Specify allowed origins explicitly: origin: ['https://yourdomain.com']
Applies To
- *.ts
- *.js
Missing Authentication Check
Id
ai-missing-auth-check
Severity
high
Type
regex
Pattern
app\.(?:get|post|put|delete|patch)\s\([^,]+,\s(?:async\s)?\([^)]\)\s*=>
Negative Pattern
auth|authenticate|isAuthenticated|requireAuth|protect|verify
Message
Route handler without apparent authentication middleware.
Fix Action
Add authentication middleware: app.get('/api/data', authMiddleware, handler)
Applies To
- *.ts
- *.js