Score:1

ฉันควรหลีกเลี่ยงเครื่องหมายทับ '/' ใน RewriteCond หรือไม่

ธง cn

ฉันต้องหลีกเลี่ยงเครื่องหมายทับ '/' ใน RewriteCond หรือไม่

ขณะนี้ฉันเขียนกฎต่อไปนี้ใน .htaccess:

RewriteCond %{QUERY_STRING} rp=/knowledgebase/
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]

อย่างไรก็ตาม วิธีนี้ใช้ได้เฉพาะกับ URL เช่น https://www.datanumen.com/fi/customer/index.php?rp=/knowledgebase/7/How-to-order-the-full-version-of-DataNumen-Access-Repair.html&language=swedishแต่ใช้งานไม่ได้กับ URL เช่น https://www.datanumen.com/fi/customer/index.php?rp=%2Fknowledgebase%2F7%2FHow-to-order-the-full-version-of-DataNumen-Access-Repair.html&language=swedish

เลยต้องแก้ไขกฎดังนี้

RewriteCond %{QUERY_STRING} rp=/knowledgebase/ [หรือ]
RewriteCond %{QUERY_STRING} rp=%2Fknowledgebase%2F
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]

แต่ฉันตรวจสอบ https://serverfault.com/a/968916/280923 และมันบอกว่า "เครื่องหมายทับ (/) ไม่จำเป็นต้องหนี“.ก็เลยงง.

ถ้าฉันต้องพิจารณาทุกสถานการณ์ เช่น เวอร์ชันที่ใช้ Escape และเวอร์ชันที่ไม่ใช้ Escape ของ '/' ดังนั้นควรมีชุดค่าผสมทั้งหมด 4 ชุด ฉันควรเพิ่มทั้งหมดเป็น RewriteCond:

rp=/ฐานความรู้/
rp=%2Fฐานความรู้%2F
rp=%2Fฐานความรู้/
rp=/knowledgebase%2F
Score:1
ธง kz

ฉันควรจะหนีการเฉือน / ใน เขียนซ้ำ?

โดย "escape the slash" คุณหมายถึง "ฉันควรจับคู่ URL ที่เข้ารหัสเครื่องหมายทับหรือไม่" ขึ้นอยู่กับคำขอ HTTP ที่ส่งไปยังเซิร์ฟเวอร์ของคุณทั้งหมด

แต่ฉันตรวจสอบ https://serverfault.com/a/968916/280923 และมันบอกว่า "เครื่องหมายทับ (/) ไม่ต้องหนี" ผมก็เลยงง

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

สิ่งที่คุณกำลังจัดการคือ %-encoded URL URL ปรากฏในคำขอ HTTP อย่างไร ส่วนต่างๆ ของ URL (โดยเฉพาะอย่างยิ่ง "เส้นทาง" และ "สตริงข้อความค้นหา") มีข้อกำหนดในการเข้ารหัสที่แตกต่างกัน ไม่ว่าจะเป็นตัวละครเฉพาะ ความต้องการ การจะเข้ารหัส % ขึ้นอยู่กับว่าจะมีความหมายพิเศษในบริบทนั้นหรือไม่

ตามที่กำหนดไว้ใน RFC3986, เครื่องหมายทับ (/) ไม่จำเป็นต้องเข้ารหัส % อย่างเคร่งครัดในส่วนสตริงข้อความค้นหาของ URL อย่างไรก็ตาม ฟังก์ชันการเข้ารหัส URL (เช่น ใน PHP และ JavaScript) มักจะ %-เข้ารหัสอักขระนี้ (ฉันคิดว่านี่เป็นเรื่องในอดีตเป็นส่วนใหญ่เนื่องจากการใช้งานแบบเก่าบางรายการไม่ได้จัดการเครื่องหมายทับที่ไม่ได้เข้ารหัสอย่างถูกต้อง - อ้างอิง RFC3986.)

อย่างไรก็ตามไม่ว่าจะเป็นตัวละคร ความต้องการ ในการเข้ารหัส URL (เพื่อลบล้างความหมายพิเศษ) อักขระใดๆ สามารถเข้ารหัส % ได้ และควรได้รับการปฏิบัติเช่นเดียวกับอักขระที่เป็นตัวอักษร (ไม่ได้เข้ารหัส)

