จากข่าวที่มีนักพัฒนาซอฟต์แวร์ท่านนึงประสบปัญหาเกี่ยวกับ Cloud Billing พุ่งกระฉูดเพราะ Credentials หลุดสู่สาธารณะ ทำให้ผู้ไม่ประสงค์ดีเอา Credentials ไปใช้ ค่า Cloud สูงจนเกินจะรับได้

หรืออาจจะเคยเห็นข่าวที่ข้อมูลหลุด เพราะผู้ไม่ประสงค์ดีพบรหัสผ่านของฐานข้อมูลที่ถูก commit ไว้ใน repository สาธารณะ

เรื่องพวกนี้เกิดขึ้นบ่อยกว่าที่คิด และผลกระทบก็รุนแรงมาก ตั้งแต่ค่าใช้จ่าย Cloud พุ่งหลักแสนหลักล้าน ไปจนถึงข้อมูลลูกค้าหลุดทั้งระบบ

วิธีป้องกัน Secret หลุดใน Git Repository

การป้องกันต้นเหตุของปัญหานี้สามารถทำได้หลายจุดมาก โดยเริ่มจากสิ่งที่สำคัญที่สุดคือ เราต้องไม่ปล่อยให้มี Secrets หรือ Credentials หลุดเข้าไปอยู่ใน source code ตั้งแต่แรก

มีเครื่องมือหลายตัวที่สามารถใช้สแกนหา secrets ใน codebase ได้ เช่น

  • gitleaks — open-source, เบา, เร็ว, เหมาะกับ pre-commit hook และ CI/CD
  • TruffleHog — สแกนได้ลึก รองรับ S3 buckets, Docker images และอื่นๆ นอกเหนือจาก git repos
  • GitGuardian — แพลตฟอร์มเชิงพาณิชย์ มี dashboard สำหรับทีม พร้อม incident management
  • GitHub Secret Scanning — built-in ใน GitHub สำหรับ public repos (private repos ต้องใช้ Advanced Security)
  • detect-secrets (by Yelp) — ใช้ baseline approach เน้นลด false positives

วันนี้ขอแนะนำ gitleaks เพราะเป็นจุดเริ่มต้นที่ง่ายที่สุด ติดตั้งเสร็จใช้ได้ทันที (ดูตารางเปรียบเทียบเครื่องมือทั้งหมดได้ที่ท้ายบทความ)

gitleaks คืออะไร?

gitleaks เป็น open-source SAST (Static Application Security Testing) tool ที่ออกแบบมาเพื่อตรวจจับ secrets ที่ถูก hardcode ไว้ใน git repositories โดยเฉพาะ เช่น passwords, API keys, tokens, private keys และอื่นๆ

gitleaks เขียนด้วยภาษา Go ทำให้มันเบาและเร็วมาก ปัจจุบันมี GitHub Stars มากกว่า 24,000 ดาว และเป็นหนึ่งใน secret scanner ที่ได้รับความนิยมมากที่สุด

การทำงานของ gitleaks

gitleaks ใช้ regex patterns และ entropy analysis ในการตรวจจับ secrets โดยมี built-in rules สำหรับ secret patterns ที่พบบ่อย เช่น AWS keys, GitHub tokens, Slack webhooks และอีกกว่า 140 รูปแบบ

gitleaks มี 2 โหมดหลักในการสแกน:

  • git — สแกนหา secrets ใน git repository (รวมถึง git history ทั้งหมด)
  • protect — สแกนเฉพาะ uncommitted changes เหมาะสำหรับใช้เป็น pre-commit hook

เมื่อพบ secret gitleaks จะแสดงข้อมูลที่เกี่ยวข้อง เช่น ไฟล์ที่พบ, บรรทัดที่พบ, commit ที่เกี่ยวข้อง, ประเภทของ secret และ author ที่ commit

