0

3 rủi ro hay bị bỏ sót trong code do AI viết: khóa còn trong lịch sử Git, CVE ở phụ thuộc gián tiếp và giấy phép GPL

Công khai: mình là người sáng lập TechDD. Bài này chia sẻ những gì bọn mình rút ra khi quét mã nguồn thực tế, kèm lệnh để bạn tự kiểm tra trên repo của mình.

Ngày nay một phần lớn code chạy trên production được viết bởi Cursor, Claude hay Copilot. Tốc độ phát triển nhanh hơn hẳn, nhưng có một vấn đề: trong team thường không ai biết chính xác trong code đang có gì. Qua nhiều lần quét, bọn mình thấy ba nhóm rủi ro lặp lại nhiều nhất. Chúng hiếm khi gây lỗi ngay, mà thường lộ ra đúng lúc bất lợi nhất: khi nhà đầu tư thẩm định kỹ thuật, khi bàn giao cho khách hàng doanh nghiệp, hoặc khi khách hàng yêu cầu đánh giá bảo mật.

1. Khóa bí mật đã xóa khỏi file nhưng vẫn còn trong lịch sử Git

Tình huống rất quen: AI gợi ý dán thẳng API key vào code để chạy thử, sau đó bạn chuyển sang biến môi trường và xóa dòng đó đi. File hiện tại sạch, nhưng commit cũ vẫn giữ nguyên giá trị. Ai có quyền đọc repo (hoặc bản ZIP có kèm thư mục .git) đều lấy lại được.

Các công cụ hay trợ lý AI chỉ đọc file hiện tại sẽ không thấy lỗi này. Bạn cần quét toàn bộ lịch sử:

# Quét toàn bộ lịch sử commit
gitleaks git --log-opts="--all" .

# Tìm nhanh một chuỗi nghi ngờ trong lịch sử
git log --all -S "sk_live_" --oneline

Nếu phát hiện khóa thật, việc đầu tiên là thu hồi và đổi khóa (rotate) ở phía nhà cung cấp. Viết lại lịch sử (ví dụ bằng git filter-repo) chỉ là bước sau, vì bản clone cũ ở nơi khác vẫn còn giá trị đó.

git filter-repo --replace-text replacements.txt

2. Lỗ hổng (CVE) nằm ở phụ thuộc gián tiếp

Mô hình ngôn ngữ không biết các CVE được công bố sau thời điểm huấn luyện. Khi AI đề xuất "cài thư viện X phiên bản Y", phiên bản đó có thể đã có lỗ hổng. Phần lớn lỗ hổng lại nằm ở phụ thuộc gián tiếp — thư viện mà bạn không trực tiếp cài, nên cũng không để ý.

Cách kiểm tra là dùng cơ sở dữ liệu lỗ hổng được cập nhật hằng ngày, không dựa vào trí nhớ của mô hình:

# Xem thư viện nào kéo theo gói có vấn đề
npm ls sharp

# Quét lockfile bằng cơ sở dữ liệu CVE
trivy fs --scanners vuln .
npm audit --omit=dev

Mẹo: tách riêng phụ thuộc chạy ở runtime và phụ thuộc chỉ dùng khi phát triển. Lỗ hổng ở gói devDependencies vẫn cần xử lý, nhưng mức độ ưu tiên thấp hơn gói chạy trên production.

3. Giấy phép GPL/AGPL trong sản phẩm thương mại

Khi AI chèn một đoạn code hay gợi ý một thư viện, nó hiếm khi nói đến giấy phép. Nếu trong sản phẩm thương mại có thành phần GPL hoặc AGPL, bạn có thể phát sinh nghĩa vụ công khai mã nguồn — đây là điểm nhà đầu tư và khách hàng doanh nghiệp hỏi rất kỹ.

# Liệt kê giấy phép của các gói npm
npx license-checker --summary

# Quét giấy phép ở mức file
scancode --license --json-pp licenses.json src/

Hãy đặc biệt chú ý AGPL: chỉ cần cung cấp dịch vụ qua mạng là đã có thể phát sinh nghĩa vụ.

4. Bài học khi quét thật: cẩn thận với kết quả báo động giả

Khi chạy quét trên repo thật của chính bọn mình, bọn mình phải sửa khá nhiều quy tắc vì báo động giả:

  • Khóa AWS tạm thời trong presigned URL: khóa bắt đầu bằng ASIA trong phản hồi API đã lưu là khóa phiên tạm thời của bucket bên thứ ba, đã hết hạn. Không nên xếp vào mức nghiêm trọng như khóa dài hạn (AKIA).
  • Khóa công khai: site key của reCAPTCHA, Turnstile hay khóa IndexNow vốn được công khai, không phải bí mật.
  • File .env cục bộ: để khóa trong .env (đã có trong .gitignore) là cách làm chuẩn. Rủi ro thật là khi .env bị commit vào Git, hoặc bị nén chung khi gửi mã nguồn cho bên khác.
  • Bản sao trùng: git worktree hay thư mục copy làm cùng một lỗi bị đếm 3–5 lần.
  • Truy vấn SQL hằng: phép cộng bên trong câu SQL (ví dụ MAX(sort_order)+1) không phải là nối chuỗi từ dữ liệu người dùng.

Bài học: kết quả quét chỉ có giá trị khi có bằng chứng theo từng file và dòng để đội phát triển tự kiểm chứng.

5. Checklist ngắn trước khi thẩm định hoặc bàn giao

  1. Quét toàn bộ lịch sử Git để tìm khóa bí mật; đổi khóa trước, viết lại lịch sử sau.
  2. Quét lockfile bằng cơ sở dữ liệu CVE mới nhất, ưu tiên gói chạy ở runtime.
  3. Liệt kê giấy phép, kiểm tra GPL/AGPL trong sản phẩm thương mại.
  4. Không nén file .env và các bản lưu phản hồi API khi gửi mã nguồn ra ngoài.

Về TechDD: các công cụ quét tĩnh như trên đã được nhiều doanh nghiệp lớn sử dụng, nhưng sản phẩm thương mại thường đắt và cần người vận hành. Bọn mình làm sản phẩm B2B cho doanh nghiệp trước; sau đó nhiều founder startup và lập trình viên "vibe coding" một mình đề nghị có bản dùng thử trực tuyến, nên bọn mình mở thêm dịch vụ online: tải lên ZIP hoặc URL repo, nhận báo cáo bằng tiếng Việt trong 24 giờ. Mã nguồn được phân tích trong mạng khép kín, không gửi tới AI bên ngoài và tự động xóa sau khi tạo báo cáo.

Đến hết ngày 23/10 (giờ Hàn Quốc) bọn mình đang mở chương trình dùng miễn phí đổi lấy đánh giá thật. Lưu ý: khi đăng ký, PayPal chỉ tạm giữ (không trừ tiền); khoản giữ được hủy khi bạn viết đánh giá, và chỉ bị trừ nếu không có đánh giá trong 10 ngày. Chi tiết: https://dd.knowverse.net/vi/review-event?utm_source=viblo&utm_medium=blog&utm_campaign=review-2026

Mọi góp ý — đặc biệt về báo động giả — bọn mình đều rất cảm ơn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí