Semgrep SAST Interview Preparation คืออะไร
Semgrep เป็น open source Static Application Security Testing (SAST) tool ที่ช่วยค้นหา bugs, vulnerabilities และ code patterns ในซอร์สโค้ด รองรับกว่า 30 ภาษา (Python, JavaScript, Java, Go, etc.) ด้วย syntax ที่เรียนรู้ง่ายกว่า traditional SAST tools Interview Preparation สำหรับตำแหน่ง Application Security Engineer, DevSecOps Engineer หรือ Security Analyst ต้องเข้าใจทั้ง SAST concepts, Semgrep rules, CI/CD integration และ vulnerability remediation บทความนี้รวบรวมคำถามสัมภาษณ์ แนวทางตอบ และทักษะที่ต้องเตรียม
SAST Fundamentals
# sast_basics.py — SAST fundamentals for interviews
import json
class SASTBasics:
CONCEPTS = {
"sast": {
"name": "SAST (Static Application Security Testing)",
"definition": "วิเคราะห์ซอร์สโค้ดหา vulnerabilities โดยไม่ต้องรันโปรแกรม",
"when": "Development phase (shift-left security)",
"finds": "SQL injection, XSS, hardcoded secrets, insecure patterns",
},
"dast": {
"name": "DAST (Dynamic Application Security Testing)",
"definition": "ทดสอบ application ที่รันอยู่ จากภายนอก (black-box)",
"when": "Testing/Staging phase",
"finds": "Runtime vulnerabilities, misconfigurations, auth issues",
},
"sca": {
"name": "SCA (Software Composition Analysis)",
"definition": "วิเคราะห์ third-party dependencies หา known vulnerabilities",
"when": "Development + CI/CD",
"finds": "CVEs ใน libraries (Log4j, etc.)",
},
"iast": {
"name": "IAST (Interactive AST)",
"definition": "รวม SAST + DAST — instrument code ขณะรัน",
"when": "Testing phase",
"finds": "Runtime + code-level vulnerabilities",
},
}
COMPARISON = {
"sast_vs_dast": {
"sast": "วิเคราะห์ source code, white-box, เร็ว, false positives สูง",
"dast": "ทดสอบ running app, black-box, ช้ากว่า, false positives ต่ำกว่า",
"best": "ใช้ทั้งคู่ — SAST ใน CI + DAST ใน staging",
},
}
def show_concepts(self):
print("=== Security Testing Types ===\n")
for key, concept in self.CONCEPTS.items():
print(f"[{concept['name']}]")
print(f" {concept['definition']}")
print(f" Finds: {concept['finds']}")
print()
def show_comparison(self):
print("=== SAST vs DAST ===")
comp = self.COMPARISON["sast_vs_dast"]
print(f" SAST: {comp['sast']}")
print(f" DAST: {comp['dast']}")
print(f" Best: {comp['best']}")
sast = SASTBasics()
sast.show_concepts()
sast.show_comparison()
Semgrep Deep Dive
# semgrep_deep.py — Semgrep technical details
import json
class SemgrepDeepDive:
ARCHITECTURE = {
"pattern_matching": {
"name": "Pattern Matching Engine",
"description": "ใช้ AST (Abstract Syntax Tree) matching ไม่ใช่ regex",
"benefit": "แม่นยำกว่า grep — เข้าใจ code structure",
},
"rules": {
"name": "Rules (YAML)",
"description": "เขียน rules ด้วย YAML + pattern syntax",
"types": ["pattern", "pattern-either", "pattern-not", "pattern-inside", "metavariable-regex"],
},
"registry": {
"name": "Semgrep Registry",
"description": "4,000+ community rules สำหรับ OWASP Top 10, best practices",
"url": "semgrep.dev/explore",
},
}
CUSTOM_RULE = """
# custom-rule.yaml — Custom Semgrep rule example
rules:
- id: hardcoded-password
patterns:
- pattern: |
password = "$PASSWORD"
- metavariable-regex:
metavariable: $PASSWORD
regex: ".{3,}"
message: "Hardcoded password detected. Use environment variables instead."
languages: [python]
severity: ERROR
metadata:
owasp: "A07:2021 - Identification and Authentication Failures"
cwe: "CWE-798: Use of Hard-coded Credentials"
fix: "Use os.environ.get('PASSWORD') instead"
- id: sql-injection
patterns:
- pattern: |
cursor.execute(f"... {$VAR} ...")
- pattern-not: |
cursor.execute("...", ...)
message: "Potential SQL injection via f-string. Use parameterized queries."
languages: [python]
severity: ERROR
metadata:
owasp: "A03:2021 - Injection"
cwe: "CWE-89: SQL Injection"
- id: insecure-jwt-none
pattern: |
jwt.decode($TOKEN, algorithms=["none"])
message: "JWT decoded with 'none' algorithm. This allows token forgery."
languages: [python]
severity: ERROR
"""
CLI_COMMANDS = """
# Semgrep CLI commands
semgrep --config auto . # Auto config (recommended rules)
semgrep --config p/owasp-top-ten . # OWASP Top 10 rules
semgrep --config p/python . # Python-specific rules
semgrep --config custom-rule.yaml . # Custom rules
semgrep --config auto --json -o results.json . # JSON output
semgrep --config auto --sarif -o results.sarif . # SARIF output (GitHub)
semgrep ci # CI mode (Semgrep Cloud)
"""
def show_architecture(self):
print("=== Semgrep Architecture ===\n")
for key, comp in self.ARCHITECTURE.items():
print(f"[{comp['name']}]")
print(f" {comp['description']}")
print()
def show_rule(self):
print("=== Custom Rule Example ===")
print(self.CUSTOM_RULE[:500])
def show_cli(self):
print(f"\n=== CLI Commands ===")
print(self.CLI_COMMANDS[:400])
semgrep = SemgrepDeepDive()
semgrep.show_architecture()
semgrep.show_rule()
semgrep.show_cli()
Interview Questions & Answers
# interview_qa.py — Interview questions and answers
import json
class InterviewQA:
QUESTIONS = {
"q1": {
"category": "SAST Concepts",
"question": "SAST กับ DAST ต่างกันอย่างไร? เมื่อไหร่ใช้อะไร?",
"answer": "SAST: วิเคราะห์ source code (white-box), ใช้ใน development/CI, เร็ว, false positives สูง DAST: ทดสอบ running app (black-box), ใช้ใน staging, ช้ากว่า, พบ runtime issues ใช้ทั้งคู่: SAST ใน CI pipeline + DAST ใน staging/pre-production",
},
"q2": {
"category": "Semgrep",
"question": "ทำไมเลือก Semgrep แทน SonarQube หรือ Checkmarx?",
"answer": "Semgrep: open source, fast, easy rule writing (YAML), developer-friendly, CI/CD-native SonarQube: mature, code quality + security, heavy setup, enterprise Checkmarx: enterprise SAST, comprehensive, expensive เลือก Semgrep: startup/mid-size, developer-first security, custom rules needed",
},
"q3": {
"category": "Vulnerability",
"question": "อธิบาย SQL Injection และวิธีป้องกัน",
"answer": "SQL Injection: attacker ใส่ SQL code ใน user input เพื่อ manipulate database ป้องกัน: 1) Parameterized queries/prepared statements 2) ORM (SQLAlchemy, Django ORM) 3) Input validation 4) Least privilege DB user Semgrep rule: detect f-string/string concat ใน SQL queries",
},
"q4": {
"category": "CI/CD",
"question": "วาง SAST ใน CI/CD pipeline อย่างไร?",
"answer": "1) PR-level scan: scan เฉพาะ changed files (fast feedback) 2) Main branch scan: full scan ทุก merge 3) Scheduled scan: weekly full scan + new rules 4) Gate: block merge ถ้ามี HIGH/CRITICAL findings 5) Report: ส่ง results ไป dashboard/Slack",
},
"q5": {
"category": "False Positives",
"question": "จัดการ false positives อย่างไร?",
"answer": "1) Triage: review findings แล้ว mark true/false positive 2) Suppress: nosemgrep comment สำหรับ known false positives 3) Custom rules: เขียน rules ที่แม่นยำกว่า (pattern-not) 4) Baseline: ignore existing findings, focus on new code 5) Metrics: track false positive rate แล้ว tune rules",
},
"q6": {
"category": "OWASP",
"question": "OWASP Top 10 2021 มีอะไรบ้าง?",
"answer": "A01: Broken Access Control A02: Cryptographic Failures A03: Injection (SQL, XSS, etc.) A04: Insecure Design A05: Security Misconfiguration A06: Vulnerable Components A07: Auth Failures A08: Software & Data Integrity A09: Logging Failures A10: SSRF Semgrep มี rules ครอบคลุมทุกข้อ (p/owasp-top-ten)",
},
}
def show_questions(self):
print("=== Interview Questions ===\n")
for key, qa in self.QUESTIONS.items():
print(f"[{qa['category']}] Q: {qa['question']}")
print(f" A: {qa['answer'][:120]}...")
print()
def behavioral_tips(self):
print("=== Behavioral Tips ===")
tips = [
"อธิบาย trade-offs ได้ (security vs developer velocity)",
"ยกตัวอย่าง real-world vulnerability ที่เคยพบ",
"แสดงว่าเข้าใจ developer experience (ไม่ block CI โดยไม่จำเป็น)",
"พูดถึง metrics: findings resolved, MTTR, false positive rate",
"แสดง continuous improvement mindset (tune rules, reduce noise)",
]
for tip in tips:
print(f" • {tip}")
qa = InterviewQA()
qa.show_questions()
qa.behavioral_tips()
Hands-on Practice
# practice.py — Hands-on Semgrep practice
import json
class HandsOnPractice:
EXERCISES = {
"ex1": {
"name": "Exercise 1: Find Hardcoded Secrets",
"task": "เขียน Semgrep rule หา hardcoded API keys, passwords, tokens",
"hint": "ใช้ metavariable-regex match patterns like 'sk-...', 'AKIA...'",
},
"ex2": {
"name": "Exercise 2: Detect Insecure Deserialization",
"task": "เขียน rule หา pickle.loads() ที่รับ untrusted input",
"hint": "pattern-inside: function ที่รับ request data → pattern: pickle.loads($X)",
},
"ex3": {
"name": "Exercise 3: CI/CD Integration",
"task": "ตั้ง Semgrep ใน GitHub Actions scan PR แล้ว comment findings",
"hint": "ใช้ semgrep/semgrep-action@v1 + SARIF upload",
},
"ex4": {
"name": "Exercise 4: Custom Rule for Business Logic",
"task": "เขียน rule เฉพาะองค์กร เช่น ห้ามใช้ eval(), ต้อง log ทุก admin action",
"hint": "ใช้ pattern + pattern-not-inside สำหรับ exceptions",
},
}
GITHUB_ACTION = """
# .github/workflows/semgrep.yml
name: Semgrep SAST
on:
pull_request: {}
push:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: semgrep ci
env:
SEMGREP_APP_TOKEN: }
# Alternative: without Semgrep Cloud
- name: Run Semgrep (standalone)
run: |
semgrep --config auto --config p/owasp-top-ten \\
--sarif -o results.sarif .
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
"""
def show_exercises(self):
print("=== Practice Exercises ===\n")
for key, ex in self.EXERCISES.items():
print(f"[{ex['name']}]")
print(f" Task: {ex['task']}")
print(f" Hint: {ex['hint']}")
print()
def show_github_action(self):
print("=== GitHub Actions Setup ===")
print(self.GITHUB_ACTION[:500])
practice = HandsOnPractice()
practice.show_exercises()
practice.show_github_action()
Career & Job Market
# career.py — AppSec career and job market
import json
class AppSecCareer:
ROLES = {
"appsec_engineer": {
"title": "Application Security Engineer",
"salary_th": "60,000-150,000 บาท/เดือน",
"salary_us": "$100,000-180,000/year",
"skills": ["SAST/DAST tools", "Secure code review", "OWASP", "CI/CD security"],
},
"devsecops": {
"title": "DevSecOps Engineer",
"salary_th": "70,000-160,000 บาท/เดือน",
"salary_us": "$110,000-190,000/year",
"skills": ["CI/CD", "Container security", "IaC security", "SAST/SCA"],
},
"security_architect": {
"title": "Security Architect",
"salary_th": "100,000-250,000+ บาท/เดือน",
"salary_us": "$150,000-250,000/year",
"skills": ["Threat modeling", "Security design", "Risk assessment", "Compliance"],
},
}
CERTIFICATIONS = [
{"name": "CSSLP (Certified Secure Software Lifecycle Professional)", "org": "ISC²", "focus": "Secure SDLC"},
{"name": "CEH (Certified Ethical Hacker)", "org": "EC-Council", "focus": "Penetration testing"},
{"name": "OSCP (Offensive Security Certified Professional)", "org": "OffSec", "focus": "Hands-on pentesting"},
{"name": "AWS Security Specialty", "org": "AWS", "focus": "Cloud security"},
]
def show_roles(self):
print("=== AppSec Career Roles ===\n")
for key, role in self.ROLES.items():
print(f"[{role['title']}]")
print(f" Salary (TH): {role['salary_th']}")
print(f" Skills: {', '.join(role['skills'][:3])}")
print()
def show_certs(self):
print("=== Certifications ===")
for cert in self.CERTIFICATIONS:
print(f" [{cert['name']}] {cert['org']} — {cert['focus']}")
career = AppSecCareer()
career.show_roles()
career.show_certs()
FAQ - คำถามที่พบบ่อย
Q: Semgrep เรียนยากไหม?
A: ง่ายกว่า SAST tools อื่น — rule syntax เขียนคล้าย code จริง เริ่มต้น: ใช้ --config auto (rules สำเร็จรูป) 30 นาที ขั้นกลาง: เขียน custom rules ด้วย YAML 1-2 วัน ขั้นสูง: complex patterns, taint analysis 1-2 สัปดาห์ Resources: semgrep.dev/learn (interactive tutorial ดีมาก)
Q: สัมภาษณ์ AppSec ต้องเตรียมอะไร?
A: Technical: OWASP Top 10, SAST/DAST concepts, secure coding, common vulnerabilities Tools: Semgrep, SonarQube, Burp Suite, OWASP ZAP (ใช้ได้จริง) CI/CD: GitHub Actions, Jenkins security integration Soft skills: communicate risk ให้ developers เข้าใจ Hands-on: เตรียม demo — scan project ด้วย Semgrep แล้วอธิบาย findings
Q: SAST tools ตัวไหนเป็นที่ต้องการตลาด?
A: Open source: Semgrep (growing fast), SonarQube (established) Enterprise: Checkmarx, Veracode, Fortify, Snyk Code Cloud-native: GitHub Advanced Security, GitLab SAST แนะนำ: เรียน Semgrep (open source, ใช้ง่าย) + SonarQube (enterprise standard)
Q: AppSec Engineer เงินเดือนเท่าไหร่?
A: ไทย: 60,000-150,000 บาท/เดือน (ขึ้นกับประสบการณ์) Remote (US company): $8,000-15,000/month สิงคโปร์: SGD 8,000-15,000/month Demand สูงมาก supply น้อย — salary trend ขึ้นเรื่อยๆ เพิ่มมูลค่า: coding skills + security knowledge = premium salary
