จากคู่มือของ findutils:
ตัวอย่างเช่นการสร้างเช่นสองคำสั่งเหล่านี้
# risky find -exec sh -c "something {}" \; find -execdir sh -c "something {}" \;
อันตรายมาก เหตุผลนี้คือ '{}' ถูกขยายเป็นชื่อไฟล์ซึ่งอาจมีเครื่องหมายอัฒภาคหรืออักขระอื่น ๆ ที่พิเศษสำหรับเชลล์ หากตัวอย่างมีคนสร้างไฟล์
/tmp/foo; rm -rf $HOME
คำสั่งสองคำสั่งด้านบนสามารถลบโฮมไดเร็กตอรี่ของใครบางคนได้ดังนั้นด้วยเหตุนี้จึงไม่เรียกใช้คำสั่งใด ๆ ซึ่งจะส่งผ่านข้อมูลที่ไม่น่าเชื่อถือ (เช่นชื่อของไฟล์ les) ไปยังคำสั่งที่ตีความอาร์กิวเมนต์เป็นคำสั่งที่จะตีความเพิ่มเติม (เช่น 'sh')
ในกรณีของเชลล์มีวิธีแก้ไขปัญหาที่ฉลาดสำหรับปัญหานี้:
# safer find -exec sh -c 'something "$@"' sh {} \; find -execdir sh -c 'something "$@"' sh {} \;
วิธีการนี้ไม่รับประกันว่าจะหลีกเลี่ยงทุกปัญหา แต่จะปลอดภัยกว่าการแทนที่ข้อมูลของตัวเลือกของผู้โจมตีในข้อความของคำสั่งเชลล์
- เป็นสาเหตุของปัญหาที่เกิดขึ้นใน
find -exec sh -c "something {}" \;
การทดแทน{}
นั้นไม่มีการอ้างอิงและไม่ถือว่าเป็นสตริงเดี่ยวหรือไม่? ในการแก้ปัญหา
find -exec sh -c 'something "$@"' sh {} \;
,แรก
{}
จะถูกแทนที่ แต่เนื่องจาก{}
ไม่ได้กล่าวถึง"$@"
ก็ไม่มีปัญหาเช่นเดียวกับคำสั่งเดิม? ยกตัวอย่างเช่น"$@"
จะขยายไป"/tmp/foo;"
,"rm"
,"-rf"
และ"$HOME"
?เหตุใดจึง
{}
ไม่หนีหรืออ้างถึง
- คุณสามารถยกตัวอย่างอื่น ๆ (ยังมี
sh -c
หรือไม่มีก็ได้ถ้ามีหรือไม่มีfind
ซึ่งอาจไม่จำเป็น) ที่มีปัญหาและวิธีแก้ไขปัญหาแบบเดียวกันและเป็นตัวอย่างที่น้อยที่สุดเพื่อให้เราสามารถมุ่งเน้นไปที่ปัญหาและวิธีแก้ปัญหาด้วย สิ่งที่ทำให้ไขว้เขวน้อยที่สุดที่เป็นไปได้? ดูวิธีในการจัดเตรียมอาร์กิวเมนต์สำหรับคำสั่งที่ดำเนินการโดย `bash -c`
ขอบคุณ