02 ธ.ค. 2568·อ่าน 3 นาที

การสแกนไวรัสสำหรับการอัปโหลดไฟล์: ตัวเลือกสถาปัตยกรรมสำหรับแอป

อธิบายการสแกนไวรัสสำหรับการอัปโหลดไฟล์ในแอปที่มีเอกสารจำนวนมาก: การเก็บควอรันทีน คิวสแกน การควบคุมการเข้าถึง การลองใหม่ และกระบวนการปล่อยไฟล์อย่างปลอดภัย

การสแกนไวรัสสำหรับการอัปโหลดไฟล์: ตัวเลือกสถาปัตยกรรมสำหรับแอป

ปัญหาในแบบที่เข้าใจง่าย: ไฟล์ที่ไม่ปลอดภัยเข้าสู่แอปของคุณ

ถ้าแอปของคุณให้ผู้คนอัปโหลดเอกสาร นั่นหมายความว่าคุณรับไฟล์ที่คุณไม่ได้สร้างขึ้นเอง ในผลิตภัณฑ์ที่มีเอกสารมาก (พอร์ทัลลูกค้า ระบบ HR แอปเคลม การรับผู้ขาย) การอัปโหลดเกิดบ่อย และผู้ใช้มักแชร์ไฟล์จากอีเมล ไดรฟ์ที่แชร์ หรือบุคคลที่สาม ทำให้แอปเหล่านี้เป็นเป้าหมายที่ใช้งานได้จริง: การอัปโหลดสำเร็จเพียงครั้งเดียวสามารถแพร่ไปยังการดาวน์โหลดหลายครั้งได้

ความเสี่ยงไม่ได้มีเพียง "ไวรัส" เท่านั้น ไฟล์ Word หรือ Excel อาจมีมาโครที่เป็นอันตราย, PDF อาจถูกสร้างมาเพื่อโจมตีบั๊กของตัวอ่าน, และ "ใบแจ้งหนี้" อาจเป็นเอกสารฟิชชิงที่หลอกให้ใครสักคนโทรไปยังหมายเลขปลอมหรือใส่ข้อมูลรับรอง บางไฟล์ถูกทำพิษในวิธีที่เงียบกว่า เช่น ซ่อน payload ใน ZIP, ใช้นามสกุลซ้อน (report.pdf.exe), หรือฝังเนื้อหาจากระยะไกลที่โทรกลับเมื่อเปิด

การพึ่งพาแอนตี้ไวรัสตัวเดียวที่ติดตั้งบนเซิร์ฟเวอร์เดียวไม่เพียงพอ การอัปโหลดอาจเข้าถึงหลายอินสแตนซ์ของแอป เคลื่อนย้ายระหว่างระบบจัดเก็บ หรือถูกให้บริการจาก object storage หรือ CDN หากทางเดินโค้ดใด ๆ เผลอเผยแพร่ไฟล์ดิบ ผู้ใช้สามารถดาวน์โหลดก่อนการสแกนจะเสร็จได้ การอัปเดต การตั้งค่าผิดพลาด และการให้สิทธิ์ผู้ดูแลแบบ "ชั่วคราว" ก็สามารถก้าวข้ามการสแกนได้เมื่อเวลาผ่านไป

เป้าหมายที่ชัดเจนสำหรับการสแกนไวรัสสำหรับการอัปโหลดไฟล์คือ: ไม่มีไฟล์ที่ยังไม่สแกนควรถูกดาวน์โหลดหรือดูได้โดยใครก็ตามที่ไม่ได้รับอนุญาตให้ตรวจสอบไฟล์ที่ถูกกักกัน

กำหนดคำว่า "ปลอดภัย" เป็นกฎทางธุรกิจ ไม่ใช่ความรู้สึก ตัวอย่างเช่น:

  • ต้องผ่านการสแกนมัลแวร์ด้วยชุดลายเซ็นที่สดใหม่
  • ต้องตรงกับชนิดไฟล์ที่อนุญาตและขีดจำกัดขนาด
  • ต้องเก็บและให้บริการจากตำแหน่งที่อนุญาตเท่านั้น
  • ต้องมีร่องรอยตรวจสอบ: ใครอัปโหลด, เมื่อใด, และสถานะสุดท้าย
  • ต้องถูกบล็อกจนกว่าจะมีการตัดสินสุดท้าย: ปล่อยหรือปฏิเสธ

ถ้าคุณสร้างด้วยแพลตฟอร์มอย่าง AppMaster ให้ถือว่า "สถานะการสแกน" เป็นฟิลด์สำคัญในโมเดลข้อมูลของคุณและให้การกระทำดาวน์โหลดทุกครั้งตรวจสอบมัน ประตูเดียวนี้ป้องกันความผิดพลาดที่มีค่าใช้จ่ายสูงได้มาก

ควอรันทีนจริง ๆ หมายถึงอะไรสำหรับเอกสารที่อัปโหลด

"ควอรันทีน" ควรถูกมองว่าคือสถานะหนึ่งในระบบของคุณ ไม่ใช่แค่โฟลเดอร์ในพื้นที่จัดเก็บ ความคิดหลักคือ: ไฟล์มีอยู่ แต่ไม่มีใครสามารถเปิดหรือดาวน์โหลดจนกว่าแอปของคุณจะมีผลการสแกนที่ชัดเจนและบันทึกไว้ นี่คือหัวใจของการสแกนไวรัสสำหรับการอัปโหลดไฟล์

