จากข่าวที่มีนักพัฒนาซอฟต์แวร์ท่านนึงประสบปัญหาเกี่ยวกับ 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 แบบ:
- แบบ Project level — ตั้งค่าเฉพาะ repository นั้นๆ
- แบบ 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 CIGIT_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 เป็นต้น ซึ่งจะอธิบายในโอกาสต่อไป
| gitleaks | TruffleHog | GitGuardian | GitHub Secret Scanning | detect-secrets (Yelp) | |
|---|---|---|---|---|---|
| ประเภท | Open-source (MIT) | Open-source (AGPL) | Commercial (มี free tier) | Built-in GitHub | Open-source (Apache 2.0) |
| ภาษาที่ใช้พัฒนา | Go | Go | Python / SaaS | N/A (managed service) | Python |
| ความเร็ว | เร็วมาก | ช้ากว่า (ต้อง verify credentials) | เร็ว (cloud-based) | เร็ว (event-driven) | ปานกลาง |
| จำนวน Secret Patterns | 140+ | 800+ | 550+ | 200+ | ขึ้นอยู่กับ plugins |
| สแกน Git History | Yes | Yes | Yes | Yes | Yes |
| Pre-commit Hook | Yes native support | Yes ผ่าน CLI | Yes ผ่าน ggshield CLI | No | Yes native support |
| Verify ว่า Secret ยังใช้ได้ | No | Yes (จุดเด่นหลัก) | Yes | Yes (บาง providers) | No |
| สแกนนอก Git Repos | No เฉพาะ git + directory | Yes S3, Docker, Slack, CI/CD | Yes Slack, Jira, Confluence | No เฉพาะ GitHub repos | No เฉพาะ files |
| Dashboard / GUI | No CLI only | No CLI only (Enterprise มี) | Yes web dashboard | Yes GitHub Security tab | No CLI only |
| CI/CD Integration | Yes GitHub Actions, GitLab CI | Yes หลาย platforms | Yes 8+ CI providers | Yes GitHub เท่านั้น | Yes ต้อง config เอง |
| Output Formats | JSON, CSV, SARIF | JSON, SARIF | JSON, SARIF | SARIF (GitHub native) | JSON |
| Custom Rules | Yes TOML config | Yes ผ่าน detectors | Yes | No (ใช้ rules ของ GitHub) | Yes ผ่าน plugin system |
| False Positives | ปานกลาง | สูง (แต่ verify ช่วยลดได้) | ต่ำ | ต่ำ | ต่ำ (baseline approach) |
| เหมาะกับ | ทีมเล็ก-กลาง, pre-commit, CI/CD | ทีมที่ต้อง audit หลาย environments | Enterprise, ทีมใหญ่ | ทีมที่ใช้ GitHub อยู่แล้ว | ทีมที่เน้น low false positives |
| ราคา | ฟรี | ฟรี (Enterprise เสียเงิน) | ฟรี ≤25 devs, จากนั้นเสียเงิน | ฟรี public repos, เสียเงิน private | ฟรี |
สรุปสั้นๆ: ไม่มีเครื่องมือตัวเดียวที่ดีที่สุดในทุกด้าน หลายทีมเลือกใช้ gitleaks เป็น pre-commit hook สำหรับความเร็ว คู่กับ TruffleHog ใน CI/CD สำหรับสแกนเชิงลึก เพื่อให้ได้ความครอบคลุมที่ดีที่สุด