นักวิจัยจากมหาวิทยาลัยเคมบริดจ์ได้เผยแพร่เทคนิคการแทรกโค้ดที่เป็นอันตรายลงในซอร์สโค้ดที่ผ่านการตรวจสอบโดยผู้ทรงคุณวุฒิโดยไม่สามารถตรวจจับได้ วิธีการโจมตีนี้ (CVE-2021-42574) หรือที่รู้จักกันในชื่อ Trojan Source นั้น อาศัยการสร้างข้อความที่ดูแตกต่างกันระหว่างคอมไพเลอร์/ตัวแปลภาษา และผู้ตรวจสอบที่เป็นมนุษย์ ตัวอย่างการประยุกต์ใช้เทคนิคนี้แสดงให้เห็นในคอมไพเลอร์และตัวแปลภาษาต่างๆ ที่มีให้ใช้งานสำหรับภาษา C, C++ (gcc และ clang), C#, JavaScript (Node.js), Java (OpenJDK 16), Rust, Go และ Python
วิธีการนี้อาศัยการใช้ตัวอักษรยูนิโค้ดพิเศษในคำอธิบายโค้ด ซึ่งจะเปลี่ยนลำดับการแสดงผลของข้อความสองทิศทาง ตัวอักษรควบคุมเหล่านี้ช่วยให้บางส่วนของข้อความแสดงผลจากซ้ายไปขวา ในขณะที่ส่วนอื่นๆ แสดงผลจากขวาไปซ้าย ในทางปฏิบัติ ตัวอักษรควบคุมเหล่านี้สามารถใช้เพื่อแทรกข้อความภาษาฮิบรูหรือภาษาอาหรับลงในไฟล์โค้ดได้ อย่างไรก็ตาม หากรวมข้อความที่มีทิศทางการแสดงผลต่างกันไว้ในบรรทัดเดียวกันโดยใช้ตัวอักษรเหล่านี้ ส่วนของข้อความที่แสดงผลจากขวาไปซ้ายอาจทับซ้อนกับข้อความที่แสดงผลจากซ้ายไปขวาตามปกติได้
ด้วยวิธีนี้ สามารถแทรกโครงสร้างที่เป็นอันตรายเข้าไปในโค้ดได้ แต่ข้อความที่ประกอบด้วยโครงสร้างนั้นสามารถทำให้ตรวจจับไม่ได้โดยการเพิ่มอักขระจากขวาไปซ้ายในความคิดเห็นถัดไปหรือภายในข้อความตัวอักษร ส่งผลให้อักขระที่ทับซ้อนกับส่วนที่แทรกเข้ามานั้นแตกต่างกันโดยสิ้นเชิง โค้ดดังกล่าวจะยังคงถูกต้องตามความหมาย แต่จะถูกตีความและแสดงผลแตกต่างกันออกไป

ในระหว่างการตรวจสอบโค้ด นักพัฒนาจะพบกับลำดับตัวอักษรที่มองเห็นได้ และเห็นข้อความแสดงความคิดเห็นที่ไม่เป็นอันตรายในโปรแกรมแก้ไขข้อความสมัยใหม่ อินเทอร์เฟซบนเว็บ หรือ IDE อย่างไรก็ตาม คอมไพเลอร์และอินเตอร์พรีเตอร์จะใช้ลำดับตัวอักษรเชิงตรรกะและประมวลผลการแทรกที่เป็นอันตรายนั้นตามเดิม โดยไม่สนใจข้อความแบบสองทิศทางในข้อความแสดงความคิดเห็น ปัญหานี้ส่งผลกระทบต่อโปรแกรมแก้ไขโค้ดที่เป็นที่นิยมต่างๆ (VS Code, Emacs, Atom) รวมถึงอินเทอร์เฟซสำหรับการดูโค้ดในที่เก็บ (GitHub, Gitlab, BitBucket และผลิตภัณฑ์ Atlassian ทั้งหมด)