ควอรันทีนมักทำงานเป็นวงจรชีวิตเล็ก ๆ ที่มีสถานะชัดเจน การเก็บสถานะให้ชัดเจนทำให้การรั่วไหลของเนื้อหาไม่ปลอดภัยผ่านพรีวิว URL ตรง หรืองานส่งออกยากขึ้น

ชุดสถานะไฟล์ที่ใช้ได้จริงมีลักษณะเช่นนี้:

  • received (อัปโหลดเสร็จ แต่ยังไม่ได้สแกน)
  • scanning (ถูกดึงโดย worker)
  • clean (ปลอดภัยที่จะปล่อย)
  • rejected (พบมัลแวร์หรือละเมิดนโยบาย)
  • failed (เกิดข้อผิดพลาดของสแกนเนอร์ ไทม์เอาต์ หรือไฟล์เสียหาย)

ควอรันทีนยังต้องมีเมตาดาต้าที่เหมาะสมเพื่อให้คุณสามารถบังคับสิทธิ์และตรวจสอบเหตุการณ์ย้อนหลังได้ อย่างน้อยควรเก็บ: เจ้าของ (ผู้ใช้หรือองค์กร), สถานะ, ชื่อไฟล์และชนิดเดิม, checksum (เพื่อ dedupe และตรวจสอบการแก้ไข), ตำแหน่งจัดเก็บ, และป้ายเวลา (อัปโหลด, เริ่มสแกน, สแกนเสร็จ) หลายทีมยังเก็บเวอร์ชันของสแกนเนอร์และรายละเอียดคำตัดสินของการสแกนด้วย

การกำหนดระยะเวลาการเก็บเป็นนโยบาย แต่ควรเป็นการตัดสินใจที่มีเจตนา เก็บไฟล์ที่ถูกกักกันเฉพาะเท่าที่จำเป็นสำหรับการสแกนและดีบักความล้มเหลว การเก็บระยะสั้นช่วยลดความเสี่ยงและค่าใช้จ่าย แต่คุณยังต้องมีเวลาพอที่จะสืบสวนเหตุการณ์และช่วยผู้ใช้ที่ถามว่า "ไฟล์ที่ฉันอัปโหลดหายไปไหน?"

สุดท้าย ให้ตัดสินใจว่าจะทำอย่างไรกับไฟล์ที่ไม่เคยสแกนเสร็จ กำหนดเวลาสูงสุดสำหรับการสแกนและป้ายเวลา "หมดอายุ" เมื่อเวลาถึง ให้ย้ายไฟล์ไปยังสถานะ failed บล็อกการเข้าถึง และเลือกว่าจะลองใหม่อัตโนมัติจำนวนจำกัดหรือจะลบทิ้งแล้วขอให้ผู้ใช้อัปโหลดใหม่

รูปแบบการเก็บชั่วคราวที่ลดความเสี่ยง

พื้นที่เก็บชั่วคราวคือจุดที่ปัญหาอัปโหลดเกิดขึ้นมากที่สุด ไฟล์อยู่ในระบบของคุณ แต่คุณยังไม่รู้ว่าปลอดภัยหรือไม่ ดังนั้นคุณต้องมีที่ที่ล็อกได้ง่ายและยากที่จะเผยโดยไม่ตั้งใจ

ดิสก์ท้องถิ่นสามารถใช้ได้สำหรับเซิร์ฟเวอร์เดียว แต่เปราะบาง หากคุณสเกลขึ้นเป็นหลายเซิร์ฟเวอร์ คุณต้องแชร์พื้นที่จัดเก็บ คัดลอกไฟล์ และรักษาสิทธิ์ให้เหมือนกัน Object storage (เช่น bucket แบบ S3 หรือ container บนคลาวด์) มักปลอดภัยกว่าในแอปที่มีเอกสารมาก เพราะกฎการเข้าถึงรวมศูนย์และล็อกชัดเจนกว่า

รูปแบบง่าย ๆ สำหรับการสแกนไวรัสในการอัปโหลดไฟล์คือการแยก "ควอรันทีน" ออกจากพื้นที่จัดเก็บ "สะอาด" คุณสามารถทำได้ด้วยสองบัคเก็ต/คอนเทนเนอร์ ซึ่งลดความผิดพลาด หรือด้วย prefix ที่เข้มงวดในบัคเก็ตเดียว ซึ่งถูกกว่าและจัดการง่ายกว่า

ถ้าใช้ prefixes ให้ทำให้เป็นไปไม่ได้ที่จะสับสน ควรใช้โครงร่างเช่น quarantine/<tenant_id>/<upload_id> และ clean/<tenant_id>/<document_id> ไม่ใช่ชื่อที่ผู้ใช้กำหนดเอง อย่าใช้เส้นทางเดียวกันสำหรับสถานะต่างกัน

