Ngừng rò rỉ Secret: Hướng dẫn thực tế tích hợp Gitleaks vào CI/CD

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Vấn đề: Secret là “vàng ròng” mới đối với Hacker

Tôi đã chứng kiến điều này xảy ra quá nhiều lần: một lập trình viên đang vội, họ hardcode một mã AWS tạm thời hoặc mật khẩu cơ sở dữ liệu để kiểm tra nhanh, và trước khi kịp nhận ra, mã đó đã nằm chễm chệ trên một repository công khai.

Chỉ mất chưa đầy một phút để các bot tự động tìm thấy secret đó và bắt đầu khởi chạy các instance đắt đỏ hoặc sao lưu toàn bộ cơ sở dữ liệu của bạn. Theo kinh nghiệm thực tế của tôi, đây là một trong những kỹ năng thiết yếu cần nắm vững vì cái giá của một thông tin đăng nhập bị rò rỉ có thể gây thảm họa cho uy tín và tài chính của công ty.

Nguyên nhân gốc rễ thường không phải do kém cỏi; đó là bản chất con người. Chúng ta hay quên. Chúng ta nghĩ rằng mình sẽ xóa mã đó trước khi commit, nhưng rồi lại bị phân tâm. Việc dựa vào đánh giá mã nguồn (code review) thủ công để bắt secret là một cuộc chơi nắm chắc phần thua. Bạn cần một mạng lưới an toàn tự động không bao giờ ngủ.

Bắt đầu nhanh: Phát hiện Secret trong 5 phút

Gitleaks là một công cụ nhanh, nhẹ được thiết kế đặc biệt để quét lịch sử Git và các tệp hiện tại nhằm tìm kiếm secret. Bạn không cần thiết lập phức tạp để bắt đầu. Nếu bạn đã cài đặt Docker, bạn có thể quét dự án hiện tại của mình ngay lập tức.

docker run -v $(pwd):/path zricethezav/gitleaks:latest detect --source="/path" -v

Nếu bạn thích sử dụng file thực thi cục bộ, bạn có thể cài đặt thông qua Homebrew trên macOS hoặc tải xuống bản thực thi cho Linux/Windows. Sau khi cài đặt, việc chạy quét rất đơn giản:

gitleaks detect --source . --verbose

Lệnh detect sẽ xem xét trạng thái hiện tại của bạn. Nếu bạn muốn quét toàn bộ lịch sử commit (điều mà tôi rất khuyến khích cho bất kỳ dự án hiện có nào), hãy sử dụng chế độ git:

gitleaks detect --source . --log-opts="--all"

Khi Gitleaks tìm thấy thứ gì đó, nó sẽ thoát với mã lỗi (non-zero code), đây chính xác là những gì chúng ta cần để pipeline CI/CD dừng lại và chặn quá trình triển khai.

Đi sâu vào chi tiết: Tích hợp Gitleaks vào Pipeline của bạn

Chạy Gitleaks trên máy tính cá nhân là điều tuyệt vời, nhưng phép màu thực sự xảy ra khi bạn bắt buộc mọi pull request phải vượt qua bài kiểm tra Gitleaks. Hãy cùng xem cách thực hiện điều này trên hai nền tảng phổ biến nhất.

Tích hợp GitHub Actions

GitHub làm cho việc này trở nên cực kỳ dễ dàng với action chính thức của Gitleaks. Hãy tạo một tệp tại .github/workflows/gitleaks.yml:

name: Gitleaks
on:
  pull_request:
  push:
    branches: [main]
jobs:
  scan:
    name: Quét Gitleaks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Lưu ý fetch-depth: 0. Điều này cực kỳ quan trọng. Theo mặc định, nhiều công cụ CI chỉ lấy commit mới nhất. Gitleaks cần toàn bộ lịch sử để đảm bảo không có secret nào bị ẩn trong các commit cũ hơn đang được merge.

Tích hợp GitLab CI

Đối với người dùng GitLab, bạn có thể thêm một job vào tệp .gitlab-ci.yml bằng cách sử dụng image Docker của Gitleaks:

gitleaks_scan:
  stage: test
  image: 
    name: zricethezav/gitleaks:latest
    entrypoint: [""]
  script:
    - gitleaks detect --source=$CI_PROJECT_DIR --verbose --redact

Flag --redact là một tính năng hay cho CI—nó ẩn secret thực tế trong nhật ký quét để bạn không vô tình làm rò rỉ secret một lần nữa trong output của bản build trong khi đang cố gắng báo cáo nó.

Sử dụng nâng cao: Tùy chỉnh và Thiết lập Baseline

