Semgrep IaC Scanning
Semgrep SAST IaC Terraform Kubernetes Dockerfile CloudFormation Ansible Security Misconfiguration Rules CI/CD Open Source Production
| IaC Type | File | Common Findings | Severity |
|---|---|---|---|
| Terraform | .tf | Public S3 Open SG No Encryption | Critical-High |
| Kubernetes | .yaml | Run as Root No Limits Privileged | High-Medium |
| Dockerfile | Dockerfile | Root User latest Tag Secrets | Medium-High |
| CloudFormation | .yaml/.json | Open SG Public S3 Weak IAM | Critical-High |
| Ansible | .yml | Hardcoded Creds Unsafe Perms | Critical-Medium |
Scanning & Rules
# === Semgrep IaC Scanning ===
# Install
# pip install semgrep
# or: brew install semgrep
# Scan Terraform files with auto rules
# semgrep --config auto --lang hcl ./terraform/
# Scan Kubernetes manifests
# semgrep --config p/kubernetes ./k8s/
# Scan Dockerfiles
# semgrep --config p/dockerfile ./
# Scan with specific ruleset
# semgrep --config p/terraform ./terraform/
# semgrep --config p/owasp-top-ten ./src/
# Custom Rule Example: Detect public S3 bucket
# Save as rules/s3-public.yaml:
# rules:
# - id: terraform-s3-no-public-acl
# patterns:
# - pattern: |
# resource "aws_s3_bucket" $BUCKET {
# ...
# acl = "public-read"
# ...
# }
# message: >
# S3 bucket $BUCKET has public-read ACL.
# Use private ACL and CloudFront for public content.
# severity: ERROR
# languages: [hcl]
# metadata:
# cwe: ["CWE-284: Improper Access Control"]
# owasp: ["A01:2021 Broken Access Control"]
from dataclasses import dataclass
@dataclass
class SemgrepRule:
rule_id: str
target: str
pattern_desc: str
severity: str
fix: str
rules = [
SemgrepRule("terraform-s3-public-acl",
"Terraform (.tf)",
"S3 Bucket มี acl = public-read",
"ERROR (Critical)",
"เปลี่ยนเป็น private ใช้ CloudFront"),
SemgrepRule("terraform-sg-open-ingress",
"Terraform (.tf)",
"Security Group เปิด 0.0.0.0/0 ทุก Port",
"ERROR (Critical)",
"จำกัด CIDR Block และ Port"),
SemgrepRule("k8s-container-privileged",
"Kubernetes (.yaml)",
"Container มี privileged: true",
"ERROR (Critical)",
"ลบ privileged ใช้ securityContext"),
SemgrepRule("k8s-no-resource-limits",
"Kubernetes (.yaml)",
"Container ไม่มี resources.limits",
"WARNING (High)",
"เพิ่ม CPU Memory Limits"),
SemgrepRule("dockerfile-root-user",
"Dockerfile",
"ไม่มี USER instruction ทำงานเป็น Root",
"WARNING (High)",
"เพิ่ม USER nonroot หลัง Build Stage"),
]
print("=== Semgrep IaC Rules ===")
for r in rules:
print(f" [{r.rule_id}] Target: {r.target}")
print(f" Detect: {r.pattern_desc}")
print(f" Severity: {r.severity}")
print(f" Fix: {r.fix}")
CI/CD Integration
# === CI/CD Pipeline ===
# GitHub Actions (.github/workflows/semgrep.yml)
# name: Semgrep SAST
# on: [pull_request]
# jobs:
# semgrep:
# runs-on: ubuntu-latest
# container:
# image: semgrep/semgrep
# steps:
# - uses: actions/checkout@v4
# - run: semgrep ci
# env:
# SEMGREP_APP_TOKEN: }
# GitLab CI (.gitlab-ci.yml)
# semgrep:
# image: semgrep/semgrep
# script:
# - semgrep ci --json --output semgrep-report.json
# artifacts:
# reports:
# sast: semgrep-report.json
# Pre-commit (.pre-commit-config.yaml)
# repos:
# - repo: https://github.com/semgrep/semgrep
# hooks:
# - id: semgrep
# args: ['--config', 'p/terraform', '--error']
@dataclass
class CIPipeline:
platform: str
config_file: str
trigger: str
policy: str
notification: str
pipelines = [
CIPipeline("GitHub Actions",
".github/workflows/semgrep.yml",
"Every Pull Request",
"Block PR if Critical/High findings",
"PR Comment + Slack #security"),
CIPipeline("GitLab CI",
".gitlab-ci.yml",
"Every MR + Main Branch",
"Block MR if Critical findings",
"Security Dashboard + Email"),
CIPipeline("Pre-commit Hook",
".pre-commit-config.yaml",
"Every git commit (Local)",
"Block commit if Error severity",
"Terminal Output"),
CIPipeline("Jenkins",
"Jenkinsfile",
"Every PR + Nightly Scan",
"Fail Build if Critical findings",
"Slack + Jira Ticket"),
]
print("=== CI/CD Pipelines ===")
for p in pipelines:
print(f" [{p.platform}] Config: {p.config_file}")
print(f" Trigger: {p.trigger}")
print(f" Policy: {p.policy}")
print(f" Notify: {p.notification}")
Dashboard & Metrics
# === Security Metrics ===
@dataclass
class SecurityMetric:
metric: str
target: str
measure: str
improve: str
metrics = [
SecurityMetric("Finding Count",
"ลดลง 10% ต่อเดือน",
"Semgrep Cloud Dashboard Total Findings",
"Fix Critical/High ก่อน ลด Technical Debt"),
SecurityMetric("Mean Time to Fix (MTTF)",
"Critical < 24hr High < 1 week",
"Time from Detection to Fix PR Merged",
"Autofix Rules สำหรับ Common Issues"),
SecurityMetric("Fix Rate",
"> 90% ใน SLA",
"Fixed Findings / Total Findings",
"ตั้ง Policy Block PR ถ้าไม่ Fix"),
SecurityMetric("False Positive Rate",
"< 5%",
"Suppressed / Total Findings",
"Tune Rules ลบ Noisy Rules"),
SecurityMetric("Coverage",
"100% Repos สแกนทุก PR",
"Repos with Semgrep / Total Repos",
"Mandate Semgrep ใน CI/CD ทุก Repo"),
]
print("=== Security Metrics ===")
for m in metrics:
print(f" [{m.metric}] Target: {m.target}")
print(f" Measure: {m.measure}")
print(f" Improve: {m.improve}")
เคล็ดลับ
- Auto: ใช้ semgrep --config auto เริ่มต้นง่ายสุด
- IaC Rulesets: ใช้ p/terraform p/kubernetes p/dockerfile
- Pre-commit: ตั้ง Pre-commit Hook จับก่อน Push
- Policy: Block Critical/High ใน CI/CD ห้าม Merge
- Custom Rules: เขียน Custom Rules สำหรับ Organization Standards
Semgrep คืออะไร
Open Source SAST 30+ Languages IaC Terraform Kubernetes Dockerfile Pattern Matching 3000+ Rules OWASP CWE Fast No Build Free Team
IaC Scanning ทำอย่างไร
semgrep --config p/terraform p/kubernetes p/dockerfile S3 Public SG Open Privileged Root No Limits Encryption Hardcoded Creds
Rules เขียนอย่างไร
YAML Pattern $VAR Metavariable ... Ellipsis pattern-either pattern-not patterns pattern-inside Taint Autofix semgrep --test Registry
CI/CD Integration ทำอย่างไร
GitHub Actions GitLab CI Jenkins Pre-commit semgrep ci Block PR Critical High Policy Slack Jira Dashboard Metrics Fix Rate MTTF
สรุป
Semgrep SAST IaC Terraform Kubernetes Dockerfile Rules Pattern CI/CD GitHub Actions Pre-commit Policy Dashboard Metrics Production