จำกฎพวกนี้ไว้:

  • ห้ามอนุญาตการอ่านสาธารณะบนควอรันทีน แม้แต่วิธีชั่วคราว
  • สร้างชื่ออ็อบเจ็กต์ทางฝั่งเซิร์ฟเวอร์ ไม่ใช่ชื่อจากลูกค้า
  • แบ่งพาร์ติชันโดย tenant หรือบัญชีเพื่อลด blast radius
  • เก็บเมตาดาต้า (เจ้าของ สถานะ checksum) ในฐานข้อมูล ไม่ใช่ในชื่อไฟล์

เข้ารหัสเมื่อเก็บ และเข้มงวดว่าใครถอดรหัสได้ API การอัปโหลดควรเขียนไปยังควอรันทีนได้ สแกนเนอร์อ่านจากควอรันทีนและเขียนไปยังสะอาดได้ และแอปที่ให้บริการสาธารณะควรอ่านจากสะอาดเท่านั้น ถ้าคลาวด์ของคุณรองรับนโยบายคีย์ ให้ผูกสิทธิถอดรหัสกับชุดบทบาทที่เล็กที่สุดเท่าที่เป็นไปได้

ไฟล์ขนาดใหญ่ต้องการการดูแลเพิ่มเติม สำหรับการอัปโหลดแบบหลายพาร์ท อย่าให้วัตถุเป็น "พร้อม" จนกว่าจะ commit ส่วนสุดท้ายและคุณบันทึกขนาดที่คาดว่าจะเป็นและ checksum วิธีปลอดภัยที่พบได้บ่อยคืออัปโหลดพาร์ทลงในควอรันทีน แล้วคัดลอกหรือโปรโมตอ็อบเจ็กต์ไปยังสะอาดหลังจากการสแกนผ่าน

ตัวอย่าง: ในพอร์ทัลลูกค้าที่สร้างด้วย AppMaster คุณสามารถถือว่าทุกการอัปโหลดเป็น "pending" เก็บไว้ในบัคเก็ตควอรันทีน และแสดงปุ่มดาวน์โหลดก็ต่อเมื่อผลการสแกนเปลี่ยนสถานะเป็น "clean"

ตัวเลือกสถาปัตยกรรม: สแกนแบบ inline กับ สแกนแบบ background

เมื่อเพิ่มการสแกนไวรัสสำหรับการอัปโหลดไฟล์ คุณมักเลือกสองโฟลว์: สแกนแบบ inline (ผู้ใช้รอ) หรือสแกนแบบ background (แอปรับการอัปโหลดแต่บล็อกการเข้าถึงจนกว่าจะเคลียร์) การเลือกขึ้นกับความเร็ว ความน่าเชื่อถือ และความถี่การอัปโหลดมากกว่าระดับความปลอดภัย (ทั้งสองสามารถปลอดภัยได้)

ตัวเลือก 1: การสแกนแบบ inline (ผู้ใช้รอ)

การสแกนแบบ inline หมายถึงคำขออัปโหลดจะไม่เสร็จจนกว่าเครื่องสแกนจะส่งผลกลับ มันให้ความรู้สึกเรียบง่ายเพราะมีขั้นตอนเดียว: อัปโหลด สแกน ยอมรับหรือปฏิเสธ

การสแกนแบบ inline มักเหมาะเมื่อไฟล์มีขนาดเล็ก การอัปโหลดน้อย และคุณควบคุมเวลารอได้ เช่น เครื่องมือทีมที่ผู้ใช้ส่ง PDF ไม่กี่ไฟล์ต่อวันอาจทนการหน่วง 3–10 วินาทีได้ ข้อเสียคือการสแกนช้าจะทำให้แอปช้า ไทม์เอาต์ รีทราย และเครือข่ายมือถือสามารถทำให้ประสบการณ์แย่ลง

ตัวเลือก 2: การสแกนแบบ background (แบบอะซิงค์)

การสแกนแบบอะซิงค์เก็บไฟล์ก่อน ทำเครื่องหมายเป็น "กักกัน" และผลักงานลงคิวสแกน ผู้ใช้ได้รับการตอบกลับว่า "รับการอัปโหลดแล้ว" อย่างรวดเร็ว แต่ไม่สามารถดาวน์โหลดหรือพรีวิวไฟล์ได้จนกว่าจะเคลียร์

แนวทางนี้เหมาะกว่าสำหรับปริมาณมาก ไฟล์ขนาดใหญ่ และช่วงเวลาที่งานหนาแน่น เพราะช่วยกระจายงานและทำให้แอปตอบสนองได้ดี นอกจากนี้ยังช่วยให้คุณสเกล worker การสแกนแยกจากเซิร์ฟเวอร์เว็บหรือ API หลัก

ไฮบริดที่ใช้งานได้จริงคือ: ทำการตรวจสอบอย่างรวดเร็วแบบ inline (allowlist ชนิดไฟล์ ขีดจำกัดขนาด การตรวจสอบรูปแบบพื้นฐาน) แล้วทำการสแกนแอนติไวรัสเต็มรูปแบบแบบ background วิธีนี้จับปัญหาที่ชัดเจนตั้งแต่ต้นโดยไม่ทำให้ผู้ใช้ทุกคนต้องรอ