ทำไมถึงแนะนำ gitleaks?

  • ติดตั้งในเครื่องได้เลย — ไม่ต้องรอ pipeline ตรวจจับ secrets ได้ตั้งแต่ก่อน commit
  • เร็วมาก — เขียนด้วย Go สแกนได้เร็วกว่า tools ตัวอื่นที่ต้อง verify credentials
  • ตั้งค่า pre-commit hook ได้ — สแกนอัตโนมัติทุกครั้งที่ commit เพื่อลดความผิดพลาดจากการลืม
  • ใช้ง่าย ไม่ซับซ้อน — config เป็น TOML file, command line ตรงไปตรงมา
  • ฟรี open-source (MIT License) — ใช้ได้ทั้ง personal และ commercial โดยไม่มีค่าใช้จ่าย
  • รองรับ output หลายรูปแบบ — JSON, CSV, SARIF (ใช้กับ GitHub Advanced Security ได้)

วิธีติดตั้ง gitleaks บน macOS, Linux และ Windows

บน macOS

brew install gitleaks

บน Linux

วิธีที่ 1: ดาวน์โหลด binary จาก GitHub Releases

# ดาวน์โหลดและติดตั้ง (เปลี่ยน version ตามต้องการ)
wget https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz
tar -xzf gitleaks_8.30.0_linux_x64.tar.gz
sudo mv gitleaks /usr/local/bin/

วิธีที่ 2: ผ่าน apt (Kali Linux / Debian-based)

sudo apt install gitleaks

บน Windows

วิธีที่ 1: ผ่าน Chocolatey

choco install gitleaks

วิธีที่ 2: ผ่าน Scoop

scoop install gitleaks

วิธีที่ 3: ดาวน์โหลด binary (.zip) จาก GitHub Releases แล้วเพิ่ม path เข้า System Environment Variables

ผ่าน Docker (ใช้ได้ทุก OS)

docker pull zricethezav/gitleaks:latest

ตรวจสอบว่าติดตั้งสำเร็จ

gitleaks version

วิธีใช้ gitleaks สแกนหา Secret ใน Code

สแกน code ใน git repository

สแกน git history ทั้งหมดของ repository:

gitleaks git /path/to/repo

หรือถ้าอยู่ใน directory ของ repo อยู่แล้ว:

gitleaks git .

ตัวอย่าง output เมื่อพบ secret:

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

Finding:     AKIAIOSFODNN7EXAMPLE
Secret:      AKIAIOSFODNN7EXAMPLE
RuleID:      aws-access-key-id
Entropy:     3.684184
File:        config/settings.py
Line:        42
Commit:      a1b2c3d4e5f6...
Author:      developer@example.com
Date:        2026-01-15T10:30:00Z

12:15PM INF 1 leaks found in 234 commits

สแกนเฉพาะ directory (ไม่ใช่ git repo)

gitleaks dir /path/to/directory

สแกนแบบ verbose (แสดงรายละเอียดมากขึ้น)

gitleaks git . -v

สแกนและ export ผลลัพธ์เป็น JSON

gitleaks git . --report-format json --report-path gitleaks-report.json

ตั้งค่า gitleaks เป็น Pre-commit Hook สแกนทุกครั้งที่ Commit

นี่คือฟีเจอร์ที่ทำให้ gitleaks มีประโยชน์มากที่สุด เพราะเป็นการป้องกันตั้งแต่ต้นทาง ก่อนที่ secrets จะหลุดเข้าไปใน git history

การตั้งค่ามีตัวเลือกให้ 2 แบบ:

  1. แบบ Project level — ตั้งค่าเฉพาะ repository นั้นๆ
  2. แบบ Global — ตั้งค่าให้ทุก repository ในเครื่อง

แบบ Project level

เหมาะสำหรับกรณีที่ต้องการให้แค่บาง project มีการสแกน

วิธีที่ 1: ใช้ native git hook

สร้างไฟล์ .git/hooks/pre-commit ใน repository ที่ต้องการ:

#!/bin/sh

# gitleaks pre-commit hook
gitleaks protect --staged -v

if [ $? -ne 0 ]; then
    echo "[ERROR] gitleaks พบ secrets ใน staged files!"
    echo "กรุณาลบ secrets ออกก่อน commit"
    exit 1
fi

จากนั้นให้ไฟล์สามารถ execute ได้:

chmod +x .git/hooks/pre-commit

วิธีที่ 2: ใช้ pre-commit framework

ถ้าใช้ pre-commit อยู่แล้ว สร้างไฟล์ .pre-commit-config.yaml ที่ root ของ repository:

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.0
    hooks:
      - id: gitleaks

จากนั้นรัน:

pre-commit install

เมื่อลอง commit code ที่มี secret จะได้ผลลัพธ์แบบนี้:

