SiamCafe · Blog
Semgrep SAST Citizen Developer —
บทความ

Semgrep SAST Citizen Developer —

เผยแพร่ 28 พฤษภาคม 2569

Semgrep SAST

Semgrep SAST Static Analysis Security Citizen Developer Custom Rules CI/CD Integration Pattern Matching Vulnerability Scanning Open Source Production

ToolTypeLanguagesSpeedCustom RulesCost
SemgrepSAST30+เร็วมากYAML ง่ายFree OSS / Paid App
SonarQubeSAST + Quality25+ปานกลางJava pluginFree CE / Paid
CodeQLSAST10+ช้าQL languageFree for OSS
Snyk CodeSAST15+เร็วLimitedFree tier / Paid
BanditSAST (Python)Python onlyเร็วPython pluginFree
ESLint SecuritySAST (JS)JS/TS onlyเร็วJS rulesFree

Getting Started

# === Semgrep Installation and Usage ===

# Install
# pip install semgrep
# OR
# brew install semgrep

# Quick scan with auto config (3000+ rules)
# semgrep --config auto .

# Scan with specific ruleset
# semgrep --config p/python .
# semgrep --config p/javascript .
# semgrep --config p/owasp-top-ten .
# semgrep --config p/security-audit .

# Scan single file
# semgrep --config auto app.py

# Output formats
# semgrep --config auto --json -o results.json .
# semgrep --config auto --sarif -o results.sarif .

# Common rulesets:
# p/python          — Python security rules
# p/javascript      — JavaScript security rules
# p/typescript      — TypeScript security rules
# p/owasp-top-ten   — OWASP Top 10 vulnerabilities
# p/security-audit  — Comprehensive security audit
# p/secrets         — Hardcoded secrets detection
# p/ci              — CI-optimized ruleset

from dataclasses import dataclass

@dataclass
class SemgrepFinding:
    rule_id: str
    severity: str
    file: str
    line: int
    message: str
    fix: str

findings = [
    SemgrepFinding("python.lang.security.audit.exec-detected", "WARNING",
        "app.py", 42, "Detected use of exec() which can lead to code injection",
        "Use ast.literal_eval() for safe evaluation"),
    SemgrepFinding("python.django.security.injection.sql-injection", "ERROR",
        "views.py", 85, "SQL injection via string formatting in raw query",
        "Use parameterized queries: cursor.execute(sql, [param])"),
    SemgrepFinding("python.lang.security.audit.hardcoded-password", "WARNING",
        "config.py", 12, "Hardcoded password detected in source code",
        "Use environment variables: os.environ.get('DB_PASSWORD')"),
    SemgrepFinding("javascript.express.security.xss.reflected-xss", "ERROR",
        "routes/api.js", 23, "User input directly rendered without sanitization",
        "Use DOMPurify or escape output before rendering"),
]

print("=== Semgrep Scan Results ===")
for f in findings:
    print(f"  [{f.severity}] {f.rule_id}")
    print(f"    File: {f.file}:{f.line}")
    print(f"    Issue: {f.message}")
    print(f"    Fix: {f.fix}")

Custom Rules

=== Custom Semgrep Rules ===

rules/sql-injection.yaml

rules:

  • id: custom-sql-injection

pattern: |

cursor.execute($QUERY)

pattern-not: |

cursor.execute($QUERY, $PARAMS)

message: >

SQL query without parameterized arguments detected.

Use cursor.execute(query, [params]) to prevent SQL injection.

severity: ERROR

languages: [python]

metadata:

category: security

owasp: A03:2021 Injection

  • id: custom-hardcoded-secret

patterns:

  • pattern: |

$VAR = "..."

  • metavariable-regex:

metavariable: $VAR

regex: (password|secret|api_key|token|auth)

message: >

Possible hardcoded secret in variable '$VAR'.

Use environment variables instead.

severity: WARNING

languages: [python]

  • id: custom-insecure-random

pattern: random.random()

fix: secrets.token_hex(32)

message: >

Using random.random() for security purposes is insecure.

Use secrets module instead.

severity: WARNING

languages: [python]

Test custom rules:

semgrep --config rules/ --test

Run custom rules:

semgrep --config rules/ src/

@dataclass

class CustomRule:

rule_id: str

pattern: str

severity: str

category: str

languages: str

rules = [

CustomRule("no-eval", "eval($X)", "ERROR", "Code Injection", "python javascript"),

CustomRule("no-exec", "exec($X)", "ERROR", "Code Injection", "python"),

CustomRule("sql-injection", "cursor.execute(f'...')", "ERROR", "Injection", "python"),

CustomRule("hardcoded-secret", "$VAR = '...' (regex: password|key)", "WARNING", "Secrets", "python javascript"),

CustomRule("insecure-random", "random.random()", "WARNING", "Crypto", "python"),

CustomRule("no-debugger", "debugger", "WARNING", "Debug Code", "javascript"),

CustomRule("open-redirect", "redirect(request.args.get(...))", "ERROR", "Redirect", "python"),

]

print("\n=== Custom Rules Library ===")

for r in rules:

print(f" [{r.rule_id}] Severity: {r.severity} | Category: {r.category}")

print(f" Pattern: {r.pattern}")

print(f" Languages: {r.languages}")

CI/CD Integration

=== CI/CD Pipeline Integration ===

GitHub Actions

.github/workflows/semgrep.yml

name: Semgrep Security Scan

on: [pull_request]

jobs:

semgrep:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v4
  • uses: returntocorp/semgrep-action@v1

with:

config: >-

p/security-audit

p/secrets

generateSarif: true

  • uses: github/codeql-action/upload-sarif@v3

with:

sarif_file: semgrep.sarif

CircleCI

.circleci/config.yml

jobs:

security-scan:

docker:

  • image: returntocorp/semgrep

steps:

  • checkout
  • run:

name: Semgrep Scan

command: semgrep ci --config auto

GitLab CI

.gitlab-ci.yml

semgrep:

image: returntocorp/semgrep

script:

  • semgrep ci --config auto

rules:

  • if: $CI_MERGE_REQUEST_IID

@dataclass

class PolicyConfig:

severity: str

action: str

notify: str

auto_fix: bool

policies = [

PolicyConfig("CRITICAL", "Block PR / Block Deploy", "Slack #security + PagerDuty", False),

PolicyConfig("ERROR", "Block PR", "Slack #security + Comment on PR", False),

PolicyConfig("WARNING", "Comment on PR", "Slack #dev-alerts", False),

PolicyConfig("INFO", "Log only", "Dashboard only", False),

]

print("Security Policy:")

for p in policies:

print(f" [{p.severity}] Action: {p.action}")

print(f" Notify: {p.notify}")

เคล็ดลับ

  • Auto: เริ่มด้วย --config auto สแกน 3000+ Rules ทันที
  • CI: ใส่ Semgrep ใน CI/CD ทุก PR อัตโนมัติ
  • Custom: เขียน Custom Rule สำหรับ Pattern เฉพาะองค์กร
  • Policy: กำหนด Policy ว่า Severity ไหน Block Deploy
  • False Positive: ใช้ pattern-not ลด False Positive

Semgrep SAST คืออะไร

Static Analysis Security Open Source สแกนช่องโหว่โค้ด 30+ ภาษา Pattern Matching YAML Rule Registry 3000+ CI/CD Pipeline เร็ว Monorepo