</>Học Dev
Bài học

Tuần 4 - Ngày 23: Logging, Audit và Incident Response

Tuần 4 – Ngày 23

Mục tiêu học tập

  • Xác định các sự kiện security-relevant cần log (auth, privileged action, data access, config change)
  • Tránh leak PII/secret vào log — redact và structured logging với schema
  • Thiết kế centralized log: ELK, Splunk, Datadog, CloudWatch Logs với retention requirement
  • Hiểu SIEM: correlation rules, alerting, threat intel
  • Áp dụng NIST Incident Response lifecycle: Preparation → Detection → Containment → Eradication → Recovery → Lessons Learned
  • Chuẩn bị runbook, on-call rotation, tabletop exercise
  • Forensics 101: preserve evidence, chain of custody, timeline reconstruction
  • GDPR breach notification 72h và các regulation tương tự

1. Log gì cho mục đích security?

Không phải mọi log đều có giá trị security. Tập trung vào sự kiện có thể giúp detect, investigate, prove:

Loại eventVí dụVì sao quan trọng
AuthenticationLogin success/fail, MFA challenge, password resetBrute force, credential stuffing detection
AuthorizationAccess denied, role assumption, privilege escalationPhát hiện horizontal/vertical privilege abuse
Privileged actionsudo, admin user tạo IAM key, modify firewall ruleInsider threat, post-compromise activity
Data accessQuery database, S3 GetObject với PII, export reportGDPR audit, data exfiltration detect
Configuration changeIAM policy modified, SG rule added, deploy productionChange tracking, blame-free root cause
Security tool eventWAF block, IDS alert, EDR detection, AV quarantineActive attack indicator
Application error5xx, exception stack trace với security contextVulnerability exploitation evidence

Minimum log fields cho mỗi event

{
  "timestamp": "2025-06-05T10:23:45.123Z",     // ISO 8601 UTC + millisecond
  "event_id": "auth.login.success",
  "actor": {                                     // ai
    "user_id": "u_12345",
    "session_id": "s_abc...",
    "ip": "203.0.113.42",
    "user_agent": "Mozilla/5.0..."
  },
  "action": "login",                             // làm gì
  "resource": "user/u_12345",                    // trên cái gì
  "result": "success",                           // kết quả
  "request_id": "req_xyz...",                    // để correlate với upstream/downstream
  "trace_id": "trace_abc...",                    // distributed tracing
  "metadata": {
    "mfa_used": true,
    "method": "password"
  }
}

Why structured (JSON)? SIEM/Log platform query field cụ thể (event_id:auth.login.fail AND actor.ip:203.0.113.42). Plain text log → grep chậm + không reliable parse.


2. PII và secret trong log — Redact!

Bài toán

# ❌ BAD
logger.info(f"User signup: {request.json}")
# → log có email, password, credit card đầy đủ
2025-06-05T10:23:45Z INFO User signup: {"email":"alice@example.com","password":"hunter2","ssn":"123-45-6789","cc":"4111-1111-1111-1111"}

Hậu quả: log file leak (CloudWatch Logs IAM misconfig, S3 export public, dev workstation pwned) = leak PII của hàng ngàn user → GDPR fine 4% revenue.

Redact pattern

# Allow-list approach: chỉ log field đã approve
ALLOWED_FIELDS = {"user_id", "email_hash", "role", "country"}

def safe_log(event, payload):
    safe_payload = {k: v for k, v in payload.items() if k in ALLOWED_FIELDS}
    logger.info(event, extra=safe_payload)

# Hoặc deny-list — xoá field nhạy cảm
SENSITIVE = {"password", "ssn", "credit_card", "api_key", "token"}

def redact(payload):
    return {k: ("***REDACTED***" if k in SENSITIVE else v) for k, v in payload.items()}

Pino (Node) redact built-in

import pino from "pino";

const logger = pino({
  redact: {
    paths: [
      "password",
      "*.password",
      "req.headers.authorization",
      "req.headers.cookie",
      "user.ssn",
      "user.creditCard.number",
    ],
    censor: "[REDACTED]",
  },
});

logger.info({ user: { email: "a@x.com", ssn: "123-45-6789" } });
// → user.ssn = "[REDACTED]"

Email/identifier — hash thay vì plain

import hashlib

def email_hash(email):
    return hashlib.sha256(email.lower().strip().encode()).hexdigest()[:16]

logger.info("user.login", extra={"email_hash": email_hash(user.email)})
# → giữ được khả năng correlate request từ cùng user mà không lộ email