แนวทางง่าย ๆ ในการเลือก:

  • ไฟล์เล็ก ปริมาณน้อย เวิร์กโฟลว์ที่ต้องรู้ผลทันที: สแกนแบบ inline
  • ไฟล์ใหญ่ อัปโหลดจำนวนมาก หรือเวลาสแกนอาจไม่แน่นอน: สแกนแบบ background
  • SLA ที่เข้มงวดเรื่องความเร็วตอบสนองการอัปโหลด: สแกนแบบ background พร้อม UI แสดงสถานะชัดเจน
  • งานผสม: ไฮบริด (ตรวจเร็วก่อน แล้วสแกนเต็มรูปแบบแบบอะซิงค์)

ถ้าคุณสร้างด้วย AppMaster ทางเลือกนี้มักแมปชัดเจนเป็น endpoint แบบ synchronous (inline) หรือ Business Process ที่ส่งงานสแกนลงคิวและอัปเดตสถานะไฟล์เมื่อผลมาถึง

ขั้นตอนทีละขั้น: สร้างคิวการสแกนแบบอะซิงค์

ทำให้สถานะการสแกนเป็นชั้นข้อมูลสำคัญ
สร้างตารางสถานะไฟล์และการตรวจสอบสิทธิ์ในที่เดียว
เริ่มสร้าง

การสแกนแบบอะซิงค์หมายถึงคุณรับการอัปโหลด ล็อกมันในควอรันทีน และสแกนมันในพื้นหลัง ผู้ใช้จะไม่เข้าถึงจนกว่าเครื่องสแกนจะบอกว่าปลอดภัย นี่มักเป็นสถาปัตยกรรมการสแกนมัลแวร์ที่ปฏิบัติได้จริงสำหรับแอปที่มีเอกสารมาก

1) กำหนดข้อความคิว (keep it small)

ถือคิวเป็นรายการสิ่งที่ต้องทำ แต่ละการอัปโหลดสร้างข้อความหนึ่งรายการที่ชี้ไปยังไฟล์ ไม่ใช่ใส่ไฟล์ลงไปในข้อความ

ข้อความง่าย ๆ มักรวม:

  • File ID (หรือ object key) และ tenant หรือ project ID
  • Uploaded-by user ID
  • Upload timestamp และ checksum (เป็นทางเลือกแต่ช่วยได้)
  • หมายเลขพยายาม (หรือเคาน์เตอร์การลองใหม่แยกต่างหาก)

หลีกเลี่ยงการใส่ไบต์ดิบลงในคิว payload ขนาดใหญ่ทำให้เกินขีดจำกัด เสียค่าใช้จ่ายมากขึ้น และเพิ่มการเปิดเผย

2) สร้างโฟลูว์ของ worker (fetch, scan, record)

worker ดึงข้อความ ดึงไฟล์จาก storage ควอรันทีน สแกน แล้วเขียนผลการตัดสินกลับ

โฟลูว์ที่ชัดเจนคือ:

  • ดึงไฟล์โดย ID จาก storage ควอรันทีน (บัคเก็ตส่วนตัวหรือโวลุ่มส่วนตัว)
  • รันสแกนเนอร์ (AV engine หรือบริการสแกน)
  • เขียนผลลงฐานข้อมูล: สถานะ (clean, infected, error), ชื่อ/เวอร์ชันสแกนเนอร์, และป้ายเวลา
  • เมื่อ clean: ย้ายไฟล์ไปยัง storage ที่อนุมัติหรือเปลี่ยนธงการเข้าถึงให้สามารถดาวน์โหลดได้
  • เมื่อ infected: เก็บไว้ในควอรันทีน (หรือลบทิ้ง) และแจ้งคนที่เกี่ยวข้อง

3) ทำให้เป็น idempotent (ปลอดภัยต่อการประมวลผลซ้ำ)

worker จะล่ม ข้อความจะถูกส่งซ้ำ และจะมีการลองใหม่ ออกแบบให้การสแกนไฟล์เดิมซ้ำ ๆ ไม่ก่อให้เกิดปัญหา ใช้บันทึกแหล่งเดียวของความจริง เช่น files.status และอนุญาตเฉพาะการเปลี่ยนแปลงที่ถูกต้อง เช่น: uploaded -> scanning -> clean/infected/error ถ้า worker เห็น clean ให้หยุดและ acknowledge ข้อความ

4) ควบคุมความขนาน (หลีกเลี่ยงการสแกนถล่ม)

กำหนดขีดจำกัดต่อ worker และต่อ tenant จำกัดจำนวนการสแกนพร้อมกัน และพิจารณาคิวแยกสำหรับไฟล์ขนาดใหญ่ นี่จะป้องกันไม่ให้ลูกค้าที่งานหนาใช้ความจุทั้งหมดของสแกนเนอร์

5) จัดการความล้มเหลวด้วยการลองใหม่และร่องรอยตรวจสอบ

ใช้การลองใหม่สำหรับข้อผิดพลาดชั่วคราว (ไทม์เอาต์สแกนเนอร์ ปัญหาเครือข่าย) พร้อมจำนวนพยายามสูงสุดเล็ก ๆ หลังจากนั้นส่งข้อความไปยัง dead-letter queue เพื่อตรวจสอบด้วยมนุษย์

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

