Bỏ qua để vào nội dung chính
Copilot Agent Mode: từ 912MB/50+ CVE về 108MB/0 CVE

Copilot Agent Mode: từ 912MB/50+ CVE về 108MB/0 CVE

Bởi Marcus Bennett
23 thg 8, 20263 phút đọc

Hướng dẫn dùng Copilot Agent Mode hardening image Node.js: 912MB và 50+ CVE về 108MB Distroless 0 vulnerability, kèm cái bẫy Alpine cần biết.

Một hướng dẫn trên Dev.to đưa image Node.js từ 912 MB với 50+ CVE Critical/High về 108 MB và 0 vulnerability, bằng cách giao thẳng terminal cho GitHub Copilot Agent Mode. Ba phase, hai prompt, và một cái bẫy mà phần lớn team VN đang mắc.

Điểm khởi đầu: node:14 single-stage

Bài viết bắt đầu bằng thứ rất dễ gặp trong repo cũ: một image single-stage trên node:14. Kết quả scan bằng docker scout cves theo bài: kích thước ~912 MB, "50+ Critical & High CVEs", và ba rủi ro cụ thể — "outdated base OS packages, running process as root, unnecessary build tools exposed in runtime".

Ba vấn đề đó độc lập nhau. Image nặng làm chậm CI và pull; chạy bằng root là leo thang đặc quyền nếu container bị chiếm; build tool còn trong runtime là bề mặt tấn công không ai cần tới.

Phase 2 — multi-stage Alpine: giảm 85%

Prompt đầu tiên yêu cầu Copilot Agent Mode refactor Dockerfile thành multi-stage build trên node:20-alpine: tách hẳn stage cài dependency khỏi stage runtime, tạo user không phải root, và sinh file .dockerignore. Theo bài, Copilot tự tạo .dockerignore, viết lại Dockerfile thành hai stage, rồi build image.

Kết quả so sánh trong bài: node:14 912 MB, app:alpine 123 MB — mức giảm 85%.

Cái bẫy Alpine

Đây là phần đáng đọc nhất, vì nhiều team dừng lại đúng ở đây và tưởng đã xong. Bài gọi nó là "The Alpine Trap": scan app:alpine vẫn lộ ra vulnerability trong các lớp utility của Alpine. Quan trọng hơn, nếu container bị chiếm thì Alpine vẫn còn package manager (apk) và shell (/bin/sh) để kẻ tấn công dùng tiếp.

Nói cách khác: giảm dung lượng và giảm bề mặt tấn công là hai việc khác nhau. Alpine làm tốt việc thứ nhất và chỉ làm một phần việc thứ hai.

Phase 3 — Distroless về 0

Prompt thứ hai yêu cầu đổi production stage sang gcr.io/distroless/nodejs20-debian12, build thành app:hardened rồi scan lại. Theo bài, Distroless "contain only your application and its runtime dependencies—no package managers, no shell, and no standard Linux utilities", và lần scan cuối cho ra "0 Total Vulnerabilities".

VariantBase imageSizeCVEShell / package manager
Legacy single-stagenode:14912 MB50+ Critical/HighCó (/bin/bash, apt)
Multi-stage Alpinenode:20-alpine123 MBLow / MediumCó (/bin/sh, apk)
Hardened Distrolessdistroless/nodejs20108 MB0Không (shell-less)

Đánh đổi cần biết trước khi copy: image không có shell nghĩa là docker exec vào debug cũng không còn. Nếu quy trình vận hành của bạn dựa vào việc ssh/exec vào container để xem log, phải chuyển sang log tập trung và ephemeral debug container trước, không phải sau.

Cần copy gì

Ba kết luận bài viết đưa ra cho team DevOps, và cả ba đều đúng dù bạn dùng agent nào: không dùng single-stage cho production, luôn tách build tool khỏi runtime; Alpine không phải điểm dừng cuối về bảo mật; và prompt có cấu trúc rõ cho phép agent inspect, refactor, build, audit trong một vòng lặp liên tục thay vì từng lệnh rời rạc.

Việc làm được ngay chiều nay: chạy docker scout cves trên image production nặng nhất của bạn và ghi lại hai số — dung lượng và số CVE Critical/High. Đó là baseline. Không có baseline thì mọi refactor sau đó chỉ là cảm giác.

Lưu ý: đây là kết quả một bài hướng dẫn với một app Node.js cụ thể, không phải benchmark trên nhiều codebase. Con số 912 → 108 MB phụ thuộc vào dependency của app; phần tái lập được là trình tự ba phase và lệnh verify.

Không spam, hủy đăng ký bất kỳ lúc nào.

Bài viết liên quan