Log filter / processor layer

Đặt filter tại pipeline (Fluentd, Vector, Logstash) — xoá field nhạy cảm trước khi vào index. Nếu app log "nhầm", filter vẫn cứu được.

# Vector config — drop field
[transforms.redact]
type = "remap"
inputs = ["app-logs"]
source = '''
  del(.password)
  del(.credit_card)
  if exists(.ssn) { .ssn = "***" }
'''

3. Centralized logging và retention

Kiến trúc

App1App2AppNLogAgent(Fluentd/Vector/CloudWatchAgent)ShipCentralizedPlatformELK/Splunk/Datadog/CloudWatch/Loki/OpenSearchSearch/UIAlertingLong-term(Kibana)(PagerDuty)Archive(S3Glacier)

Lựa chọn platform

PlatformĐặc điểmUse case
ELK / Elastic StackOSS, self-host, mạnhTeam có DevOps capacity
SplunkEnterprise, mạnh SIEM/SOARCompliance, regulated industry
Datadog LogsSaaS, tích hợp APM/metricCloud-native, không muốn ops
AWS CloudWatch LogsAWS-native, Logs Insights queryTích hợp AWS service, ít volume
Grafana LokiOSS, label-based, rẻKhi log volume lớn, query metric-style
OpenSearchAWS fork của ElasticAvoiding Elastic license, AWS native

Retention requirement

StandardRetention
PCI-DSS1 year online, 3 months immediately accessible
HIPAA6 years
SOX7 years
GDPR"Storage limitation" — không quá thời gian cần thiết, thường 6-24 tháng
ISO 27001Định nghĩa trong policy (thường 1-3 years)

Hot/Warm/Cold tier

Hottier(0-30day)SSDindex,fastquery,expensiveWarmtier(30-90day)Slowerdisk,infrequentqueryColdtier(90day-1year)S3/Glacier,archive,slowrestore
# AWS CloudWatch — Logs Group với retention 365 ngày
aws logs put-retention-policy \
  --log-group-name /aws/lambda/api \
  --retention-in-days 365

# Export sang S3 (cheaper long-term)
aws logs create-export-task \
  --log-group-name /aws/lambda/api \
  --from $(date -d "30 days ago" +%s)000 \
  --to $(date +%s)000 \
  --destination security-logs-archive-bucket \
  --destination-prefix lambda-api/

Log integrity

Log có thể bị attacker xoá để cover track. Bảo vệ:

  • Append-only / WORM (Write Once Read Many): S3 Object Lock, immutable index
  • Off-host: ship log đi khỏi server trước khi attacker chiếm máy
  • CloudTrail Lake / log signing: hash chain, không ai chỉnh sửa được
  • Centralized + RBAC: log platform tách hoàn toàn account production

4. SIEM — Security Information & Event Management

SIEM = log aggregation + correlation + alerting + investigation UI cho security.

Core capabilities

LogsNormalizeEnrichCorrelateAlertInvestigate"5failedlogin+1successfromsameIPin1min""IAMroleassumedfromunusualIP""S3GetObject10000obj/minbyuserwithnohistory"GeoIP,threatintelfeed,assetDBUsercontext(role,department)Maptoschema:ECS,CIM,OCSF

Tool

SIEMĐặc điểm
Splunk Enterprise SecurityIndustry leader, đắt
Microsoft SentinelCloud-native, Azure-integrated, pay-per-GB
Elastic SecurityFree tier, OSS base
Datadog Cloud SIEMSaaS, gắn với observability stack
AWS Security Lake + AthenaCheap storage + ad-hoc query, không real-time alerting
WazuhOSS HIDS + SIEM-lite

Correlation rule ví dụ

-- Splunk SPL: brute force attempt
index=auth event_id="auth.login.fail"
| stats count by actor.ip, _time span=5m
| where count >= 10
| eval risk=case(count >= 50, "high", count >= 20, "medium", true(), "low")
# Elastic detection rule (KQL)
event.category:authentication AND event.outcome:failure
| histogram time=5m
| where count() >= 10

Alert fatigue

Nguy cơ lớn nhất của SIEM: ngày 100 alert → analyst burnout → bỏ qua → miss real attack.

Anti-pattern: bật rule "kitchen sink", thresholding ngẫu nhiên
            → 100 alert/ngày, 95% là benign

Best practice:
  1. Tune threshold theo baseline (5σ above normal)
  2. Suppress known-benign source (vd: vulnerability scanner IP)
  3. Severity-based routing (critical → PagerDuty, low → ticket queue)
  4. Auto-close alert đã resolved trong 24h không re-trigger
  5. Run-book gắn với mỗi alert: ai investigate, làm gì

5. Incident Response Lifecycle (NIST SP 800-61)

1.PreparationRunbook,training,on-call,tools,commchannel2.Detection&AnalysisAlerttriage,scopeassessment,severityrating3.ContainmentShort-term:isolatehost,revokesessionLong-term:patch,rotatecred,fixrootcause4.EradicationRemovemalware,closelateralmovement,killC25.RecoveryRestoreservice,monitorforre-infection6.Post-Incident(LessonsLearned)Blamelesspost-mortem,actionitems,updaterunbookloopbacktoPreparation

Severity matrix (ví dụ)

SeverityĐịnh nghĩaResponse SLA
SEV-1 CriticalProduction down, data breach, ransomware active< 15 phút, all-hands
SEV-2 HighPartial outage, suspicious activity confirmed< 1 giờ
SEV-3 MediumSingle component degraded, possible threat< 4 giờ
SEV-4 LowCosmetic, FYINext business day

Roles trong incident

RoleTrách nhiệm
Incident Commander (IC)Quyết định, không tự fix — coordinate
Tech LeadHands-on debug, propose fix
Communications LeadUpdate status page, notify stakeholder, customer
ScribeGhi timeline, decisions, commands chạy
Subject Matter ExpertsOn-demand cho component liên quan

6. Runbook, on-call, tabletop exercise

Runbook

Tài liệu cho từng loại incident — không phải design doc, không phải full architecture. Chỉ "khi alert X kêu, làm 1, 2, 3".

# Runbook: Suspicious S3 download spike

## Symptom
CloudTrail GetObject count > 5σ above baseline trong 5 phút từ một IAM user/role.

## Severity
SEV-2 default. Bump lên SEV-1 nếu bucket chứa PII (data-classification: confidential).

## Triage (5 phút đầu)
1. Identify actor: `aws cloudtrail lookup-events --lookup-attributes ...`
2. Check actor history: thông thường action gì? Lần đầu access bucket này?
3. Check source IP: GeoIP, có trong VPN range không?

## Containment
- Nếu IAM user: disable access key

aws iam update-access-key --access-key-id AKIA... --status Inactive --user-name

- Nếu IAM role: detach permission policy hoặc revoke session

aws iam put-role-policy --role-name --policy-name DenyAll --policy-document file://deny-all.json

- Block IP via WAF/SG nếu xác định malicious

## Eradication
- Rotate compromised credential
- Audit other resources actor đã access trong 7 ngày qua

## Recovery
- Re-enable access sau khi rotate + verify nguyên nhân
- Monitor 24h cho hành vi tương tự

## Escalation
- Bucket có PII → notify DPO trong 12h (chuẩn bị GDPR 72h notification)
- Bucket có PCI data → notify card brand qua PCI process

On-call rotation

Primary on-call: nhận page đầu tiên, response < 15 phút (SEV-1)
Secondary: backup nếu primary không acknowledge sau N phút
Manager on-call: escalation cho decision business (PR, customer comm)

Tool: PagerDuty, Opsgenie, Splunk On-Call
Pattern: weekly rotation, follow-the-sun cho global team

Tabletop exercise

Diễn tập trên giấy (không thực sự chạy production). 1 lần/quý. Scenario ví dụ:

  1. Facilitator: "Lúc 3AM Sunday, CloudTrail detect IAM user ci-deploy tạo 50 EC2 instance ở region eu-central-1 (region không dùng). Bạn nhận page. Làm gì?"
  2. Team discuss step-by-step: ai làm gì, lệnh gì chạy, escalate ai
  3. Facilitator inject tình huống mới ("EC2 đang chạy crypto miner", "AWS bill đã +$5000")
  4. Hậu tabletop: ghi nhận gap (vd: không biết ai có quyền revoke IAM, không có runbook cho EC2 mass-creation) → tạo action item

7. Forensics 101

Khi có incident nghiêm trọng (data breach, ransomware), bằng chứng phải được preserve để:

  • Phân tích root cause
  • Trình toà nếu có liên quan pháp lý
  • Báo cáo regulator

Nguyên tắc Chain of Custody

Mỗi vật chứng (disk image, log file, memory dump) phải có:
  - Who collected: tên, ID, timestamp
  - From where: hostname, IP, path
  - How: command sử dụng (vd: dd, fmem)
  - Hash integrity: SHA-256 ngay khi collect
  - Storage: ai access từ thời điểm collect đến giờ
  - Each transfer: signed log
# Collect EC2 disk image (snapshot EBS)
aws ec2 create-snapshot --volume-id vol-abc123 \
  --description "IR-2025-06-05 host-compromise"

# Hash snapshot for integrity
aws ec2 describe-snapshots --snapshot-ids snap-xyz | sha256sum > evidence.sha256

# Memory dump (Linux)
sudo ./avml memory.dump      # Microsoft AVML tool
sha256sum memory.dump >> evidence.sha256

Timeline reconstruction

Timeline(UTC)14:23:01CloudTrail:GetCallerIdentityfrom203.0.113.4214:23:15IAM:AccessKeyAKIA...createdforuserbob14:24:02S3:GetObjectfromnewkey,1000obj/minspike14:25:30GuardDutyalert:anomalousdataaccess14:26:00On-callpaged14:28:14IAM:Disableaccesskey(containment)14:30:45Log:50000objdownloaded(10GBtotal)Reconstruct:"Bob'slaptoppwnedat14:20viaphishing,attackerstoleAWScredentials,creatednewkeyat14:23topersist..."

Tool: Plaso/log2timeline (super timeline), Splunk SPL transaction command, Datadog timeline view.

Live vs Dead forensics

  • Live (host running): capture memory, network connection, running process. Mất nếu reboot. Rủi ro: hành động bạn để lại dấu vết.
  • Dead (offline): image disk, analyze offline. Mất evidence in-memory (decrypted secret, network state).

Best practice IR: snapshot trước (preserve state) → isolate (revoke creds, NSG block) → investigate trên snapshot copy, không trên prod.


8. GDPR 72-hour breach notification

GDPR Article 33: nếu personal data breach có "likely risk to rights and freedoms", controller phải notify Data Protection Authority (DPA) trong 72 giờ kể từ khi aware (không phải khi xảy ra).

T+0    : Detection (vd: alert hoặc tipoff)
T+24h  : Initial assessment — scope, data type, count
T+48h  : Containment + impact analysis
T+72h  : Notify DPA + (nếu high risk) notify data subject

         Nếu chưa đủ thông tin → notify "preliminary" với
         thông tin có, hứa supplement sau.

Nội dung notification phải bao gồm:

  • Bản chất breach, loại data, ước lượng số người ảnh hưởng
  • Tên + contact của DPO
  • Hậu quả khả dĩ
  • Biện pháp đã/sẽ thực hiện

Tương đương:

  • CCPA / California: tương tự GDPR nhưng cho residents California
  • HIPAA (US): notify HHS trong 60 ngày
  • PCI-DSS: notify card brand "immediately" — định nghĩa bởi brand
  • Vietnam Nghị định 13/2023: notify Bộ Công An trong 72h, tương tự GDPR

Implication cho dev: log + audit phải sẵn sàng để trả lời "data nào bị access, bởi ai, khi nào, bao nhiêu record" trong < 72h. Đây là lý do log everything security-relevant và keep ≥ 1 năm.


9. Câu hỏi ôn tập

  1. Tại sao structured logging (JSON) tốt hơn plain text cho mục đích security?

    Xem đáp án

    SIEM/Log platform query field cụ thể: event.category:auth AND user.id:u_123 AND source.ip:203.0.113.42. Plain text phải dùng regex grep — chậm, không reliable (vd email Alice@Example.com vs ALICE@example.com), không aggregate được (vd "đếm distinct IP"). Structured log còn cho phép correlate cross-service qua trace_id, request_id.

    Schema chuẩn: ECS (Elastic Common Schema), OCSF (Open Cybersecurity Schema Framework), CIM (Splunk).

  2. PII trong log nguy hiểm vì sao và làm sao redact đúng?

    Xem đáp án

    Log thường được index ở nhiều nơi (CloudWatch, SIEM, archive), nhiều người access cho debug. PII trong log = PII trong nhiều system → 1 log platform bị compromise = leak hàng triệu PII. GDPR còn yêu cầu PII chỉ ở nơi cần thiết.

    Redact: (1) allow-list field được phép log (an toàn nhất — bỏ field mới không vô tình lộ), (2) deny-list SENSITIVE fields, (3) hash email/identifier để giữ correlation mà không lộ raw, (4) log filter layer (Vector, Logstash) xoá field trước khi index — backup layer khi app log nhầm.

  3. NIST IR lifecycle có Containment trước Eradication. Khác biệt là gì?

    Xem đáp án
    • Containment: chặn attack lan rộng. Quick action như disable IAM key, isolate host khỏi network, block IP. Chưa root-cause, chỉ giảm bleeding.
    • Eradication: loại bỏ root cause sau khi đã hiểu attack. Remove malware, patch vulnerability, rotate creds liên quan, close lateral movement path.

    Vì sao tách: trong khủng hoảng, mục tiêu đầu tiên là stop the bleeding càng nhanh càng tốt; root cause cần thời gian phân tích. Nếu cố eradicate trước khi contain, attacker có thể exfiltrate thêm trong lúc bạn đang investigate.

  4. Tabletop exercise khác simulation chạy thực thế nào, vì sao vẫn cần?

    Xem đáp án

    Tabletop: discuss trên giấy/whiteboard, không chạy lệnh thật. Nhanh (2-3 giờ), không nguy cơ outage, focus vào decision-making và communication.

    Live drill / chaos engineering: thực sự kill instance, simulate breach. Tốn thời gian hơn, nguy cơ nếu sai môi trường.

    Vẫn cần tabletop vì: (1) test runbook coverage (có thiếu scenario nào?), (2) tìm communication gap (ai gọi ai, escalation path), (3) low cost — chạy được mỗi quý. Live drill bổ sung, không thay thế — thường 1-2 lần/năm cho scenario critical.

  5. Vì sao "snapshot trước khi investigate" quan trọng trong forensics?

    Xem đáp án

    Hành động investigate (login server, chạy ps, restart process) thay đổi state của vật chứng: timestamp file truy cập đổi, memory rewrite, log thêm dòng. Nếu attacker đặt trap (vd shell script tự xoá khi detect login admin), bạn mất evidence.

    Best practice: (1) snapshot disk (EBS snapshot, VM snapshot) — immutable copy, (2) memory dump trước khi reboot/isolate, (3) export logs off-host trước khi attacker có thể edit, (4) investigate trên copy, prod giữ nguyên cho forensic team. Nếu liên quan pháp lý, chain of custody phải document mọi access từ thời điểm snapshot.

Bài tập thực hành

# 1. Setup structured logging trong Node app
npm install pino pino-pretty

cat > app.js <<'EOF'
const pino = require("pino");
const logger = pino({
  level: "info",
  redact: {
    paths: ["password", "*.password", "req.headers.authorization", "*.ssn"],
    censor: "[REDACTED]",
  },
});

logger.info({ user: { id: "u_1", email: "a@x.com", ssn: "123-45-6789" } }, "user.signup");
EOF
node app.js | jq

# 2. CloudWatch Logs Insights query
aws logs start-query \
  --log-group-name /aws/lambda/api \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, actor.ip, action | filter event_id="auth.login.fail" | stats count() by actor.ip | sort count() desc | limit 20'

# 3. Set retention 365 ngày cho log group
aws logs put-retention-policy \
  --log-group-name /aws/lambda/api \
  --retention-in-days 365

# 4. Test gitleaks log: tạo runbook mẫu
mkdir -p runbooks
cat > runbooks/aws-key-leak.md <<'EOF'
# Runbook: AWS Key Detected in Public Repo
## Triage (5 min)
1. Identify key: AKIA prefix → console
2. aws iam list-access-keys --user-name <user>
## Contain
1. aws iam update-access-key --status Inactive ...
2. Notify on-call + key owner
## Eradicate
1. Rotate key, delete old
2. Audit CloudTrail with old key for 24h
EOF

# 5. Tabletop scenario (đọc và thảo luận với team)
cat <<'EOF'
SCENARIO: Sáng thứ Hai 9 AM, customer support nhận ticket
"Tôi nhận password reset email không yêu cầu". 30 phút sau,
50 ticket tương tự. CloudTrail thấy IAM user "cs-bot" gọi
sts:AssumeRole vào prod role 200 lần.

Q1: Severity?
Q2: Ai page đầu tiên? Ai làm IC?
Q3: Hành động 5 phút đầu là gì?
Q4: Khi nào notify customer? Legal? DPO?
Q5: GDPR clock bắt đầu chạy lúc nào?
EOF

Tài liệu tham khảo chính thức


Quiz Tuần 4 →