การควบคุมการเข้าถึง: ทำให้ไฟล์ที่กักกันเป็นส่วนตัวอย่างแท้จริง

ควอรันทีนไม่ใช่แค่สถานะในฐานข้อมูล มันคือสัญญาว่าไม่มีใครเปิดไฟล์ได้จนกว่าจะพิสูจน์ว่าปลอดภัย กฎที่ปลอดภัยที่สุดคือ: อย่าให้ไฟล์ที่กักกันถูกเสิร์ฟผ่าน URL สาธารณะ แม้แต่แบบชั่วคราว

โฟลว์การดาวน์โหลดที่ดีนั้นน่าเบื่อและเข้มงวด แอปควรปฏิบัติกับการดาวน์โหลดทุกครั้งเหมือนเป็นการกระทำที่ป้องกัน ไม่ใช่การดึงรูปภาพ

  1. ขอการดาวน์โหลด
  2. ตรวจสอบสิทธิ์ของผู้ใช้สำหรับไฟล์นั้นโดยเฉพาะ
  3. ตรวจสอบสถานะไฟล์ (quarantined, clean, rejected)
  4. ส่งมอบไฟล์ก็ต่อเมื่อสถานะเป็น clean

ถ้าคุณใช้ signed URLs ให้รักษาหลักการเดียวกัน: สร้าง URL เฉพาะหลังจากการตรวจสิทธิ์และการตรวจสถานะ และให้เวลาหมดอายุสั้น การหมดอายุสั้นช่วยลดความเสียหายหากลิงก์รั่วผ่านล็อก สกรีนช็อต หรืออีเมลที่ถูกส่งต่อ

การเข้าถึงตามบทบาทช่วยให้คุณหลีกเลี่ยงตรรกะ "กรณีพิเศษ" ที่กลายเป็นช่องโหว่ บทบาททั่วไปสำหรับแอปที่มีเอกสารมากคือ:

  • Uploader: ดูการอัปโหลดของตนเองและสถานะการสแกนได้
  • Reviewer: ดูไฟล์ที่ clean ได้ และบางครั้งดูไฟล์ที่กักกันได้เฉพาะในเครื่องมือรีวิวที่ปลอดภัย
  • Admin: ตรวจสอบ รีสแกน และยกเว้นสิทธิ์เมื่อจำเป็น
  • External user: เข้าถึงเอกสารที่แชร์กับพวกเขาโดยเฉพาะเท่านั้น

นอกจากนี้ป้องกันการเดา ID อย่าเผย ID ไฟล์ที่เพิ่มทีละหนึ่ง เช่น 12345 ใช้ ID ที่ไม่ชัดเจน และตรวจสิทธิ์ต่อผู้ใช้ต่อไฟล์เสมอ (ไม่ใช่แค่ "ผู้ใช้ใด ๆ ที่ล็อกอิน") แม้ว่า bucket ของคุณจะเป็นส่วนตัว แต่ endpoint API ที่ประมาทก็ยังสามารถรั่วไหลเนื้อหาที่กักกันได้

เมื่อคุณสร้างการสแกนไวรัสสำหรับการอัปโหลดไฟล์ ชั้นการเข้าถึงคือที่ที่เกิดความล้มเหลวในโลกจริงที่สุด ในแพลตฟอร์มอย่าง AppMaster คุณจะบังคับการตรวจสอบเหล่านี้ใน endpoints API และตรรกะธุรกิจก่อนสร้างการตอบกลับดาวน์โหลด ดังนั้นควอรันทีนจะเป็นส่วนตัวโดยดีฟอลต์

การปล่อย ปฏิเสธ และการลองใหม่: การจัดการผลการสแกน

วางแผนการล้มเหลวของสแกนเนอร์
จัดการการลองใหม่ ไทม์เอาต์ และการสแกนที่ค้างด้วยสถานะและการแจ้งเตือนที่ชัดเจน
สร้างเวิร์กโฟลว์

เมื่อไฟล์สแกนเสร็จ สิ่งสำคัญคือย้ายไฟล์ไปยังสถานะเดียวที่ชัดเจนและทำให้ขั้นตอนถัดไปคาดเดาได้ หากคุณกำลังสร้างการสแกนไวรัสสำหรับการอัปโหลดไฟล์ ให้ปฏิบัติต่อผลการสแกนเหมือนเป็นเกต: ไม่มีอะไรจะกลายเป็นดาวน์โหลดได้จนกว่าเกตจะบอกให้

ชุดผลลัพธ์ง่าย ๆ ครอบคลุมระบบจริงส่วนใหญ่:

  • Clean: ปล่อยไฟล์จากควอรันทีนและอนุญาตการเข้าถึงตามปกติ
  • Infected: บล็อกการเข้าถึงถาวรและเปิดเวิร์กโฟลว์สำหรับไฟล์ที่ติดเชื้อ
  • Unsupported: สแกนเนอร์ประเมินชนิดนี้ไม่ได้ (หรือมีรหัสผ่าน) ให้เก็บไว้บล็อก
  • Scan error: ความล้มเหลวชั่วคราว (ไทม์เอาต์ บริการไม่พร้อม) ให้บล็อกไว้