➜ git commit -m "add config"
Detect hardcoded secrets.................................................Failed

commit จะถูกบล็อกไว้ ไม่ให้ secrets หลุดเข้าไปใน git history

จัดการ False Positives ด้วย .gitleaksignore

ในการใช้งานจริง อาจเจอกรณีที่ gitleaks แจ้งเตือนสิ่งที่ไม่ใช่ secret จริง (false positive) เช่น example keys ใน documentation หรือ test fixtures สามารถจัดการได้ 2 วิธี:

วิธีที่ 1: สร้างไฟล์ .gitleaksignore ที่ root ของ repository แล้วใส่ fingerprint ของ finding ที่ต้องการข้าม:

# ข้าม example key ใน documentation
a1b2c3d4:config/example.py:aws-access-key-id

fingerprint ดูได้จาก output ของ gitleaks เมื่อรันด้วย --report-format json

วิธีที่ 2: ใส่ comment gitleaks:allow ในบรรทัดที่ต้องการข้าม:

EXAMPLE_KEY = "AKIAIOSFODNN7EXAMPLE"  # gitleaks:allow

หมายเหตุ: ในกรณีที่ต้องการข้าม gitleaks ทั้ง commit ชั่วคราว สามารถใช้:

SKIP=gitleaks git commit -m "skip gitleaks check"

แบบ Global

เหมาะสำหรับกรณีที่ต้องการให้ทุก repository ในเครื่องมีการสแกนโดยอัตโนมัติ ไม่ต้องตั้งค่าทีละ project

ขั้นตอนที่ 1: สร้าง directory สำหรับเก็บ global git hooks

mkdir -p ~/.git-hooks

ขั้นตอนที่ 2: สร้างไฟล์ ~/.git-hooks/pre-commit

#!/bin/sh

# Global gitleaks pre-commit hook
gitleaks protect --staged -v

if [ $? -ne 0 ]; then
    echo "[ERROR] gitleaks พบ secrets ใน staged files!"
    echo "กรุณาลบ secrets ออกก่อน commit"
    exit 1
fi

ขั้นตอนที่ 3: ให้ไฟล์สามารถ execute ได้

chmod +x ~/.git-hooks/pre-commit

ขั้นตอนที่ 4: ตั้งค่า git ให้ใช้ global hooks directory

git config --global core.hooksPath ~/.git-hooks

เท่านี้ทุก repository ในเครื่องจะถูกสแกนโดย gitleaks ทุกครั้งที่ commit โดยอัตโนมัติ

ข้อควรระวัง: ถ้า repository ไหนมี .git/hooks/pre-commit อยู่แล้ว hook ใน .git/hooks/ จะถูกข้ามไป เพราะ git จะใช้ core.hooksPath แทน ถ้าต้องการใช้ทั้ง global hook และ local hook ต้องเขียน script ให้เรียก local hook ด้วย

ใช้ gitleaks ใน CI/CD Pipeline เป็น Safety Net

นอกจาก pre-commit hook แล้ว ควรใส่ gitleaks ใน CI/CD Pipeline ด้วย เพื่อเป็น safety net อีกชั้นหนึ่ง เผื่อมีคน skip pre-commit hook หรือมีเครื่องที่ยังไม่ได้ตั้งค่า

ตัวอย่าง GitHub Actions

name: gitleaks

on: [pull_request, push, workflow_dispatch]

jobs:
  scan:
    name: gitleaks secret scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # สแกน full git history

      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}  # จำเป็นเฉพาะ Organization repos

หมายเหตุ:

  • fetch-depth: 0 จำเป็นต้องใส่ เพื่อให้ gitleaks สแกน git history ทั้งหมดได้
  • GITLEAKS_LICENSE จำเป็นเฉพาะ repository ที่อยู่ใน Organization account เท่านั้น ถ้าเป็น personal account ไม่ต้องใส่ สามารถสมัครฟรีได้ที่ gitleaks.io

ตัวอย่าง GitLab CI/CD

stages:
  - security

