FDE PulseViệc làm FDE đang mở 642Mới trong 7 ngày 46Công ty đang tuyển 98Nhận làm từ xa 24%Lương trung vị (Mỹ) $204kTuyển nhiều nhất Databricks 122
EN

Tờ báo của nghề Forward Deployed Engineer

Công cụ

Trivy: tự quét container image trước khi đội bảo mật của khách làm việc đó

Một lần quét trước ngày bàn giao có thể phát hiện secret còn sót trong image, còn sự cố tháng 3/2026 dạy cách đưa chính máy quét này vào CI của khách mà không mở thêm cửa.

Ảnh kỹ sư ngồi trước laptop đang xem mã và kết quả quét bảo mật trong văn phòng, hoặc dãy máy chủ trong phòng server.
Ảnh: James Harrison / Unsplash
Chia sẻLinkedInFacebookX

Tóm tắt nhanh

  • Với container image, Trivy mặc định quét lỗ hổng và secret; đổi tổ hợp bằng --scanners.
  • Báo cáo sạch chỉ phản ánh các nguồn advisory Trivy dùng, không chứng minh image an toàn.
  • Sau sự cố tháng 3/2026, hãy ghim trivy-action theo commit SHA, không theo tag phiên bản.
Thanh ngang biểu diễn 180 lỗ hổng trong một ví dụ giả định, chia thành 120 lỗ hổng chưa có bản vá (tô cam) và 60 lỗ hổng còn hiển thị sau khi dùng --ignore-unfixed (tô xanh). Chú thích dưới phần cam cho biết khách quét đầy đủ vẫn thấy 120 dòng này.
--ignore-unfixed làm 120 dòng biến khỏi màn hình chứ không biến khỏi image, nên hãy gửi khách cả hai bản báo cáo. Nguồn: ví dụ giả định trong bài.

Tháng 3/2026, mã độc xuất hiện ngay trong một công cụ quét bảo mật. Aqua Security cho biết 76 trong 77 tag phiên bản của trivy-action đã bị force-push sang commit độc hại, và một binary Trivy v0.69.4 độc hại đã được phát hành.

Trivy vẫn đáng có trong bộ đồ nghề của FDE, nhưng sự cố ấy thay đổi cách bạn nên dùng nó. Giá trị của công cụ thì đơn giản: nó cho bạn thấy trước điều đội bảo mật của khách có thể tìm ra.

Thử hình dung đội bảo mật của một ngân hàng quét image bạn vừa giao và thấy một API key nằm bên trong. Bạn không chỉ mất vài ngày sửa lỗi, mà còn mất uy tín đúng lúc khách đang cân nhắc có cho hệ thống lên production hay không. Tự quét trước khi giao rẻ hơn nhiều.

Một lệnh trả lời hai câu hỏi

Trivy là dự án open source do Aqua Security duy trì, phát hành theo giấy phép Apache-2.0. Phạm vi của nó khá rộng: lỗ hổng, misconfiguration, secret và SBOM, trên các target như container image, filesystem, remote git repository, VM image và Kubernetes.

Với container image, mặc định có hai scanner được bật, là vulnerability và secret. Chúng tương ứng với hai câu hỏi: thành phần phần mềm trong image có lỗ hổng đã biết không, và có thông tin bí mật nào bị lộ không?

Phần lỗ hổng bao phủ cả package của hệ điều hành lẫn package của ngôn ngữ. Vì thế, cùng một báo cáo có thể cho bạn biết cả về base image lẫn dependency của ứng dụng, tức hai thứ thường do hai người khác nhau chịu trách nhiệm.

Khi nào FDE cần đến Trivy?

Thời điểm rõ nhất là trước khi bàn giao, khi image đã build xong nhưng chưa rời tay bạn. Thời điểm thứ hai là khi khách gửi sang một danh sách finding và bạn cần đối chiếu nó với image đang chạy.

Thời điểm thứ ba đến sớm hơn cả: khi bạn vừa nhận một repo của khách. Secret scanning cũng chạy được trên filesystem và git repository, nên bạn có thể biết repo đang chứa gì trước khi đóng gói nó vào bất cứ đâu.

Một lần quét trước ngày bàn giao

Lấy một ví dụ giả định: bạn sắp giao image acme/api:1.4.2 cho khách. Lần chạy đầu tiên không cần cờ nào, vì hai scanner bạn cần đã bật sẵn.

trivy image acme/api:1.4.2

Giả sử kết quả có 180 lỗ hổng và 1 secret. Đừng bắt đầu từ con số 180, vì secret là việc có thể xử lý ngay và tệ nhất nếu bị phát hiện sau. Nếu image đó đã từng được đẩy lên registry, hãy coi secret đã lộ: thu hồi và cấp lại trước, build lại image sau.

Sau khi build lại, quét lần nữa và bỏ những lỗ hổng chưa có bản vá, vì đó là những dòng bạn chưa thể sửa bằng cách nâng phiên bản.

trivy image --ignore-unfixed acme/api:1.4.3

Giả sử 120 dòng biến mất và còn 60. Bây giờ bạn có một danh sách làm được: nâng base image, nâng dependency, quét lại. Khi cần kiểm tra riêng một loại, --scanners cho phép chạy đúng scanner đó:

trivy image --scanners secret acme/api:1.4.3

Bộ lọc giúp bạn tập trung, nhưng cũng dễ tự lừa mình

Quay lại con số 120 ở trên. --ignore-unfixed làm chúng biến khỏi màn hình, không làm chúng biến khỏi image. Nếu bạn chỉ gửi báo cáo đã lọc và đội bảo mật của khách chạy bản đầy đủ, họ sẽ thấy 120 dòng bạn không hề nhắc tới.