การสื่อสารกับผู้ใช้ควรชัดเจนและใจเย็น หลีกเลี่ยงคำที่ทำให้ตื่นตระหนกเช่น "บัญชีของคุณถูกบุกรุก" วิธีที่ดีกว่าคือ: "ไฟล์กำลังถูกตรวจสอบ คุณสามารถทำงานต่อได้" หากไฟล์ถูกบล็อก ให้บอกว่าผู้ใช้สามารถทำอะไรต่อได้: "อัปโหลดไฟล์ชนิดอื่น" หรือ "ลองใหม่ในภายหลัง" สำหรับไฟล์ที่ไม่รองรับ ให้ระบุชัดเจน (เช่น "อาร์ไคฟ์ที่เข้ารหัสไม่สามารถสแกนได้")

สำหรับไฟล์ที่ติดเชื้อ ให้ตัดสินใจตั้งแต่ต้นว่าจะลบทิ้งหรือเก็บไว้ การลบง่ายกว่าและลดความเสี่ยง การเก็บไว้ช่วยการตรวจสอบหลังเหตุการณ์ได้ แต่ต้องเก็บในพื้นที่แยกที่เข้มงวดด้วยการเข้าถึงสั้น ๆ และล็อกว่าใครดูได้ (ในอุดมคติไม่มีใครยกเว้นแอดมินด้านความปลอดภัย)

การลองใหม่มีประโยชน์ แต่สำหรับข้อผิดพลาดที่เป็นชั่วคราวเท่านั้น กำหนดนโยบายลองใหม่เล็ก ๆ เพื่อไม่ให้เกิดคิวสะสมไม่สิ้นสุด:

  • ลองใหม่เมื่อเกิดไทม์เอาต์และสแกนเนอร์ไม่พร้อม
  • ไม่ลองใหม่เมื่อผลคือ “infected” หรือ “unsupported”
  • จำกัดจำนวนลองใหม่ (เช่น 3 ครั้ง) แล้วทำเครื่องหมายว่า failed
  • ใส่ backoff ระหว่างการลองใหม่เพื่อหลีกเลี่ยงการโอเวอร์โหลด

สุดท้าย ให้ถือว่าความล้มเหลวซ้ำ ๆ เป็นปัญหา ops ไม่ใช่ปัญหาผู้ใช้ หากไฟล์จำนวนมากพบ "scan error" ในหน้าต่างเวลาอันสั้น ให้แจ้งทีมและพักการปล่อยใหม่ ใน AppMaster คุณสามารถโมเดลสถานะเหล่านี้ในฐานข้อมูลและส่งการแจ้งเตือนผ่านโมดูลข้อความในตัวเพื่อให้คนที่เกี่ยวข้องได้รับทราบอย่างรวดเร็ว

สถานการณ์ตัวอย่าง: พอร์ทัลลูกค้าที่มีเอกสารจำนวนมาก

เพิ่มเส้นทางการตรวจสอบและการยกเว้น
สร้างหน้าจอผู้ดูแลเพื่อตรวจสอบรายการที่ถูกกักกันโดยไม่เปิดเผยให้ผู้ใช้
เริ่มตอนนี้

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

เมื่อผู้ใช้ลูกค้าส่ง PDF พอร์ทัลจะบันทึกไปยังตำแหน่งชั่วคราวส่วนตัวและสร้างระเบียนในฐานข้อมูลโดยตั้งค่าสถานะเป็น Pending scan ไฟล์ยังไม่ปรากฏให้ดาวน์โหลด คนที่สแกนจะดึงไฟล์จากคิว รันการสแกน แล้วอัปเดตระเบียนเป็น Clean หรือ Blocked

ใน UI ลูกค้าจะเห็นเอกสารปรากฏทันที แต่มีป้าย Pending ชัดเจน ชื่อไฟล์และขนาดแสดงเพื่อให้ทราบว่าอัปโหลดสำเร็จ แต่ปุ่ม Download ถูกปิดจนกว่าจะสแกนผ่าน หากการสแกนใช้เวลานานกว่าคาด พอร์ทัลสามารถแสดงข้อความง่าย ๆ เช่น "เรากำลังตรวจสอบไฟล์นี้เพื่อความปลอดภัย ลองใหม่อีกครั้งในหนึ่งนาที"

ถ้าสแกนเนอร์แจ้งว่ามีปัญหา ลูกค้าจะเห็นสถานะ Blocked พร้อมข้อความสั้น ๆ ที่ไม่เป็นทางเทคนิค: "ไฟล์นี้ผ่านการตรวจสอบความปลอดภัยไม่สำเร็จ" ฝ่ายสนับสนุนและแอดมินจะมีมุมมองแยกที่รวมสาเหตุการสแกนและการดำเนินการต่อไป พวกเขาสามารถ:

  • เก็บไว้บล็อกและขอให้อัปโหลดใหม่
  • ลบทิ้งและบันทึกเหตุผล
  • ทำเครื่องหมายว่าเป็น false positive เฉพาะเมื่อโยบายอนุญาต

เมื่อมีข้อพิพาท ("ฉันอัปโหลดเมื่อวานและคุณทำหาย") บันทึกที่ดีมีความสำคัญ เก็บป้ายเวลา upload received, scan started, scan finished, status changed, และใครทำอะไร นอกจากนี้เก็บแฮชไฟล์ ชื่อไฟล์เดิม บัญชีผู้ที่อัปโหลด ที่อยู่ IP และรหัสผลสแกน หากคุณสร้างใน AppMaster Data Designer และ Business Process คุณสามารถจัดการสถานะและฟิลด์ audit เหล่านี้โดยไม่เปิดเผยไฟล์ที่กักกันให้ผู้ใช้ธรรมดา

ความผิดพลาดที่พบบ่อยที่ทำให้เกิดช่องโหว่ในความปลอดภัยจริง

ความล้มเหลวด้านความปลอดภัยการอัปโหลดส่วนใหญ่ไม่ใช่การโจมตีหรูหรา แต่เป็นทางเลือกการออกแบบเล็ก ๆ ที่ทำให้ไฟล์ไม่ปลอดภัยทำตัวเหมือนไฟล์ปกติ

ปัญหาแบบคลาสสิกคือการแข่งขัน (race): แอปรับการอัปโหลด ส่งกลับ URL ดาวน์โหลด และผู้ใช้ (หรือบริการอื่น) สามารถดึงไฟล์ก่อนการสแกนจะเสร็จ หากคุณทำการสแกนไวรัสสำหรับการอัปโหลดไฟล์ ให้ถือว่า "อัปโหลด" และ "พร้อมใช้งาน" เป็นสองสถานะต่างกัน

นี่คือความผิดพลาดที่เกิดซ้ำบ่อยครั้ง:

  • ผสมไฟล์ที่สะอาดและถูกกักกันในบัคเก็ต/โฟลเดอร์เดียวกัน แล้วพึ่งพากฎการตั้งชื่อ หนึ่งสิทธิ์ผิดหรือการเดาเส้นทางก็ทำให้ควอรันทีนไร้ความหมาย
  • เชื่อถือสกุลไฟล์ นามสกุล MIME หรือการตรวจสอบฝั่งลูกค้า ผู้โจมตีสามารถเปลี่ยนนามสกุลเป็น .pdf และ UI ของคุณจะมองข้ามได้
  • ไม่วางแผนสำหรับการหยุดทำงานของสแกนเนอร์ ถ้าสแกนเนอร์ช้าหรือออฟไลน์ ไฟล์จะค้างใน "pending" และทีมจะเริ่มใช้การยกเว้นด้วยมือที่ไม่ปลอดภัย
  • ให้ worker พื้นหลังข้ามกฎการอนุญาตเดียวกับ API หลัก worker ที่อ่าน "ไฟล์ใดก็ได้" เป็นการยกระดับสิทธิ์เงียบ ๆ
  • เผยแพร่ ID ที่เดาได้ง่าย (เช่น ตัวเลขเพิ่มทีละหนึ่ง) สำหรับรายการที่กักกัน แม้ว่าคุณคิดว่าเนื้อหาจะถูกป้องกัน

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

ตัวอย่างจริงง่าย ๆ: ผู้ใช้พอร์ทัลลูกค้าอัปโหลด "contract.pdf" ที่แท้จริงคือ executable ที่ถูกเปลี่ยนนามสกุลอยู่ในอาร์ไคฟ์ ถ้าพอร์ทัลของคุณเสิร์ฟไฟล์กลับทันที หรือทีมสนับสนุนสามารถเข้าถึงควอรันทีนโดยไม่มีการตรวจสอบที่เหมาะสม คุณได้สร้างช่องทางส่งมอบตรงสู่ผู้ใช้คนอื่น

เช็คลิสต์ด่วนก่อนส่งขึ้นโปรดักชัน

สร้างต้นแบบวงจรชีวิตเต็มรูปแบบ
ทดสอบสถานะ Pending, Clean, Rejected และ Failed ด้วยเอกสารจริง
สร้างต้นแบบ

ก่อนปล่อยการสแกนไวรัสสำหรับการอัปโหลดไฟล์ ให้ทำการตรวจรอบสุดท้ายในจุดที่ทีมมักคิดว่า "โอเค" แต่ต่อมาพบว่าไม่เป็นเช่นนั้น เป้าหมายง่าย ๆ คือ: ไฟล์ที่ไม่ปลอดภัยไม่ควรกลายเป็นอ่านได้เพียงเพราะมีคนเดา URL รีทรายคำขอ หรือใช้ลิงก์เก่าในแคช

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

ใช้เช็คลิสต์ก่อนส่งนี้เป็นเกณฑ์ฐานขั้นต่ำ:

  • พื้นที่เก็บควอรันทีนเป็นส่วนตัวโดยดีฟอลต์: ไม่มีบัคเก็ตสาธารณะ, ไม่มี "ใครมีลิงก์ก็เข้าถึงได้", และไม่มีการเสิร์ฟตรงจาก object storage ดิบ
  • ทุกระเบียนไฟล์มีเจ้าของ (ผู้ใช้ ทีม หรือ tenant) และสถานะวงจรชีวิตชัดเจน เช่น pending, clean, infected, หรือ failed
  • คิวการสแกนและ worker ของคุณมีการลองใหม่จำกัด กฎ backoff ชัดเจน และมีการแจ้งเตือนเมื่อรายการค้างหรือเกิดความล้มเหลวซ้ำ
  • มีล็อกการตรวจสอบสำหรับการอัปโหลด ผลการสแกน และความพยายามดาวน์โหลด (รวมทั้งความพยายามที่ถูกบล็อก) ระบุว่า ใคร เมื่อไร และทำไม
  • มีการยกเว้นด้วยมือสำหรับกรณีหายาก แต่เป็นสิทธิ์ผู้ดูแลเท่านั้น บันทึก และมีเวลาจำกัด (ไม่มีปุ่ม "mark clean" เงียบ ๆ)

สุดท้าย ให้แน่ใจว่าคุณสามารถสังเกตระบบแบบ end-to-end คุณควรตอบคำถามได้ว่า: "ตอนนี้มีไฟล์ที่รอการสแกนเท่าไร?" และ " tenant ไหนกำลังเจอความล้มเหลว?" หากสร้างบน AppMaster ให้โมเดลวงจรชีวิตไฟล์ใน Data Designer และบังคับการเช็คสถานะใน Business Process Editor เพื่อให้กฎคงที่ข้ามเว็บและมือถือ

ขั้นตอนถัดไป: เปลี่ยนการออกแบบให้เป็นแอปที่ใช้งานได้

เริ่มจากเขียนลงไปว่ามีสถานะอะไรบ้างที่ไฟล์ของคุณสามารถอยู่ได้ และแต่ละสถานะอนุญาตอะไร ทำให้เรียบง่ายและชัดเจน: "uploaded", "queued", "scanning", "clean", "infected", "scan_failed" แล้วเพิ่มกฎการเข้าถึงข้าง ๆ แต่ละสถานะ ใครดูได้ ใครดาวน์โหลดได้ หรือลบได้ในขณะที่ไฟล์ยังไม่เชื่อถือได้?

ถัดไป เลือกแนวทางที่ตรงกับปริมาณงานและเป้าหมายประสบการณ์ผู้ใช้ของคุณ การสแกนแบบ inline อธิบายง่ายกว่า แต่ทำให้อัปโหลดรู้สึกช้า การสแกนแบบอะซิงค์สเกลได้ดีกว่าสำหรับแอปที่มีเอกสารมาก แต่เพิ่มสถานะ คิว และ UI แบบ "pending"

วิธีปฏิบัติที่เป็นรูปธรรมเพื่อไปจากการออกแบบสู่การสร้างคือการพัฒนาต้นแบบฟลูว์ครบวงจรโดยใช้เอกสารจริง (PDF, ไฟล์ Office, รูปภาพ, อาร์ไคฟ์) และพฤติกรรมผู้ใช้จริง (อัปโหลดหลายไฟล์ ยกเลิก รีทราย) อย่าหยุดที่ "สแกนเนอร์ทำงาน" ให้ยืนยันว่าแอปไม่เสิร์ฟไฟล์ที่กักกันโดยไม่ตั้งใจแม้แต่กรณีเดียว

นี่คือแผนการสร้างง่าย ๆ ที่ทำได้ในหนึ่งสัปดาห์:

  • กำหนดสถานะไฟล์ การเปลี่ยนแปลง และกฎการเข้าถึงในหน้าเดียว
  • เลือกการสแกนแบบ inline, async หรือ hybrid และจดข้อแลกเปลี่ยน
  • นำไปสู่การอัปโหลด -> storage ควอรันทีน -> งานสแกน -> callback ผล พร้อมล็อกการตรวจสอบ
  • สร้าง UI สถานะที่ผู้ใช้จะเห็น (pending, blocked, failed, approved)
  • เพิ่มการมอนิเตอร์ตั้งแต่วันแรก: ขนาดคิวสะสม อัตราความล้มเหลว เวลาเฉลี่ยถึง clean

ถ้าคุณสร้างแบบไม่ต้องเขียนโค้ด AppMaster สามารถช่วยโมเดลเมตาดาต้าไฟล์ (สถานะ เจ้าของ checksum ป้ายเวลา) สร้างหน้าจออัปโหลดและรีวิว และจัดการเวิร์กโฟลว์การสแกนด้วยตรรกะธุรกิจและการประมวลผลแบบคิว ช่วยให้คุณทดสอบฟลูว์สินค้าจริงตั้งแต่ต้น แล้วเสริมความเข้มแข็งในส่วนที่สำคัญ: สิทธิ์ การแยก storage และการลองใหม่ที่เชื่อถือได้

สุดท้าย ตัดสินใจว่า "ดี" มีค่าอย่างไรด้วยตัวเลข กำหนดเกณฑ์แจ้งเตือนก่อนเปิดตัว เพื่อที่คุณจะสังเกตการสแกนค้างและความล้มเหลวก่อนที่ผู้ใช้จะสังเกตเห็น

ง่ายต่อการเริ่มต้น
สร้างบางสิ่งที่ น่าทึ่ง

ทดลองกับ AppMaster ด้วยแผนฟรี
เมื่อคุณพร้อม คุณสามารถเลือกการสมัครที่เหมาะสมได้

เริ่ม
การสแกนไวรัสสำหรับการอัปโหลดไฟล์: ตัวเลือกสถาปัตยกรรมสำหรับแอป | AppMaster