Không phải mọi chuỗi ký tự trông giống secret đều thực sự là secret. Cảnh báo giả (False positives) là kẻ thù của năng suất lập trình viên. Nếu pipeline của bạn thất bại vì một mã test giả, các lập trình viên sẽ bắt đầu phớt lờ công cụ này.

Xử lý Cảnh báo giả với .gitleaksignore

Nếu Gitleaks đánh dấu một tệp hoặc một dòng cụ thể mà bạn biết là an toàn, đừng chỉ để đó. Hãy tạo một tệp .gitleaksignore trong thư mục gốc. Bạn có thể bỏ qua các Fingerprint cụ thể (mã băm của kết quả tìm thấy) được cung cấp trong output của Gitleaks:

# .gitleaksignore
# Bỏ qua một thông tin đăng nhập kiểm thử cụ thể
6f7d8e9a... (fingerprint của bạn tại đây)

Thiết lập Baseline (Điểm cơ sở)

Nếu bạn đang đưa Gitleaks vào một dự án cũ với hàng nghìn commit, bạn có thể thấy hàng trăm “secret”—một số trong đó đã cũ, bị thu hồi hoặc là cảnh báo giả. Bạn không muốn phải sửa 500 lỗi chỉ để bắt đầu sử dụng công cụ. Hãy sử dụng baseline:

gitleaks detect --source . --baseline-path gitleaks-baseline.json

Lệnh này tạo ra một báo cáo về tất cả các vấn đề hiện tại. Gitleaks giờ đây sẽ chỉ thất bại nếu các secret *mới* được đưa vào. Điều này cho phép bạn áp dụng phương pháp “cầm máu” trước khi dọn dẹp những rắc rối trong quá khứ.

Quy tắc tùy chỉnh

Mỗi công cụ đều có những định dạng nội bộ riêng biệt. Có lẽ các API key nội bộ của bạn luôn bắt đầu bằng MYCORP_. Bạn có thể xác định các quy tắc tùy chỉnh trong tệp gitleaks.toml:

[[rules]]
id = "mycorp-api-key"
description = "Phát hiện API Key nội bộ của MyCorp"
regex = '''(?i)MYCORP_[a-z0-9]{32}'''
keywords = ["mycorp"]

Mẹo thực tế cho quy trình làm việc không rò rỉ

Triển khai Gitleaks trong CI là tuyến phòng thủ cuối cùng, nhưng nó không nên là tuyến duy nhất. Dưới đây là một số chiến lược tôi sử dụng để giữ an toàn cho đội ngũ của mình.

1. Pre-commit Hook: Ngăn chặn trước khi Push

Tại sao phải đợi đến khi CI thất bại? Hãy cài đặt pre-commit và thêm Gitleaks vào quy trình làm việc cục bộ của bạn. Điều này ngăn chặn secret rời khỏi máy tính của lập trình viên.

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.2
    hooks:
      - id: gitleaks

2. Làm gì khi tìm thấy secret?

Nếu Gitleaks phát hiện một secret trong PR, đừng chỉ xóa dòng đó và commit lại. Secret vẫn còn trong lịch sử Git của bạn. Nếu secret đã từng được push lên server từ xa, bạn phải coi nó như đã bị xâm nhập.

  • Rotate (Thay mới): Thu hồi mã đó và tạo một mã mới ngay lập tức.
  • Remove (Gỡ bỏ): Sử dụng các công cụ như git-filter-repo hoặc BFG Repo-Cleaner nếu bạn thực sự phải xóa sạch lịch sử, nhưng việc thay mới luôn là ưu tiên hàng đầu.

3. Sử dụng Biến môi trường

Điều này có vẻ hiển nhiên, nhưng cách tốt nhất để tránh thất bại Gitleaks là không bao giờ đưa secret vào mã nguồn. Hãy sử dụng các tệp .env (và thêm chúng vào .gitignore) hoặc các dịch vụ quản lý secret như AWS Secrets Manager hoặc HashiCorp Vault. Theo kinh nghiệm của tôi, nếu bạn thấy mình cần phải bỏ qua quá nhiều thứ trong Gitleaks, thì cách tiếp cận kiến trúc đối với secret của bạn có lẽ mới là vấn đề thực sự.

Bằng cách tự động hóa việc phát hiện secret, bạn chuyển từ văn hóa “hy vọng điều tốt đẹp nhất” sang một tâm thế bảo mật chủ động. Chỉ mất chưa đầy một giờ để thiết lập, nhưng nó có thể cứu bạn khỏi ngày tồi tệ nhất trong cuộc đời sự nghiệp của mình.

Share: