guest@websec: ~/websec/21-logging-and-incident-response/th — zsh — 100×40 เขียนโดย SaKKo ENTH โค้ด:

guest@websec ~ % man 21-logging-and-incident-response

21 · Logging, การแจ้งเตือน และการรับมือเหตุการณ์

การป้องกันทุกอย่างสุดท้ายจะพลาดที่ไหนสักแห่ง ที่สำคัญคือสังเกตเห็นเร็วแค่ไหน และรับมือได้ดีแค่ไหน

21.1 ควร log อะไร

log security event ให้มี ใคร, อะไร, เมื่อไร, จากที่ไหน และ ผลลัพธ์

ควร log

  • การล็อกอิน: สำเร็จ ล้มเหลว ถูกล็อก ออกจากระบบ
  • การเปลี่ยนรหัสผ่าน อีเมล และ MFA การรีเซ็ตรหัสผ่าน
  • การตรวจสิทธิ์ไม่ผ่าน (403, policy ปฏิเสธ)
  • CSRF token ไม่ผ่าน, ถูก rate limit
  • การกระทำของ admin และการเปลี่ยนสิทธิ์
  • ธุรกรรมมูลค่าสูง การ export ข้อมูลจำนวนมาก
  • การตรวจ input ไม่ผ่านที่ดูเหมือนการโจมตี
  • รายงานการละเมิด CSP

ห้าม log

  • รหัสผ่าน (แม้แต่ที่ผิด: มักเป็นรหัสจริงที่พิมพ์ผิด)
  • session id, API key, token, ลิงก์รีเซ็ต
  • เลขบัตรเต็ม, CVV
  • secret จาก config หรือ environment
  • ข้อมูลส่วนบุคคลมากเกินจำเป็น (กฎหมายคุ้มครองข้อมูลใช้กับ log ด้วย)
Rails log request ให้ (กรอง secret แล้ว) แต่ไม่ log security event อย่างการล็อกอินหรือการปฏิเสธ ต้องเพิ่มเองเป็น JSON แบบมีโครงสร้าง
# a tiny security-event helper
# (assumes Current has request_id and ip, set in a before_action)
module SecurityLog
  def self.event(name, **data)
    Rails.logger.info({ event: name, at: Time.now.utc.iso8601,
      user_id: Current.user&.id, request_id: Current.request_id, ip: Current.ip, **data }.to_json)
  end
end

SecurityLog.event("login.failure", email_hash: Digest::SHA256.hexdigest(email.downcase))
SecurityLog.event("authz.denied", policy: "OrderPolicy#refund?", order_id: order.id)
SecurityLog.event("admin.role_changed", target_id: user.id, from: "member", to: "admin")

21.2 Log injection

การขึ้นบรรทัดใหม่ใน input ของผู้ใช้ปลอมบรรทัด log ได้ทั้งบรรทัด เช่น "admin ล็อกอินแล้ว" ถ้า log เป็น JSON input จะอยู่ในช่องของมัน

sim: ปลอมบรรทัด logชื่อผู้ใช้ที่พิมพ์ตอนล็อกอิน

logger.info "login.failure user=#{username}"

log แบบ JSON มีโครงสร้าง

21.3 การแจ้งเตือน: log ที่ไม่มีใครอ่านไม่นับ

การเจาะระบบมักอยู่ใน log เป็นเดือนโดยไม่มีใครเห็น ให้เปลี่ยนสัญญาณสำคัญเป็นการแจ้งเตือนที่มีเจ้าของ: ล็อกอินล้มเหลวพุ่ง admin ใหม่ export ใหญ่ๆ ให้มีน้อยๆ ไม่อย่างนั้นคนจะเมิน

sim: ปรับการแจ้งเตือนจำนวนล็อกอินล้มเหลวต่อนาที ชั่วโมงที่ผ่านมา

21.4 การปกป้อง log เอง

  • ส่ง log ออกจากเซิร์ฟเวอร์แอปไปยังระบบกลาง (ผู้โจมตีลบ log ในเครื่อง)
  • จำกัดคนที่อ่านได้ เพราะมีข้อมูลส่วนบุคคล
  • ทำให้เป็นแบบเพิ่มอย่างเดียว หรือตรวจจับการแก้ไขได้ในจุดที่สำคัญ (audit trail)

21.5 การรับมือเหตุการณ์

ขั้นตอน: ตรวจจับ, วิเคราะห์, ควบคุม, แก้ไข, กู้คืน, เรียนรู้ เขียน runbook หนึ่งหน้าไว้ตอนนี้เลย: โทรหาใคร หมุนเวียน secret อย่างไร สั่งให้ทุกคนออกจากระบบอย่างไร ตาม PDPA ของไทย (และ GDPR ของยุโรป) ต้องแจ้งสำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคล (สคส.) ภายใน 72 ชั่วโมงนับจากที่รู้ว่าข้อมูลส่วนบุคคลรั่ว เว้นแต่ไม่น่าจะกระทบสิทธิของใคร ถ้าความเสี่ยงสูงต้องแจ้งเจ้าของข้อมูลด้วย

ซ้อม: เรียงลำดับการรับมือคลิกขั้นตอนตามลำดับที่คุณจะทำ