Claude Code Generates Insecure Code Patterns Fix
When working with Claude Code, you might occasionally receive code that contains security vulnerabilities This happens because AI models generate code based on patterns in their training data, which can include legacy or insecure practices. Understanding how to identify and fix these patterns is essential for building secure applications.
This guide covers common insecure code patterns that Claude Code might generate, how to recognize them, and practical workflows using Claude skills to improve your code security.
Common Insecure Patterns in AI-Generated Code
SQL Injection Vulnerabilities
One of the most frequent issues appears in database queries. Claude might generate code like this:
# INSECURE - Never use this pattern
user_input = request.form['username']
query = f"SELECT * FROM users WHERE name = '{user_input}'"
cursor.execute(query)
This pattern is vulnerable to SQL injection attacks. The fix is straightforward—use parameterized queries instead:
# SECURE - Using parameterized query
user_input = request.form['username']
query = "SELECT * FROM users WHERE name = %s"
cursor.execute(query, (user_input,))
When you encounter this pattern, you can use the tdd skill to write proper test cases that verify your queries are safe.
Hardcoded Secrets and API Keys
Another common issue is hardcoded credentials:
// INSECURE
const API_KEY = "sk-1234567890abcdef";
const dbPassword = "mysecretpassword";
Always use environment variables:
// SECURE
const API_KEY = process.env.API_KEY;
const dbPassword = process.env.DB_PASSWORD;
The supermemory skill can help you maintain a secure checklist of patterns to review in every project.
Insecure Random Number Generation
For cryptographic operations, never use Math.random() in JavaScript:
// INSECURE - Predictable, not cryptographically secure
const sessionId = Math.random().toString(36);
Use the crypto module instead:
// SECURE - Cryptographically secure
const crypto = require('crypto');
const sessionId = crypto.randomBytes(32).toString('hex');
Cross-Site Scripting (XSS) Vulnerabilities
When rendering user input in web applications, always escape output:
<!-- INSECURE -->
<div>{{ userComment }}</div>
<!-- SECURE - Using a template engine's escaping -->
<div>{{ userComment | escape }}</div>
If you’re using the frontend-design skill, configure it to include security headers and output encoding by default.
Using Claude Skills for Security Reviews
The Security Checklist Skill
Create a custom skill for security reviews. Place this in ~/.claude/skills/security-review.md:
# Security Review Skill
When reviewing code, check for:
1. SQL injection - use parameterized queries
2. XSS - escape all user input
3. CSRF - implement tokens
4. Authentication - never hardcode secrets
5. File operations - validate paths, prevent directory traversal
6. Command injection - avoid shell execution with user input
For each vulnerability found, explain the risk and provide a fixed version.
Use this skill with any code review task:
/security-review
Integrating with TDD Workflow
The tdd skill already encourages writing tests first. Extend this practice to include security test cases:
def test_login_sql_injection():
# Test that SQL injection attempts are handled safely
malicious_input = "' OR '1'='1"
result = authenticate(malicious_input, "anypassword")
assert result is None # Should not authenticate
Run your security tests alongside regular unit tests. The tdd skill will help structure these tests properly.
Automating Security Checks
Consider adding automated security scanning to your workflow. Tools like Bandit (Python), ESLint with security plugins (JavaScript), and SAST scanners can catch many issues automatically. You can create a Claude skill that runs these tools:
# Security Scan Skill
Run the following security checks on the codebase:
1. Bandit for Python: bandit -r .
2. ESLint for JavaScript: eslint --ext .js .
3. Check for secrets: git-secrets or similar
Report findings in a structured format.
Building Secure Defaults
Project Templates
When starting new projects, establish secure defaults early. Use the pdf skill if you need to generate security documentation, or apply the canvas-design skill to create security awareness materials for your team.
Dependency Management
AI-generated code might include outdated dependencies with known vulnerabilities. Always:
- Run
npm auditorpip-auditafter generating code - Review the
package-lock.jsonorrequirements.txtfor vulnerable packages - Use tools like Snyk or Dependabot to monitor dependencies
Input Validation
Never trust user input. Implement validation at every layer:
// Example: Input validation with type safety
function createUser(input: unknown): User {
if (!isValidUserInput(input)) {
throw new ValidationError("Invalid input");
}
// Proceed with sanitized input
return { ... };
}
Practical Workflow for Secure Development
-
Before generating code: Use the
supermemoryskill to recall security patterns relevant to your tech stack -
During code generation: Activate your security checklist skill to prompt for secure implementations
-
After code generation: Run the
tddskill to write security-focused test cases, then execute security scans -
Before deployment: Perform a manual security review using your custom security skill
This layered approach catches vulnerabilities at multiple stages.
Quick Reference: Secure Patterns
| Insecure Pattern | Secure Alternative |
|---|---|
| f-string SQL queries | Parameterized queries |
Math.random() |
crypto.randomBytes() |
| Hardcoded API keys | Environment variables |
| InnerHTML with user input | Text content or sanitization |
eval() with user data |
JSON.parse() or safe parsers |
Conclusion
Claude Code generates code based on patterns it has seen in training data, which sometimes includes legacy or insecure practices. By understanding common vulnerability patterns and using Claude skills strategically, you can catch and fix these issues before they reach production.
The key is establishing security as a consistent part of your development workflow. Use the tdd skill for test-driven security, create custom security review skills, and automate scanning where possible. With these practices in place, you get the speed benefits of AI-assisted development without sacrificing code security.
Built by theluckystrike — More at zovo.one