Keamanan bukan sekadar patch rutin — ini tentang membangun sistem yang resisten terhadap serangan sejak hari pertama. AI mempercepat dan memperkuat setiap lapisan security testing.
Memasang gembok pintu rumah mungkin biaya Rp100.000. Jika rumah dibobol dan barang senilai Rp50 juta dicuri, ditambah trauma dan reputasi, biayanya ribuan kali lipat. Security testing seperti memasang gembok, alarm, kamera — mahal dibanding tidak ada, tapi murah dibanding akibat pencurian.
Rata-rata biaya data breach global tahun 2023: USD 4.45 juta per insiden (IBM Cost of Data Breach Report). Bandingkan dengan biaya investasi security testing tahunan yang jauh lebih kecil.
WHO menerbitkan daftar penyakit paling mematikan agar rumah sakit memprioritaskan pencegahan dan penanganannya. OWASP Top 10 adalah "daftar penyakit paling mematikan" untuk aplikasi web — diterbitkan setiap beberapa tahun berdasarkan data serangan nyata dari ribuan organisasi. Setiap developer wajib mengenal dan tahu cara mencegah kerentanan ini.
SAST seperti insinyur yang memeriksa blueprint dan struktur bangunan di atas kertas sebelum dibangun — menemukan kelemahan tanpa perlu masuk ke dalam. DAST seperti penyusup yang mencoba masuk ke gedung yang sudah jadi — menguji pertahanan nyata dengan serangan simulasi. IAST seperti sensor di dalam gedung yang merekam semua pergerakan saat bangunan digunakan — menemukan kelemahan dari dalam saat runtime.
| Aspek | SAST (Static) | DAST (Dynamic) | IAST (Interactive) |
|---|---|---|---|
| Kapan berjalan | Saat coding / commit, tanpa menjalankan aplikasi | Saat aplikasi berjalan di staging/test env | Saat integration/QA testing (runtime) |
| Apa yang dianalisis | Source code, bytecode, binary | HTTP request/response, live application | Data flow internal aplikasi saat runtime |
| False positive | Tinggi — tidak tahu runtime context | Rendah — hanya lapor kerentanan yang benar-benar bisa dieksploitasi | Sangat rendah — tahu persis konteks eksekusi |
| Cakupan OWASP | A02, A03, A05, A06 sangat bagus | A01, A03, A07 sangat bagus | A03, A04, A08 sangat bagus |
| Tools populer | SonarQube, Semgrep, Bandit (Python), Checkmarx | OWASP ZAP, Burp Suite, Nikto, Nuclei | Contrast Security, Seeker, Hdiv |
| Kapan gunakan | Di setiap commit — integrasi ke CI/CD pipeline | Sebelum release, pentest reguler | Saat QA testing berlangsung |
Semgrep menggunakan pattern matching berbasis AST (Abstract Syntax Tree) untuk mendeteksi pola kode berbahaya. Sangat cepat, bisa dikustomisasi dengan rules sendiri.
ZAP (Zed Attack Proxy) adalah tool DAST open source paling populer. Bisa dijalankan dalam mode headless via API untuk integrasi CI/CD.
Fuzzing tradisional: Seperti pencuri yang mencoba ribuan kunci secara acak satu per satu — cepat jika kunci yang dicari sederhana, tapi lambat untuk kunci yang kompleks.
AI fuzzing: Seperti pencuri yang belajar — setiap kunci yang hampir berhasil dieksplorasi lebih lanjut, setiap kunci yang jelas salah dibuang. AI fuzzer seperti AFL++ dan LibFuzzer menggunakan code coverage sebagai feedback untuk secara cerdas memilih input berikutnya yang paling mungkin menemukan bug baru.
DevOps tanpa security: Seperti restoran yang memeriksa keamanan makanan hanya di meja kasir — terlambat, mahal untuk diperbaiki, dan sering terlewat.
DevSecOps: Seperti memeriksa kualitas bahan di pasar, kebersihan dapur saat memasak, standar sajian sebelum ke meja, dan feedback dari tamu — keamanan ada di setiap langkah. Masalah ditemukan lebih awal = biaya perbaikan jauh lebih murah.
SCA (Software Composition Analysis): Analisis dependensi open source untuk menemukan CVE yang diketahui. Tools seperti Snyk dan OWASP Dependency-Check secara otomatis mengecek apakah library yang digunakan memiliki kerentanan yang sudah dipublikasi.
STRIDE (Microsoft) membantu mengidentifikasi ancaman secara sistematis dengan memetakan setiap komponen sistem ke 6 kategori ancaman.
# ================================================================
# S11409 - Sesi 13: Security Testing Cerdas
# Mini SAST Scanner + Secure Coding Patterns
# Dosen: Riadi Marta Dinata, S.Ti., M.Kom. | ISTN Jakarta
# ================================================================
import re, ast, hashlib, hmac, secrets
from dataclasses import dataclass
from typing import List, Tuple
# ── BAGIAN 1: MINI SAST SCANNER ──────────────────────────────
@dataclass
class SecurityFinding:
severity: str # CRITICAL / HIGH / MEDIUM / LOW
rule_id: str
message: str
line: int
code: str
class MiniSASTScanner:
"""
Scanner SAST ringan berbasis pattern matching.
Mendeteksi pola kode berbahaya sesuai OWASP Top 10.
"""
RULES = [
# A03: SQL Injection
("CRITICAL", "A03-SQLi",
r'(execute|query)\s*\(["\'][^"\']*["\'\+]\s*\w',
"SQL query dengan string concatenation — risiko SQL Injection"),
# A02: Hardcoded credentials
("CRITICAL", "A02-HardCred",
r'(password|passwd|secret|api_key)\s*=\s*["\'][^"\']{6,}["\']',
"Hardcoded credential — jangan commit ke repository!"),
# A02: Weak hashing
("HIGH", "A02-WeakHash",
r'\b(md5|sha1)\s*\(',
"Algoritma hash lemah (MD5/SHA1) — gunakan bcrypt atau SHA-256+"),
# A05: Debug mode
("HIGH", "A05-Debug",
r'DEBUG\s*=\s*True',
"Debug mode aktif — jangan di production!"),
# A03: Command injection
("CRITICAL", "A03-CMDi",
r'(os\.system|subprocess\.call|eval|exec)\s*\([^)]*\+',
"Potensi command/code injection"),
# A05: Sensitive data in URL
("MEDIUM", "A09-URLParam",
r'(password|token|secret)=["\']?\w',
"Data sensitif di URL parameter — gunakan body/header"),
# A02: No SSL verification
("MEDIUM", "A02-NoSSL",
r'verify\s*=\s*False',
"SSL verification dinonaktifkan — rentan MITM attack"),
# A07: No rate limiting hint
("LOW", "A07-NoLimit",
r'def\s+(login|authenticate|signup)\s*\(',
"Fungsi auth terdeteksi — pastikan ada rate limiting"),
]
def scan_code(self, code: str, filename="") -> List[SecurityFinding]:
findings = []
lines = code.split('\n')
for line_num, line in enumerate(lines, 1):
for severity, rule_id, pattern, message in self.RULES:
if re.search(pattern, line, re.IGNORECASE):
findings.append(SecurityFinding(
severity=severity, rule_id=rule_id,
message=message, line=line_num,
code=line.strip()
))
return findings
def report(self, findings: List[SecurityFinding], filename: str):
if not findings:
print(f" [OK] {filename}: No security issues found!")
return
sev_order = {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3}
findings.sort(key=lambda f: sev_order.get(f.severity, 9))
print(f"\n Security scan: {filename}")
print(f" Found {len(findings)} issue(s)\n")
for f in findings:
icon = {"CRITICAL":"!!","HIGH":"! ","MEDIUM":"* ","LOW":"- "}
print(f" [{icon.get(f.severity,'?')}] [{f.severity:<8}] Line {f.line} | {f.rule_id}")
print(f" {f.message}")
print(f" Code: {f.code[:70]}")
print()
# ── BAGIAN 2: VULNERABLE CODE CONTOH ─────────────────────────
VULNERABLE_CODE = '''
import sqlite3, hashlib, os
DEBUG = True
API_KEY = "sk-prod-abc123xyz789secret"
def login(username, password):
conn = sqlite3.connect("siakad.db")
# VULNERABLE: SQL Injection!
query = "SELECT * FROM users WHERE username = '" + username + "'"
result = conn.execute(query)
# VULNERABLE: MD5 hash yang lemah!
hashed = hashlib.md5(password.encode()).hexdigest()
return result.fetchone()
def reset_password(token, new_password):
# VULNERABLE: SSL verification off!
import requests
requests.post("https://api.istn.ac.id/reset",
data={"token": token, "password": new_password},
verify=False)
'''
# ── BAGIAN 3: SECURE CODE YANG BENAR ─────────────────────────
def secure_login_demo(username: str, password: str) -> dict:
"""
Demonstrasi secure coding practices:
1. Parameterized query (anti SQL injection)
2. bcrypt / hashlib.pbkdf2 (secure password hashing)
3. Constant-time comparison (anti timing attack)
"""
import sqlite3, hashlib, os
# SECURE: Parameterized query — tidak bisa di-inject
# conn.execute("SELECT * FROM users WHERE username = ?", (username,))
# SECURE: PBKDF2 dengan salt acak — jauh lebih kuat dari MD5
salt = os.urandom(32)
key = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100_000)
stored = salt + key # simpan keduanya bersama
# SECURE: Verifikasi dengan hmac.compare_digest (constant-time)
# Mencegah timing attack yang bisa menebak password karakter per karakter
test_key = hashlib.pbkdf2_hmac('sha256', password.encode(),
stored[:32], 100_000)
is_valid = hmac.compare_digest(key, test_key)
# SECURE: Generate secure token untuk session
session_token = secrets.token_urlsafe(32)
return {
"authenticated": is_valid,
"session_token": session_token,
"note": "Token hanya berlaku 30 menit, rotasi setelah digunakan"
}
def validate_input_demo(user_input: str) -> Tuple[bool, str]:
"""Input validation untuk mencegah injection"""
# Whitelist approach: hanya izinkan karakter yang diharapkan
import re
if not re.match(r'^[a-zA-Z0-9._@-]{3,50}$', user_input):
return False, "Input tidak valid — hanya huruf, angka, . _ @ - diperbolehkan"
# Sanitize: escape karakter HTML untuk mencegah XSS
sanitized = (user_input
.replace('&', '&')
.replace('<', '<')
.replace('>', '>')
.replace('"', '"'))
return True, sanitized
# ── MAIN ──────────────────────────────────────────────────────
print("=" * 60)
print(" SECURITY TESTING DEMO")
print(" S11409 ISTN Jakarta | Sesi 13")
print("=" * 60)
scanner = MiniSASTScanner()
print("\n[1] SAST Scan — Vulnerable Code:")
findings = scanner.scan_code(VULNERABLE_CODE, "siakad_auth.py")
scanner.report(findings, "siakad_auth.py")
print("[2] Secure Coding Demo:")
result = secure_login_demo("mahasiswa@istn.ac.id", "P@ssw0rd123")
print(f" Authenticated : {result['authenticated']}")
print(f" Session token : {result['session_token'][:20]}...")
print("\n[3] Input Validation:")
test_inputs = [
"riadi.marta@istn.ac.id",
"'; DROP TABLE users; --",
"",
"NIM_2024001",
]
for inp in test_inputs:
valid, result = validate_input_demo(inp)
status = "SAFE" if valid else "BLOCKED"
print(f" [{status}] {inp[:40]:<40} -> {result[:30]}")
print("\nDone! Security scan selesai.")
Identifikasi kategori OWASP Top 10 untuk setiap skenario berikut: (a) SIAKAD menampilkan stack trace PHP lengkap saat error, (b) mahasiswa bisa akses nilai mahasiswa lain dengan mengubah angka di URL, (c) library Symfony versi lama yang punya CVE terkenal masih digunakan, (d) form login tidak memiliki CAPTCHA atau rate limiting sama sekali.
Kode PHP berikut: $query = "SELECT * FROM mahasiswa WHERE nim = '" . $_GET['nim'] . "'"; (a) Jelaskan bagaimana attacker bisa mengeksploitasi ini untuk mengeluarkan semua data tabel, (b) Tulis versi yang aman menggunakan prepared statement, (c) Bagaimana SAST tool mendeteksi pattern ini tanpa menjalankan kode?
Tim dev SIAKAD berencana menambahkan security testing ke pipeline CI/CD. Buat rekomendasi: (a) Tool SAST apa yang cocok untuk codebase PHP dan Python? (b) Di tahap mana CI/CD pipeline SAST dan DAST dijalankan? (c) Bagaimana menangani false positive SAST yang tinggi tanpa mengabaikan peringatan penting?
Lakukan threat modeling STRIDE untuk fitur "Upload Foto Profil Mahasiswa" di SIAKAD: untuk setiap 6 kategori STRIDE, identifikasi (a) ancaman yang relevan, (b) dampak jika berhasil dieksploitasi, dan (c) mitigasi yang harus diimplementasikan.
Perluas MiniSASTScanner di atas: (a) Tambahkan rule untuk mendeteksi XSS — output HTML tanpa escaping, (b) Tambahkan rule untuk mendeteksi hardcoded IP address atau URL production di kode, (c) Implementasikan severity scoring — hitung risk score total file (CRITICAL=10, HIGH=7, MEDIUM=4, LOW=1) dan tentukan apakah file "PASS", "WARN", atau "FAIL" berdasarkan skor.
OWASP Top 10 adalah referensi wajib — A01 Broken Access Control, A03 Injection, dan A02 Cryptographic Failures adalah prioritas utama untuk sistem akademik
SAST menemukan bug lebih awal dan murah; DAST membuktikan kerentanan yang bisa dieksploitasi — gunakan keduanya, bukan pilih salah satu
AI fuzzing menggunakan coverage feedback untuk secara cerdas mengeksplorasi state space program — jauh lebih efektif dari random fuzzing
DevSecOps bukan "security di akhir" — setiap tahap pipeline punya tanggung jawab security: SAST di commit, SCA di build, DAST di test, IaC scan di deploy
STRIDE framework membantu berpikir sistematis seperti attacker: Spoofing, Tampering, Repudiation, Information Disclosure, DoS, Elevation of Privilege
Parameterized queries + PBKDF2 + constant-time comparison adalah tiga secure coding practice paling penting untuk sistem autentikasi
⚠️ Etika Security Testing: Semua teknik yang dipelajari di sesi ini (fuzzing, injection testing, DAST) hanya boleh diterapkan pada sistem yang Anda miliki izin eksplisit untuk mengujinya. Menguji sistem orang lain tanpa izin adalah tindakan ilegal dan melanggar UU ITE.