Cách làm an toàn hơn là gửi cả hai bản, kèm một câu nói rõ bạn đã lọc gì và vì sao. Đừng lấy con số 0 làm mục tiêu của email bàn giao; hãy cho đội bảo mật của khách thấy bạn hiểu rủi ro của mình.

Ignore file cần kỷ luật tương tự. Trivy hỗ trợ .trivyignore và .trivyignore.yaml cho lỗ hổng, misconfiguration và secret, nên một dòng thêm vội có thể giấu cả một secret thật. Quy tắc nên áp dụng: mỗi mục bỏ qua phải đi qua code review, có lý do và có người chịu trách nhiệm.

Giới hạn lớn hơn nằm ở chính dữ liệu. Tài liệu của Trivy nói rõ công cụ chỉ dùng advisory từ các nguồn nó liệt kê, nên một lỗ hổng chưa có trong những nguồn đó sẽ không xuất hiện trong báo cáo.

Vì thế, đừng viết “image an toàn” trong email bàn giao. Hãy viết chính xác hơn: đã quét bằng Trivy phiên bản nào, vào ngày nào, kết quả ra sao.

Trong CI của khách, tag không phải là lời hứa

Aqua có GitHub Action chính thức là aquasecurity/trivy-action để chạy Trivy trên Docker image. Đây cũng chính là thành phần có 76 trong 77 tag bị force-push, nên một workflow trỏ vào tag có thể chạy mã độc mà không ai sửa một dòng nào trong repo.

Khuyến nghị của Aqua là ghim action theo commit SHA đầy đủ, không theo tag phiên bản, vì SHA là bất biến còn tag thì không. Muốn biết một tag đang trỏ vào commit nào, hãy hỏi thẳng repo, thay TAG bằng tag bạn định dùng:

git ls-remote https://github.com/aquasecurity/trivy-action "refs/tags/TAG" "refs/tags/TAG^{}"

Kết quả mở đầu bằng một chuỗi SHA 40 ký tự. Nếu có hai dòng, dòng có đuôi ^{} mới là commit cần ghim.

Đừng dừng ở đó, vì lệnh này chỉ cho biết tag đang trỏ vào đâu lúc này, không chứng minh commit đó sạch. Hãy mở commit trên GitHub, đọc thay đổi, đối chiếu với thông báo của Aqua, rồi mới đưa SHA vào workflow.

Một workflow tối thiểu có thể trông như sau, với image giả định ở trên:

name: scan-image
on: pull_request
permissions:
  contents: read
jobs:
  trivy:
    runs-on: ubuntu-latest
    steps:
      - uses: aquasecurity/trivy-action@FULL_COMMIT_SHA # TAG
        with:
          image-ref: acme/api:1.4.3

File này chỉ minh họa cách ghim SHA, chưa phải một bước chặn thật trong CI: tên image được viết cứng, và file không quy định khi nào job pass hay fail.

Tên tag nằm trong comment để người review biết bạn định dùng bản nào, còn thứ thực sự chạy là SHA. Chi tiết đáng chú ý là job này không khai báo secret nào. Nếu image nằm trong registry riêng, job sẽ cần thêm credential, và đó là thứ bạn phải cân nhắc trước khi thêm.

Đừng xem nhẹ bước ghim SHA, vì cái giá khi action bị tráo rất lớn. Aqua yêu cầu coi mọi secret mà runner bị ảnh hưởng truy cập được là đã lộ, nên chúng cần được rotate.

Ở CI của khách, runner đó có thể giữ credential của khách, không phải của bạn. Trước khi thêm bất kỳ action nào, hãy hỏi: job này chạm được vào secret nào? Rồi kiểm tra xem máy và runner có còn dùng v0.69.4 không.

Nếu thấy phiên bản đó trên một runner, hãy coi mọi secret mà runner ấy truy cập được là đã lộ và rotate chúng, kể cả khi chưa thấy dấu hiệu bị lạm dụng.

Học gì trước, và kể lại thế nào

Thứ tự hợp lý là chạy trivy image trên một image của chính bạn, đọc hiểu từng phần báo cáo, rồi tập --ignore-unfixed, .trivyignore và --scanners. Khi đã quen, hãy nối nó vào một workflow có action được ghim SHA. Các target khác như Kubernetes hay VM image có thể để sau.

Với sự nghiệp, phần đáng giá không phải việc biết một lệnh. Trong CV, hãy mô tả kết quả: quét image trước bàn giao, xử lý secret, giảm danh sách finding xuống mức đội bảo mật của khách có thể review, ghim CI theo SHA.

Khi đọc job description, hãy để ý những từ như container security, SBOM hay customer security review. Nếu chúng xuất hiện, hãy chuẩn bị sẵn một ví dụ quét image do chính bạn làm, và trong phỏng vấn, kể cách bạn quyết định dòng nào được bỏ qua và đã nói gì với khách về những dòng đó.

Lần tới khi một đội bảo mật hỏi “image này đã được quét chưa?”, câu trả lời đáng tin không nằm ở con số 0. Nó nằm ở việc bạn nói được đã quét bằng gì, đã lọc gì, và vì sao máy quét đó xứng đáng được chạy trong hệ thống của họ.

Bài này có hữu ích không?

Dùng cùng trợ lý AIHỏi Claude ↗Hỏi ChatGPT ↗
7 nguồn
Đọc tiếp trên lộ trình · Chặng 5: Triển khaiSnowflake Cortex qua tin tuyển FDE: Cortex Analyst, Cortex Search và Streamlit dùng vào việc gìTin tuyển FDE của Snowflake gắn thẳng Cortex Analyst với việc dựng semantic model trên bảng của khách hàng. Chi tiết đó cho bạn biết nên học gì trước.