การตรวจสอบสัญญาอัจฉริยะ (Smart Contract Audit) คือความพยายามอย่างเป็นระบบในการค้นหาวิธีที่สัญญาอาจล้มเหลว ถูกนำไปใช้ในทางที่ผิด หรือถูกควบคุมในลักษณะที่ผู้ใช้ไม่คาดคิด มันไม่เหมือนกับการใช้โปรแกรมสแกนเพียงครั้งเดียว การอ่านตราสัญลักษณ์การตรวจสอบ หรือการยืนยันว่ารหัสต้นฉบับได้รับการตรวจสอบแล้ว ใช้ขั้นตอนการทำงานด้านล่างเพื่อตรวจสอบสัญญา EVM ที่ใช้งานอยู่หรือโค้ดเบสก่อนที่คุณจะไว้วางใจให้มันจัดการเงินทุนจำนวนมาก
ข้อสำคัญ:นี่เป็นเพียงกรอบการตรวจสอบเชิงปฏิบัติ ไม่ใช่การรับประกันว่าโครงการนั้นปลอดภัย และไม่ใช่คำแนะนำด้านการลงทุน โปรโตคอลการผลิตที่มีมูลค่าสูงควรได้รับการตรวจสอบโดยอิสระจากผู้เชี่ยวชาญด้านความปลอดภัยที่มีประสบการณ์ ภาพประกอบในคู่มือนี้เป็นเพียงตัวอย่าง และไม่ควรนำไปใช้เป็นหลักฐานเกี่ยวกับโครงการหรือการใช้งานใดๆ โดยเฉพาะ
ภาพรวมรายการตรวจสอบการตรวจสอบ
| ขั้นตอน | คำถามหลัก | หลักฐานที่เป็นประโยชน์ |
| 1. ขอบเขต | ฉันกำลังตรวจสอบสัญญาฉบับเต็มที่ผู้ใช้เรียกใช้ใช่หรือไม่? | ที่อยู่, ห่วงโซ่, ไบต์โค้ด, พร็อกซี และการใช้งาน |
| 2. จุดเข้าออก | ผู้โทรแต่ละคนสามารถทำอะไรได้บ้าง? | ฟังก์ชันสาธารณะ/ภายนอก การเปลี่ยนแปลงสถานะ กราฟการเรียกใช้ฟังก์ชัน |
| 3. ระบบอัตโนมัติ | มีรูปแบบที่เห็นได้ชัดเจนอะไรบ้างที่ควรค่าแก่การพิจารณา? | ผลลัพธ์จากคอมไพเลอร์, ผลการค้นพบจาก Slither, การคัดกรองตัวตรวจจับ |
| 4. การรักษาความปลอดภัยด้วยตนเอง | ลำดับการโทรสามารถทำลายข้อสมมติฐานได้หรือไม่? | การเรียกจากภายนอก, การเรียกซ้ำ, การเรียกกลับ, การจัดการข้อผิดพลาด |
| 5. ตรรกะ | หลักการบัญชียังคงถูกต้องในกรณีพิเศษหรือไม่? | เลขคณิต, การปัดเศษ, ค่าธรรมเนียม, ข้อจำกัด, การเปลี่ยนสถานะ |
| 6. สิทธิพิเศษ | ใครสามารถเปลี่ยนแปลงหรือหยุดยั้งระบบนี้ได้? | บทบาท, เจ้าของ, คีย์ผู้ดูแลระบบ, พร็อกซี, ตัวเริ่มต้น |
| 7. การทดสอบ | พฤติกรรมนี้ยังคงเหมือนเดิมหรือไม่เมื่อเผชิญกับข้อมูลป้อนเข้าและลำดับที่ไม่คาดคิด? | การทดสอบหน่วย การทดสอบแบบฟัซซ์ การทดสอบแบบอินวาเรียนต์ และการทดสอบแบบฟอร์ก |
| 8. การรายงาน | บุคคลอื่นสามารถทำซ้ำและทดสอบผลลัพธ์ได้หรือไม่? | สถานะการค้นพบ ผลกระทบ หลักฐาน การแก้ไข และการทดสอบซ้ำ |
ขั้นตอนที่ 1: ยืนยันขอบเขตและอาร์ติแฟกต์ที่ใช้งาน
มุมมองการตรวจสอบสัญญาที่แสดงการตรวจสอบเครือข่าย ที่อยู่ เวอร์ชันคอมไพเลอร์ และการจับคู่ไบต์โค้ด เพื่อบันทึกก่อนการวิเคราะห์
เริ่มต้นด้วยการระบุลำดับและที่อยู่ให้ถูกต้อง บันทึกที่อยู่ในการปรับใช้ แฮชของธุรกรรม หมายเลขบล็อก เวอร์ชันคอมไพเลอร์ การตั้งค่าตัวเพิ่มประสิทธิภาพ อาร์กิวเมนต์ของตัวสร้าง และคอมมิตหรือรีลีสที่ทีมระบุว่าได้ปรับใช้แล้ว โครงการหนึ่งอาจมีที่อยู่หลายแห่งสำหรับโทเค็น เราเตอร์ วอลต์ พร็อกซี การใช้งาน ออราเคิล หรือการปรับใช้ทดสอบ การตรวจสอบที่อยู่ที่ไม่ถูกต้องจึงไม่มีประโยชน์ในทางปฏิบัติ
ตรวจสอบว่าซอร์สโค้ดที่ได้รับการยืนยันจากตัวสำรวจนั้นสร้างไบต์โค้ดที่ใช้งานอยู่จริงหรือไม่ การตรวจสอบนั้นมีประโยชน์เพราะช่วยให้คุณตรวจสอบซอร์สโค้ดและ ABI ได้ แต่เป็นการตรวจสอบตัวตนเท่านั้น ไม่ได้พิสูจน์ว่าตรรกะทางธุรกิจนั้นปลอดภัย หากสัญญานั้นสามารถอัปเกรดได้ ให้ระบุทั้งพร็อกซีและการใช้งานปัจจุบัน อ่านที่อยู่การใช้งานจากกลไกที่บันทึกไว้ของพร็อกซีหรือข้อมูลจากตัวสำรวจ จากนั้นยืนยันว่าการใช้งานนั้นเป็นสิ่งที่คุณต้องการตรวจสอบ คู่มือ การตรวจสอบ Foundry อย่างเป็นทางการ ของ Etherscan จะอธิบายการตรวจสอบสำหรับสัญญาใหม่และสัญญาที่มีอยู่แล้ว
นอกจากนี้ ให้กำหนดขอบเขตให้ชัดเจน รวมถึงไลบรารีที่นำเข้า สัญญาที่สืบทอดมา ไลบรารีที่เชื่อมโยง สัญญาตัวช่วยที่ใช้งาน อะแดปเตอร์ออราเคิล โทเค็นที่ได้รับจากผู้ใช้ และส่วนประกอบนอกเครือข่ายที่มีสิทธิ์พิเศษ เขียนลงไปว่าอะไรอยู่นอกขอบเขตและเหตุผลคืออะไร เพื่อป้องกันไม่ให้การตรวจสอบที่แคบเกินไปถูกเข้าใจผิดว่าเป็นการตรวจสอบระบบทั้งหมด
ขั้นตอนที่ 2: สร้างจุดเริ่มต้นและแผนที่สินทรัพย์
รายการฟังก์ชันที่แยกจุดเข้าใช้งานสาธารณะและภายนอกออกจากกัน ก่อนที่ผู้ตรวจสอบจะติดตามการเปลี่ยนแปลงสถานะของจุดเหล่านั้น
แสดงรายการฟังก์ชันสาธารณะและฟังก์ชันภายนอกทั้งหมด รวมถึงฟังก์ชันที่สืบทอดมาและตัวจัดการสำรองหรือตัวจัดการรับข้อมูล สำหรับแต่ละฟังก์ชัน ให้บันทึกว่าฟังก์ชันนั้นสามารถทำสิ่งต่อไปนี้ได้หรือไม่:
- โอนสกุลเงินหรือโทเค็นของประเทศนั้นๆ;
- สร้าง เผา ยืม ชำระบัญชี หรือเปลี่ยนแปลงบัญชี;
- เปลี่ยนแปลงออราเคิล ค่าธรรมเนียม ขีดจำกัด บทบาท สถานะหยุดชั่วคราว หรือการใช้งาน
- ทำการเรียกภายนอก, มอบหมายการเรียก หรือเรียกในระดับต่ำ; หรือ
- อ่านข้อมูลที่ฟังก์ชันเปลี่ยนสถานะอื่นต้องพึ่งพา
จากนั้นให้กำหนดขอบเขตของสินทรัพย์และความไว้วางใจ ติดตามการฝากเงินจากผู้ใช้เข้าสู่ระบบจัดเก็บ ผ่านการกำหนดราคาและการคำนวณส่วนแบ่ง ไปจนถึงการถอนเงิน ระบุที่อยู่ทุกแห่งที่ผู้เรียกให้มา และที่อยู่ทุกแห่งที่โหลดจากระบบจัดเก็บ ถามว่าค่าใดบ้างที่ถือว่าถูกต้อง: ออราเคิล โทเค็น ข้อความเชื่อมต่อ ผู้ดูแล ตัวรับการเรียกกลับ หรือผู้ดูแลระบบ เป้าหมายการตรวจสอบที่มีมูลค่าสูงสุดคือฟังก์ชันที่รวมอินพุตที่ผู้ใช้ควบคุม สถานะพิเศษ การคำนวณทางคณิตศาสตร์ และการเรียกจากภายนอก
ขั้นตอนที่ 3: คอมไพล์ให้สะอาดและทำการวิเคราะห์แบบคงที่
การวิเคราะห์โค้ดแบบคงที่สามารถระบุปัญหาที่อาจเกิดขึ้นได้อย่างรวดเร็ว แต่ยังคงต้องตรวจสอบยืนยันกับโค้ดจริงและแบบจำลองภัยคุกคามอีกครั้ง
สร้างโปรเจ็กต์ขึ้นมาใหม่โดยใช้เวอร์ชัน Solidity เวอร์ชันของไลบรารีที่เกี่ยวข้อง การกำหนดค่าตัวเพิ่มประสิทธิภาพ และข้อสมมติฐานของ Target Chain ที่ระบุไว้ ให้ถือว่าคำเตือนของคอมไพเลอร์เป็นสิ่งที่ต้องตรวจสอบ ไม่ใช่เป็นเพียงเสียงรบกวนที่ไม่เป็นอันตรายข้อควรพิจารณาด้านความปลอดภัย ของ Solidity แนะนำอย่างยิ่งให้ให้ความสำคัญกับคำเตือน รักษาข้อตกลงให้เข้าใจง่าย และตรวจสอบปัญหาของคอมไพเลอร์ที่ทราบแล้ว ปรึกษารายชื่อข้อบกพร่องของคอมไพเลอร์ Solidity ที่ทราบอย่างเป็นทางการเมื่อเวอร์ชันของคอมไพเลอร์หรือรูปแบบโค้ดที่ได้รับผลกระทบมีความเกี่ยวข้อง
สำหรับโปรเจ็กต์ Hardhat, Foundry หรือโปรเจ็กต์ที่คล้ายกัน ให้รัน Slither จากไดเร็กทอรีหลักของโปรเจ็กต์ เอกสารอย่างเป็นทางการอธิบายว่าเครื่องมือนี้เป็นเครื่องมือวิเคราะห์แบบคงที่สำหรับ Solidity และ Vyper และให้คำสั่งทั่วไปดังนี้:
slither .
บันทึกผลลัพธ์และคัดกรองแต่ละผลลัพธ์ตามผลกระทบและความน่าเชื่อถือ ตรวจสอบอย่างละเอียดกับสิ่งที่เกี่ยวข้องกับการส่งโทเค็นโดยพลการ การอัปเกรดที่ไม่ได้รับการป้องกัน การเข้าถึงซ้ำ ค่าส่งคืนที่ไม่ได้รับการตรวจสอบ การเรียกใช้ delegatecall ที่อันตราย tx.origin ความสุ่มที่ไม่แข็งแรง และอินเทอร์เฟซที่ไม่ถูกต้อง ตัวตรวจจับอาจรายงานผลลัพธ์ที่ผิดพลาด พลาดข้อบกพร่องทางเศรษฐกิจเฉพาะโครงการ หรือระบุโค้ดที่ถูกจำกัดไว้โดยเจตนาในที่อื่น การวิเคราะห์แบบคงที่ช่วยจำกัดขอบเขตการค้นหา แต่ไม่ได้แทนที่การใช้เหตุผลด้วยตนเอง คลังข้อมูลและเอกสารประกอบของ Slitherยังแสดงรายการตัวพิมพ์สำหรับจุดเริ่มต้น การอนุญาต กราฟการเรียก และบทสรุปสัญญาที่ช่วยในการจัดระเบียบการตรวจสอบ
ขั้นตอนที่ 4: ตรวจสอบการเรียกจากภายนอกและการเข้าซ้ำด้วยตนเอง
มีการเน้นการโทรจากภายนอกก่อนการอัปเดตยอดคงเหลือ ซึ่งแสดงให้เห็นถึงลำดับคำถามที่ผู้ตรวจสอบควรทดสอบในทุกขั้นตอนการถอนเงิน
สำหรับการเรียกใช้ภายนอกแต่ละครั้ง ให้หยุดและติดตามสถานะก่อน ระหว่าง และหลังการเรียกใช้ ผู้รับการเรียกใช้อาจเป็นสัญญาที่เป็นอันตราย โทเค็นที่มีฮุก ตัวรับการเรียกกลับ หรือโปรโตคอลอื่นที่เปลี่ยนแปลงการพึ่งพาที่ใช้ร่วมกัน เอกสารของ Solidity อธิบายว่าการโต้ตอบกับสัญญาอื่นสามารถส่งมอบการควบคุมให้กับสัญญานั้นได้ และแนะนำรูปแบบ Checks-Effects-Interactions: ตรวจสอบความถูกต้องก่อน อัปเดตสถานะของสัญญานี้เป็นลำดับที่สอง และโต้ตอบกับภายนอกเป็นลำดับสุดท้าย
อย่าจำกัดการค้นหาเฉพาะการโอน Ether ที่เห็นได้ชัด ตรวจสอบ hook แบบ ERC-777, callback แบบ ERC-1155, callback ของ flash loan, arbitrary router, การเรียก oracle และการเรียกผ่านไลบรารีที่สืบทอดมา ตรวจสอบการ reentrancy ข้ามฟังก์ชันและข้ามสัญญา: callback อาจเข้าสู่ฟังก์ชันอื่นที่อ่านสถานะระดับกลาง ยืนยันว่าการเรียกในระดับต่ำทุกครั้งตรวจสอบผลลัพธ์ที่สำเร็จและจัดการค่าที่ส่งคืนอย่างถูกต้อง ถามว่าผู้รับที่ล้มเหลวสามารถบล็อกการถอนเงินหรือลูปอย่างถาวรได้หรือไม่
บันทึกลำดับการโจมตีที่เป็นรูปธรรมสำหรับทุกปัญหาที่เป็นไปได้ ตัวอย่างเช่น: ผู้โจมตีฝากเงิน เริ่มการถอนเงิน ได้รับการติดต่อกลับ ป้อนการถอนเงินครั้งที่สอง และหลังจากนั้นจึงอนุญาตให้การเรียกครั้งแรกเสร็จสิ้น หากลำดับดังกล่าวไม่สามารถทำงานได้เนื่องจากเงื่อนไขหรือข้อจำกัดเฉพาะ ให้จดบันทึกเหตุผลนั้นไว้ วิธีนี้จะทำให้ข้อสรุปสามารถตรวจสอบได้ แทนที่จะเป็นการคาดเดา
ขั้นตอนที่ 5: ทดสอบค่าคงที่ทางคณิตศาสตร์และทางธุรกิจ
รายการตรวจสอบทางคณิตศาสตร์และตรรกะทางธุรกิจจะเน้นกรณีพิเศษที่การทดสอบแบบปกติมักมองข้ามไป
ตรวจสอบความหมายของหน่วยและการแปลงทุกอย่าง: wei เทียบกับ ether, ทศนิยมโทเค็น, จุดพื้นฐาน, หุ้นเทียบกับสินทรัพย์, ค่าที่มีเครื่องหมาย และหน่วยเวลา ปฏิบัติตามทิศทางการปัดเศษ การหารที่ปัดเศษไปในทิศทางที่เป็นประโยชน์ต่อผู้ฝาก ผู้กู้ ผู้ชำระบัญชี หรือผู้รับค่าธรรมเนียม อาจทำให้มูลค่าลดลงเมื่อทำซ้ำ ตรวจสอบการคูณก่อนการหาร จำนวนขั้นต่ำและสูงสุด ข้อจำกัดของค่าธรรมเนียม ราคาที่หมดอายุ อุปทานเป็นศูนย์ ยอดคงเหลือเป็นศูนย์ และผู้ฝากรายแรกหรือผู้ถอนรายสุดท้าย
Solidity เวอร์ชัน 0.8 และเวอร์ชันที่ใหม่กว่านั้น โดยปกติจะตรวจจับการล้นและการขาดของค่าทางคณิตศาสตร์ แต่โค้ดภายในuncheckedบล็อกสามารถเปลี่ยนแปลงพฤติกรรมนั้นได้โดยเจตนา การคำนวณแบบตรวจสอบค่าทางคณิตศาสตร์ยังอาจทำให้โปรโตคอลย้อนกลับหรือใช้งานไม่ได้หากไม่ได้ออกแบบข้อจำกัดอย่างถูกต้อง ทดสอบผลลัพธ์ทั้งสองแบบ: การขโมยหรือการบันทึกบัญชีที่ไม่ถูกต้อง และการปฏิเสธการให้บริการที่เกิดจากค่าที่ไม่สามารถประมวลผลได้
เขียนเงื่อนไขคงที่ด้วยภาษาที่เข้าใจง่ายก่อนที่จะแปลงเป็นชุดทดสอบ ตัวอย่างเช่น “จำนวนหุ้นทั้งหมดสอดคล้องกับสินทรัพย์ภายใต้กฎการปัดเศษที่ระบุไว้” “ผู้ใช้ไม่สามารถถอนเงินได้มากกว่าจำนวนเงินที่บันทึกไว้” “ปริมาณโทเค็นทั้งหมดเท่ากับผลรวมของยอดคงเหลือในกรณีที่โมเดลนั้นใช้ได้” และ “ค่าธรรมเนียมต้องไม่เกินขีดจำกัดที่กำหนดไว้” เปรียบเทียบยอดคงเหลือในการจัดเก็บกับยอดคงเหลือโทเค็นจริง เนื่องจากโทเค็นสามารถส่งไปยังสัญญาโดยตรงหรืออาจมีพฤติกรรมแตกต่างจากที่คาดการณ์ไว้ในการใช้งาน ERC-20
ขั้นตอนที่ 6: ตรวจสอบสิทธิ์การเข้าถึงและความสามารถในการอัปเกรด
การตรวจสอบสิทธิ์ควรเชื่อมโยงแต่ละบทบาทเข้ากับที่อยู่ การกระทำที่ได้รับอนุญาต กระบวนการถ่ายโอน และเส้นทางการอัปเกรด
สร้างเมทริกซ์สิทธิ์การเข้าถึง สำหรับฟังก์ชันการบริหารแต่ละฟังก์ชัน ให้ระบุบทบาทที่จำเป็น ผู้ถือครองปัจจุบัน กลไกการโอน การหน่วงเวลา การควบคุมลายเซ็นหลายฝ่ายหรือการกำกับดูแล และพฤติกรรมในกรณีฉุกเฉิน ให้ความสำคัญเป็นพิเศษกับการสร้างเหรียญ การหยุดชั่วคราว การเปลี่ยนแปลงค่าธรรมเนียม การเปลี่ยนแปลงแหล่งที่มาของออราเคิล การกู้คืนเงิน การอัปเกรดโค้ด และการเปลี่ยนแปลงโทเค็นที่เชื่อถือได้หรือที่อยู่เราเตอร์เอกสารเกี่ยวกับการควบคุมการเข้าถึง ของ OpenZeppelin แยกความแตกต่างระหว่างความเป็นเจ้าของแบบง่ายกับสิทธิ์ตามบทบาท และอธิบายว่าสิทธิ์ขั้นต่ำสุดเป็นแนวทางปฏิบัติด้านความปลอดภัยที่มีประโยชน์
แยกความแตกต่างระหว่าง “รหัสอนุญาตให้ผู้ดูแลระบบทำเช่นนี้ได้” กับ “ผู้ใช้ทั่วไปสามารถทำเช่นนี้ได้” ข้อแรกอาจเป็นความเสี่ยงด้านการกำกับดูแลหรือการควบคุมข้อมูลโดยตรง ส่วนข้อที่สองเป็นช่องโหว่ด้านการอนุญาต ตรวจสอบให้แน่ใจว่าการตรวจสอบบทบาทครอบคลุมทุกเส้นทางที่สำคัญ รวมถึงตัวช่วยภายในที่เข้าถึงได้จากฟังก์ชันสาธารณะ ตรวจสอบว่าผู้ดูแลระบบเริ่มต้นสามารถให้สิทธิ์เพิ่มเติมแก่ตนเองหรือผู้อื่นได้หรือไม่ และการโอนกรรมสิทธิ์สามารถถูกส่งไปยังที่อยู่ที่ไม่สามารถใช้งานได้โดยไม่ได้ตั้งใจหรือไม่
สำหรับพร็อกซี ให้ตรวจสอบตัวเริ่มต้น การอนุญาตการใช้งาน ความล่าช้าในการอัปเกรด รูปแบบการจัดเก็บ และแผนการย้อนกลับหรือแผนฉุกเฉินคำแนะนำเกี่ยวกับสัญญาที่สามารถอัปเกรดได้ ของ OpenZeppelin อธิบายว่าเหตุใดตัวสร้างจึงไม่เริ่มต้นการจัดเก็บพร็อกซี เหตุใดตัวเริ่มต้นจึงต้องได้รับการปกป้อง เหตุใดการใช้งานจึงไม่ควรปล่อยให้ไม่มีการเริ่มต้น และเหตุใดการเปลี่ยนลำดับหรือประเภทของการจัดเก็บจึงอาจทำให้การอัปเกรดเสียหายได้ ให้ถือว่าคีย์ผู้ดูแลระบบพร็อกซีเป็นส่วนหนึ่งของขอบเขตความปลอดภัยของโปรโตคอล ไม่ใช่รายละเอียดของการใช้งาน
ขั้นตอนที่ 7: ทดสอบระบบด้วยการทดสอบแบบฟัซซิ่ง ตัวแปรคงที่ และการแยกสาขา
หลักฐานจากแคมเปญที่ผ่านมานั้นมีประโยชน์ ในขณะที่ร่องรอยตัวอย่างค้านแสดงให้เห็นอย่างชัดเจนว่าลำดับใดที่ต้องได้รับการตรวจสอบ
ทำการทดสอบหน่วยเพื่อตรวจสอบพฤติกรรมที่คาดหวัง จากนั้นเพิ่มการทดสอบเชิงลบสำหรับผู้เรียกที่ไม่ได้รับอนุญาต ค่าศูนย์ ค่าสูงสุด ลายเซ็นหมดอายุ ข้อมูล Oracle ที่ล้าสมัย การโอนย้ายล้มเหลว และการดำเนินการซ้ำ ทดสอบอินพุตแบบฟัซซ์แทนที่จะทดสอบเฉพาะตัวเลขที่เลือกไว้ไม่กี่ตัว รวมผู้กระทำหลายรายและสัญญาผู้รับที่เป็นอันตรายในกรณีที่การออกแบบอนุญาตให้มีการเรียกกลับ
ใช้การทดสอบความคงที่สำหรับคุณสมบัติที่ต้องคงค่าเป็นจริงหลังจากมีการเรียกแบบสุ่มหลายครั้งเอกสารการทดสอบความคงที่ของ Foundryอธิบายถึงลำดับแบบสุ่ม อินพุตแบบฟัซซิ่ง การทำงาน ความลึก สัญญาเป้าหมาย และผู้ส่งเป้าหมาย กำหนดค่าแฮนด์เลอร์เพื่อให้การเรียกมีความหมาย หากการฝากเงินแบบฟัซซิ่งทุกครั้งกลับคืนสู่ค่าเดิมเนื่องจากแอคเตอร์ทดสอบไม่มีโทเค็น การทดสอบความคงที่ที่ผ่านอาจหมายความเพียงว่าไม่มีสถานะที่มีประโยชน์เปลี่ยนแปลงไป
เมื่อเป็นไปได้ ให้ใช้เครือข่ายเป้าหมายเวอร์ชันแยก (fork) เพื่อทดสอบที่อยู่ IP ที่ใช้งานอยู่ การกำหนดค่าปัจจุบัน พฤติกรรมของโทเค็น และการกำหนดเส้นทางพร็อกซี เก็บการทดสอบเวอร์ชันแยกไว้ในที่ปลอดภัยและอ่านได้อย่างเดียว เว้นแต่คุณจะใช้เวอร์ชันแยกในเครื่องที่แยกต่างหาก ลดลำดับความล้มเหลวทุกครั้งให้น้อยที่สุด และเก็บรักษาตัวอย่างที่ขัดแย้ง ที่อยู่ผู้เรียก บริบทของบล็อก ยอดคงเหลือ และค่าการจัดเก็บที่เกี่ยวข้อง การทดสอบที่ผ่านเป็นหลักฐานเกี่ยวกับเส้นทางที่ทดสอบ ไม่ใช่หลักฐานของเส้นทางที่เป็นไปได้ทั้งหมด
ขั้นตอนที่ 8: เขียนผลการตรวจสอบที่สามารถแก้ไขได้และทดสอบซ้ำได้
รายงานที่มีประโยชน์จะเชื่อมโยงความรุนแรงและสถานะเข้ากับหลักฐาน วิธีแก้ไขที่เฉพาะเจาะจง และเงื่อนไขการทดสอบซ้ำ
ใช้บันทึกหนึ่งรายการต่อหนึ่งประเด็น การค้นพบเชิงปฏิบัติควรประกอบด้วย:
- ชื่อเรื่องและสถานที่:สัญญา, หน้าที่, ไฟล์ และหมายเลขบรรทัดหรือรหัสอ้างอิง
- ผลกระทบ:สิ่งที่อาจถูกขโมย ถูกแช่แข็ง ถูกทำให้พองตัว ถูกหลีกเลี่ยง หรือเกิดความผิดพลาดได้
- เงื่อนไขเบื้องต้น:สิทธิ์การเข้าถึง ยอดคงเหลือ เวลา หรือการกำหนดค่าที่จำเป็น
- การจำลอง:ลำดับธุรกรรมสั้นๆ การทดสอบ การติดตาม หรือการพิสูจน์
- คำแนะนำ:ควรมีการเปลี่ยนแปลงรหัสหรือการดำเนินงานเฉพาะอย่าง โดยคำนึงถึงข้อดีข้อเสียด้วย
- สถานะ:เปิด, แก้ไขแล้ว, ลดผลกระทบแล้ว, ยอมรับความเสี่ยงแล้ว หรือไม่สามารถจำลองซ้ำได้
- ทดสอบซ้ำ:การทดสอบหรือการสังเกตที่ยืนยันผลการแก้ไขปัญหาอย่างแม่นยำ
ระดับความรุนแรงควรสะท้อนถึงผลกระทบและช่องโหว่ที่เกิดขึ้นจริง ไม่ใช่ว่ารูปแบบโค้ดดูน่ากลัวแค่ไหน อธิบายข้อสมมติฐาน การเรียกใช้ฟังก์ชันระดับต่ำอาจปลอดภัยภายใต้เงื่อนไขคงที่ที่เข้มงวด การเปลี่ยนแปลงพารามิเตอร์ที่ดูเหมือนธรรมดาอาจมีความสำคัญอย่างยิ่งหากมันควบคุมออราเคิลหรือการอัปเกรด หลังจากแก้ไขแล้ว ให้ตรวจสอบความแตกต่าง เรียกใช้การทดสอบที่เกี่ยวข้องอีกครั้ง เรียกใช้ชุดทดสอบทั้งหมดอีกครั้ง และตรวจสอบการถดถอย หากที่อยู่ใช้งานจริงได้รับการอัปเกรดหรือเปลี่ยนแปลงไปแล้ว ให้ทดสอบการใช้งานและการกำหนดค่าบนบล็อกเชนจริงอีกครั้ง
ข้อผิดพลาดทั่วไปในการตรวจสอบบัญชีที่ควรหลีกเลี่ยง
- “ซอร์สโค้ดได้รับการตรวจสอบแล้ว ดังนั้นจึงปลอดภัย”การตรวจสอบเป็นการสร้างความสัมพันธ์ระหว่างซอร์สโค้ดและไบต์โค้ด แต่ไม่ได้เป็นการตรวจสอบความถูกต้องของการออกแบบ
- “เครื่องสแกนไม่พบอะไรเลย ดังนั้นจึงไม่มีข้อผิดพลาด”เครื่องมือจะทำงานได้ดีที่สุดกับรูปแบบที่รู้จัก ในขณะที่ข้อบกพร่องทางเศรษฐกิจและข้อบกพร่องข้ามสัญญา มักต้องอาศัยการวิเคราะห์จากมนุษย์
- “โครงการนี้มีรายงานการตรวจสอบ ดังนั้นการใช้งานในปัจจุบันจึงอยู่ในขอบเขตที่กำหนด”เปรียบเทียบข้อมูลในรายงาน เช่น การเปลี่ยนแปลงโค้ด ขอบเขต ที่อยู่การใช้งาน การแก้ไข และประวัติการอัปเกรด
- “การทดสอบแบบ Fuzz ผ่านแล้ว ดังนั้นค่าคงที่จึงถูกต้อง”ขั้นแรก ตรวจสอบให้แน่ใจว่าค่าคงที่แสดงถึงคุณสมบัติทางเศรษฐกิจที่ต้องการ และตัวจัดการสามารถเข้าถึงสถานะที่มีความหมายได้
- “การควบคุมโดยผู้ดูแลระบบไม่ใช่ปัญหาด้านความปลอดภัย”อาจเป็นการตั้งสมมติฐานเรื่องความไว้วางใจโดยเจตนา แต่ผู้ใช้ควรจะสามารถเห็นได้ว่าใครสามารถสร้างเหรียญ หยุดชั่วคราว เปลี่ยนพารามิเตอร์ หรืออัปเกรดได้
ตรวจสอบตัวเองครั้งสุดท้ายก่อนเชื่อถือผลลัพธ์
คุณน่าจะตอบว่า "ใช่" สำหรับคำถามเหล่านี้ได้:
- ฉันได้บันทึกข้อมูลลำดับการเชื่อมต่อ ที่อยู่ ไบต์โค้ด พร็อกซี การใช้งาน และการตั้งค่าการสร้างอย่างแม่นยำหรือไม่?
- ฉันได้ตรวจสอบรายการจุดเข้าใช้งานที่เปลี่ยนแปลงสถานะทั้งหมดและสินทรัพย์ที่อาจได้รับผลกระทบแล้วหรือยัง?
- ฉันคอมไพล์โปรแกรมได้อย่างถูกต้อง ตรวจสอบคำเตือน และคัดกรองสิ่งที่ตรวจพบโดยอัตโนมัติแล้วหรือยัง?
- ฉันได้ตรวจสอบการเรียกใช้ภายนอก การเรียกกลับ การเรียกใช้ระดับต่ำ และเส้นทางความล้มเหลวทั้งหมดแล้วหรือยัง?
- ฉันได้ทดสอบการปัดเศษ ขีดจำกัด ค่าศูนย์ ข้อมูลเก่า และการกระทำซ้ำหรือไม่?
- ฉันได้กำหนดบทบาทพิเศษ คีย์ การหน่วงเวลา ตัวเริ่มต้น และเส้นทางการอัปเกรดทั้งหมดแล้วหรือยัง?
- ฉันได้รักษาความคลุมเครือที่มีความหมายและตัวอย่างค้านที่ไม่เปลี่ยนแปลงไว้หรือไม่?
- ผู้ตรวจสอบอิสระสามารถจำลองข้อค้นพบแต่ละข้อและยืนยันการแก้ไขแต่ละอย่างได้หรือไม่?
หากคำตอบใดเป็น "ไม่" ให้ระบุว่าการตรวจสอบไม่สมบูรณ์และระบุหลักฐานที่ขาดหายไป ข้อจำกัดที่ชัดเจนจะมีประโยชน์มากกว่าข้อสรุปที่คลุมเครือว่า "ปลอดภัย" การรักษาความปลอดภัยของสัญญาอัจฉริยะเป็นกระบวนการต่อเนื่อง: การอัปเกรด การเปลี่ยนแปลงการพึ่งพา การบูรณาการใหม่ และการเปลี่ยนแปลงสิทธิ์ทุกครั้งสามารถสร้างขอบเขตการตรวจสอบใหม่ได้