มีหลายวิธีที่จะใช้ประโยชน์จากวิธีการนี้เพื่อกระทำการที่เป็นอันตราย เช่น การเพิ่มคำสั่ง "return" ที่ซ่อนอยู่ซึ่งทำให้ฟังก์ชันหยุดทำงานก่อนกำหนด การใส่เครื่องหมายคอมเมนต์ในคำสั่งที่ปกติแล้วมองเห็นได้ว่าเป็นโครงสร้างที่ถูกต้อง (ตัวอย่างเช่น เพื่อปิดใช้งานการตรวจสอบที่สำคัญ) หรือการกำหนดค่าสตริงอื่น ๆ ที่ทำให้การตรวจสอบความถูกต้องของสตริงล้มเหลว
ตัวอย่างเช่น ผู้โจมตีอาจเสนอการเปลี่ยนแปลงที่รวมบรรทัดต่อไปนี้: if access_level != "user{U+202E} {U+2066}// Check if admin{U+2069} {U+2066}" {
ซึ่งจะแสดงในอินเทอร์เฟซการตรวจสอบราวกับว่า access_level != "user" { // ตรวจสอบว่าเป็นผู้ดูแลระบบหรือไม่
มีการเสนอช่องโหว่การโจมตีอีกรูปแบบหนึ่ง (CVE-2021-42694) ซึ่งเกี่ยวข้องกับการใช้โฮโมกลิฟ—สัญลักษณ์ที่มีลักษณะคล้ายกันแต่มีความหมายและรหัสยูนิโค้ดต่างกัน (ตัวอย่างเช่น สัญลักษณ์ "ɑ" คล้ายกับ "a", "ɡ" คล้ายกับ "g" และ "ɩ" คล้ายกับ "l") สัญลักษณ์เหล่านี้สามารถใช้ในบางภาษาในชื่อฟังก์ชันและตัวแปรเพื่อทำให้ผู้พัฒนาเข้าใจผิด ตัวอย่างเช่น อาจมีการกำหนดฟังก์ชันสองฟังก์ชันที่มีชื่อเหมือนกันแต่ทำงานต่างกัน หากไม่มีการวิเคราะห์อย่างละเอียด จะไม่สามารถระบุได้ทันทีว่าฟังก์ชันใดถูกเรียกใช้ในตำแหน่งใด

เพื่อเป็นมาตรการรักษาความปลอดภัย ขอแนะนำให้คอมไพเลอร์ อินเตอร์พรีเตอร์ และเครื่องมือสร้างโปรแกรมที่รองรับอักขระยูนิโค้ด แสดงข้อผิดพลาดหรือคำเตือนเมื่อคอมเมนต์ สตริงลิเทอรัล หรือตัวระบุมีอักขระควบคุมที่ไม่จับคู่ซึ่งเปลี่ยนทิศทางการแสดงผล (U+202A, U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069, U+061C, U+200E และ U+200F) อักขระเหล่านี้ควรถูกห้ามอย่างชัดเจนในข้อกำหนดของภาษาโปรแกรม และควรนำมาพิจารณาในโปรแกรมแก้ไขโค้ดและอินเทอร์เฟซของที่เก็บโค้ดด้วย
อัปเดต 1: ได้มีการเตรียมแพตช์เพื่อแก้ไขช่องโหว่สำหรับ GCC, LLVM/Clang, Rust, Go, Python และ binutils แล้ว นอกจากนี้ GitHub, Bitbucket และ Jira ก็ได้แก้ไขปัญหาแล้วเช่นกัน ส่วนการแก้ไขสำหรับ GitLab กำลังอยู่ระหว่างการเตรียมการ เพื่อระบุโค้ดที่มีปัญหา ขอแนะนำให้ใช้คำสั่ง: grep -r $'[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]' /path/to/source
ภาคผนวก 2: รัสส์ ค็อกซ์ หนึ่งในผู้พัฒนา Plan 9 OS และภาษาโปรแกรม Go ได้วิพากษ์วิจารณ์การให้ความสนใจมากเกินไปกับวิธีการโจมตีที่กล่าวถึง ซึ่งเป็นที่รู้จักกันมานานแล้ว (ใน Go, Rust, C++, Ruby) และถูกมองข้ามไปแล้ว ตามที่ค็อกซ์กล่าว ปัญหาหลักๆ เกี่ยวข้องกับการแสดงข้อมูลอย่างถูกต้องในโปรแกรมแก้ไขโค้ดและส่วนติดต่อผู้ใช้บนเว็บ และสามารถแก้ไขได้โดยการใช้เครื่องมือและโปรแกรมวิเคราะห์โค้ดที่เหมาะสมในระหว่างการตรวจสอบ ดังนั้น แทนที่จะให้ความสนใจกับการโจมตีแบบคาดเดา การมุ่งเน้นไปที่การปรับปรุงกระบวนการตรวจสอบโค้ดและส่วนประกอบต่างๆ จะเหมาะสมกว่า
รัสส์ ค็อกซ์ เชื่อว่าคอมไพเลอร์ไม่ใช่สถานที่ที่เหมาะสมในการแก้ไขปัญหา เพราะการปิดใช้งานสัญลักษณ์อันตรายในระดับคอมไพเลอร์จะทำให้เครื่องมือต่างๆ จำนวนมากยังคงอนุญาตให้ใช้สัญลักษณ์เหล่านี้ได้ เช่น ระบบสร้างโปรแกรม แอสเซมเบลอร์ ตัวจัดการแพ็กเกจ และตัวแยกวิเคราะห์ข้อมูลและการกำหนดค่าต่างๆ ตัวอย่างเช่น โครงการ Rust ซึ่งไม่อนุญาตให้ประมวลผลโค้ด LTR/RTL ในคอมไพเลอร์ แต่ล้มเหลวในการแก้ไขสำหรับตัวจัดการแพ็กเกจ Cargo ทำให้เกิดการโจมตีในลักษณะเดียวกันผ่านไฟล์ Cargo.toml ในทำนองเดียวกัน ไฟล์ต่างๆ เช่น BUILD.bazel, CMakefile, Cargo.toml, Dockerfile, GNUmakefile, Makefile, go.mod, package.json, pom.xml และ requirements.txt ก็อาจกลายเป็นแหล่งที่มาของการโจมตีได้เช่นกัน
ที่มา: opennet.ru
