Chuyển đến nội dung chính

Lesson 18: Security in Vibe Coding

Common security vulnerabilities in AI-generated code. OWASP Top 10 and Vibe Coding. Prompt injection risks. Secure coding patterns. Security scanning tools. Code review for security.

💻 Programming — Lesson 18 Lesson 18: Security in Vibe Coding

Vibe Coding with GitHub Copilot: From Basics to Advanced

Part 6: Professional Vibe Coding — Quality, Security & Production

xdev.asia

1. Current status of security in AI-Generated Code

The year 2025-2026 sees a boom in Vibe Coding, but with it comes serious security concerns:

Research Results
VeraCode (2026) 72% of apps using AI code have security flaws
Stanford (2025) Developers using AI write less secure code and are more confident about security
GitHub (2026) AI code scanning catches 3x more issues when used with AI-generated code

Core problem: AI is trained on public code — including code with security vulnerabilities. AI does not discriminate example code (tutorial, StackOverflow) with production code.

2. OWASP Top 10 and Vibe Coding

2.1. Injection (A03:2021)

AI often generates unsafe SQL queries:

// ❌ AI có thể generate:
const users = await db.query(
  `SELECT * FROM users WHERE email = '${email}'`
);

// ✅ Phải yêu cầu:
const users = await db.query(
  'SELECT * FROM users WHERE email = $1',
  [email]
);
// Prompt an toàn:
Always use parameterized queries. Never concatenate user input
into SQL strings. Use ORM methods when available.

2.2. Broken Authentication (A07:2021)

// ❌ AI có thể generate weak JWT:
jwt.sign(payload, 'secret123')  // Hardcoded secret!

// ✅ Secure version: jwt.sign(payload, process.env.JWT_SECRET!, { expiresIn: '15m', algorithm: 'RS256', // Asymmetric })

2.3. Sensitive Data Exposure (A02:2021)

// ❌ AI có thể log sensitive data:
console.log('User login:', { email, password });
res.json({ user: { ...user } });  // Includes password hash!

// ✅ Chỉ return cần thiết: const { password, ...safeUser } = user; res.json({ user: safeUser });

2.4. Insecure Direct Object Reference (A01:2021)

// ❌ AI thường bỏ auth check:
app.get('/api/tasks/:id', async (req, res) => {
  const task = await prisma.task.findUnique({
    where: { id: req.params.id },
  });
  res.json(task);  // Any user can access any task!
});

// ✅ Luôn check ownership: app.get('/api/tasks/:id', auth, async (req, res) => { const task = await prisma.task.findFirst({ where: { id: req.params.id, project: { members: { some: { userId: req.userId } }, }, }, }); if (!task) return res.status(404).json({ error: 'Not found' }); res.json(task); });

3. Common vulnerabilities in AI Code

Vulnerability Frequency of AI Example
Hardcoded secrets Very high API keys, passwords in code
Missing input validation High Do not validate user input
Weak crypto High MD5 instead of bcrypt, SHA-256
Missing authentication checks Average Endpoint does not verify users
SQL injection Average String concatenation queries
XSS Average Direct HTML rendering
Path traversal Low Unsanitized file paths

4. Prompt Injection Risks

When using MCP servers or processing user input via AI:

// User nhập vào form:
"; DROP TABLE users; --

// Nếu AI xử lý raw input:
AI có thể generate code chứa malicious input

Prevention:

  • Never pass user input directly into the AI prompt
  • Sanitize input BEFORE sending it to AI
  • Validate AI output before executing
  • Use allowlists instead of denylists

5. Secure Prompting Patterns

5.1. Custom instructions for security


## Security Requirements
  • NEVER hardcode secrets, API keys, or passwords
  • ALWAYS use parameterized queries, never string concatenation for SQL
  • ALWAYS validate and sanitize user input at API boundaries
  • ALWAYS check authorization before returning data
  • NEVER log sensitive data (passwords, tokens, PII)
  • Use bcrypt with cost factor >= 12 for password hashing
  • Use HTTPS for all external API calls
  • Set security headers (CORS, CSP, HSTS)
  • Implement rate limiting on auth endpoints

5.2. Security-first prompts

// Thay vì:
Create a login endpoint

// Dùng: Create a secure login endpoint with:

  • Rate limiting (5 attempts per minute per IP)
  • Password hashing with bcrypt (cost 12)
  • JWT with short expiry (15 min) + refresh token
  • Account lockout after 10 failed attempts
  • Audit logging for failed attempts
  • No password in response or logs

6. Security Scanning Tools

6.1. GitHub Advanced Security

GitHub Secret Scanning: phát hiện secrets trong code
CodeQL: static analysis cho security vulnerabilities
Dependabot: scan dependencies cho known vulnerabilities

6.2. In the CI/CD pipeline

# .github/workflows/security.yml
name: Security Scan
on: [pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
  # Dependency scan
  - run: npm audit --audit-level=high

  # Secret detection
  - uses: trufflesecurity/trufflehog@main
    with:
      path: ./

  # SAST scan
  - uses: github/codeql-action/analyze@v3
    with:
      languages: javascript-typescript

  # Container scan (if using Docker)
  - uses: aquasecurity/trivy-action@master
    with:
      scan-type: fs
      scan-ref: .

6.3. IDE-level scanning

// Copilot itself can help with security review:
@workspace /review Check all API endpoints for:
1. Missing authentication middleware
2. Missing input validation
3. SQL injection vulnerabilities
4. Hardcoded secrets
5. Sensitive data in responses

7. Secure Coding Patterns for Vibe Coding

Pattern 1: Validate-first middleware

// Yêu cầu AI tạo validation middleware:
const validateRequest = (schema: z.ZodSchema) => {
  return (req: Request, res: Response, next: NextFunction) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(400).json({
        error: 'Validation failed',
        details: result.error.issues,
      });
    }
    req.body = result.data;  // Use validated data
    next();
  };
};

Pattern 2: Authorization guard

// Resource-level authorization:
const canAccessProject = async (userId: string, projectId: string) => {
  const member = await prisma.projectMember.findUnique({
    where: {
      userId_projectId: { userId, projectId },
    },
  });
  return member !== null;
};

Pattern 3: Output sanitization

// Chỉ return fields cần thiết:
const sanitizeUser = (user: User) => ({
  id: user.id,
  name: user.name,
  email: user.email,
  avatar: user.avatar,
  // Exclude: password, resetToken, etc.
});

8. Security Checklist for Vibe Coding

# Check When
1 There are no hardcoded secrets Every commit
2 Input validation at all endpoints Each new endpoint
3 Auth middleware in protected routes Each new route
4 Parameterized queries Each DB query
5 No sensitive data in logs/responses Each API response
6 Dependencies do not have CVEs Every week
7 Security headers configured One time + verify
8 Rate limiting on auth endpoints One time + verify

9. Summary

Security in Vibe Coding requires different mindset:

  • Trust but verify: AI code always needs security review
  • Defense in depth: Multiple layers of security checks
  • Automate scanning: CI/CD must force AI issues to create
  • Secure by default: Custom instructions enforce security patterns
  • Stay updated: AI models improve but the threat landscape also changes

Next article: Technical Debt & Maintainability — manage technical debt when using Vibe Coding.