gitleaks:
  stage: security
  image:
    name: zricethezav/gitleaks:latest
    entrypoint: [""]  # จำเป็นสำหรับ GitLab CI + gitleaks image
  variables:
    GIT_DEPTH: 0  # สแกน full git history
  script:
    - gitleaks git . --report-format json --report-path gitleaks-report.json -v
  artifacts:
    when: always
    paths:
      - gitleaks-report.json
    expire_in: 1 week
  allow_failure: false  # pipeline จะ fail ถ้าพบ secrets

หมายเหตุ:

  • entrypoint: [""] จำเป็นต้องใส่ เพราะ gitleaks Docker image มี default entrypoint ที่ conflict กับ GitLab CI
  • GIT_DEPTH: 0 ทำให้ GitLab clone full history เพื่อสแกนได้ครบถ้วน
  • ตั้ง allow_failure: false เพื่อบังคับให้ pipeline fail ถ้าพบ secrets ป้องกันไม่ให้ code ที่มี secrets ถูก merge ได้

สรุป: gitleaks เป็นเครื่องมือที่เรียบง่ายแต่ทรงพลัง ติดตั้งง่ายใช้เวลาไม่กี่นาที แต่สามารถป้องกันปัญหาที่อาจสร้างความเสียหายได้มหาศาล เริ่มต้นด้วยการติดตั้ง gitleaks แล้วตั้งเป็น pre-commit hook ก็เพียงพอที่จะลดความเสี่ยงได้อย่างมากแล้วครับ

เรื่องของ Secret Management ที่ครบวงจร ตั้งแต่ขั้นตอน Development ไปถึง Production Deployment จะมีเครื่องมือตัวอื่นมาเกี่ยวข้องด้วย เช่น HashiCorp Vault, AWS Secrets Manager, SOPS เป็นต้น ซึ่งจะอธิบายในโอกาสต่อไป


gitleaksTruffleHogGitGuardianGitHub Secret Scanningdetect-secrets (Yelp)
ประเภทOpen-source (MIT)Open-source (AGPL)Commercial (มี free tier)Built-in GitHubOpen-source (Apache 2.0)
ภาษาที่ใช้พัฒนาGoGoPython / SaaSN/A (managed service)Python
ความเร็วเร็วมากช้ากว่า (ต้อง verify credentials)เร็ว (cloud-based)เร็ว (event-driven)ปานกลาง
จำนวน Secret Patterns140+800+550+200+ขึ้นอยู่กับ plugins
สแกน Git HistoryYesYesYesYesYes
Pre-commit HookYes native supportYes ผ่าน CLIYes ผ่าน ggshield CLINoYes native support
Verify ว่า Secret ยังใช้ได้NoYes (จุดเด่นหลัก)YesYes (บาง providers)No
สแกนนอก Git ReposNo เฉพาะ git + directoryYes S3, Docker, Slack, CI/CDYes Slack, Jira, ConfluenceNo เฉพาะ GitHub reposNo เฉพาะ files
Dashboard / GUINo CLI onlyNo CLI only (Enterprise มี)Yes web dashboardYes GitHub Security tabNo CLI only
CI/CD IntegrationYes GitHub Actions, GitLab CIYes หลาย platformsYes 8+ CI providersYes GitHub เท่านั้นYes ต้อง config เอง
Output FormatsJSON, CSV, SARIFJSON, SARIFJSON, SARIFSARIF (GitHub native)JSON
Custom RulesYes TOML configYes ผ่าน detectorsYesNo (ใช้ rules ของ GitHub)Yes ผ่าน plugin system
False Positivesปานกลางสูง (แต่ verify ช่วยลดได้)ต่ำต่ำต่ำ (baseline approach)
เหมาะกับทีมเล็ก-กลาง, pre-commit, CI/CDทีมที่ต้อง audit หลาย environmentsEnterprise, ทีมใหญ่ทีมที่ใช้ GitHub อยู่แล้วทีมที่เน้น low false positives
ราคาฟรีฟรี (Enterprise เสียเงิน)ฟรี ≤25 devs, จากนั้นเสียเงินฟรี public repos, เสียเงิน privateฟรี

สรุปสั้นๆ: ไม่มีเครื่องมือตัวเดียวที่ดีที่สุดในทุกด้าน หลายทีมเลือกใช้ gitleaks เป็น pre-commit hook สำหรับความเร็ว คู่กับ TruffleHog ใน CI/CD สำหรับสแกนเชิงลึก เพื่อให้ได้ความครอบคลุมที่ดีที่สุด