ไม่ว่าคุณจะต้องการจับคู่หรือไม่ / (ถอดรหัส) หรือ %2F (เข้ารหัส) ขึ้นอยู่กับว่าอักขระนั้นถูกเข้ารหัส % ในคำขอหรือไม่

ปัญหาของคุณก็คือว่า QUERY_STRING ตัวแปรเซิร์ฟเวอร์ไม่ได้ถอดรหัส % ซึ่งแตกต่างจากเส้นทาง URL ที่จับคู่โดย เขียนกฎใหม่ ลวดลาย.

แต่... คุณต้องตรวจสอบทั้ง %-decoded หรือไม่ / และ %-เข้ารหัส %2F? สันนิษฐานว่าคุณกำลังลิงก์ไปยัง URL (ตามรูปแบบบัญญัติ) เพียงรายการเดียวหรือ URL อื่นอย่างสม่ำเสมอ ดังนั้น คำขอใดๆ ที่ส่งไปยัง URL ที่ไม่ใช่ตามรูปแบบบัญญัติจะต้องพิมพ์ด้วยตนเองหรือเชื่อมโยงไปยังบุคคลที่สามอย่างไม่ถูกต้อง คุณได้รับคำขอทั้งสองหรือไม่ อะไรคือผลของการไม่เปลี่ยนเส้นทาง URL ที่ไม่ใช่ตามรูปแบบบัญญัติ

มิฉะนั้น ใช่ คุณจะต้องตรวจสอบทั้งสองอย่าง (และอาจเป็นรูปแบบ/กรณีทั้งหมด) แม้ว่านี่จะเป็นเพียงแค่ /ฐานความรู้/ หรือ %2Fฐานความรู้%2F. แต่โปรดทราบว่าอาจเป็นได้ %2F (ตัวพิมพ์ใหญ่) หรือ %2ฉ (ตัวพิมพ์เล็ก). ตัวพิมพ์ใหญ่เป็นเพียงแบบแผน ต้องตรวจสอบการเข้ารหัสแบบผสม เช่น %2Fฐานความรู้/ น่าจะหายากมาก แต่นำไปมากนี้ก็เช่นเดียวกับ %2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f. คุณจะต้องจัดการกับรูปแบบเหล่านี้ทั้งหมดหรือไม่นั้นขึ้นอยู่กับความเป็นไปได้ที่จะได้รับคำขอดังกล่าวและความรุนแรงของกฎที่ไม่ตรงกัน

ดังนั้นเพื่อให้ตรงกับทั้งสอง /ฐานความรู้/ และ %2Fฐานความรู้%2F (ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่) คุณสามารถใช้สิ่งต่อไปนี้:

RewriteCond %{QUERY_STRING} ^rp=(/|%2[Ff])ฐานความรู้(/|%2[Ff])

คุณสามารถหลีกเลี่ยงคลาสตัวละครได้ [เอฟ] และใช้ เอ็น.ซี ตั้งค่าสถานะแทนเพื่อให้การเปรียบเทียบทั้งหมดไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ ตัวอย่างเช่น:

RewriteCond %{QUERY_STRING} ^rp=(/|%2F)ฐานความรู้(/|%2F) [NC]

บน Apache 2.4 คุณสามารถใช้ไฟล์ ยูสเคป() ทำงานในนิพจน์ Apache ด้วย เขียนซ้ำ คำสั่งไปยัง URL ถอดรหัส QUERY_STRING ก่อนทำการเปรียบเทียบ อย่างไรก็ตาม สิ่งนี้ไม่ได้ช่วยคุณได้จริงๆ เนื่องจากมันไม่ได้ %-decode ทับ เช่น %2F หรือ %2ฉ ยังคงอยู่ตามคำขอ (แต่อักขระอื่น ๆ จะถูก % -decoded) ตัวอย่างเช่น:

RewriteCond expr "unescape(%{QUERY_STRING}) =~ m#^rp=(/|%2[Ff])ฐานความรู้(/|%2[Ff])#"

สิ่งนี้จะช่วยให้คุณจับคู่ได้ rp=%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f.


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

# บล็อกคำขอใดๆ ที่มีอักขระ %-encoded ในสตริงข้อความค้นหา
RewriteCond %{QUERY_STRING} %[\da-f]{2} [NC]
RewriteRule ^ - [R=400]
alancc avatar
cn flag
ขอบคุณมาก. ตอนนี้ฉันเข้าใจแล้ว

โพสต์คำตอบ

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