Express res.sendfile การโยนข้อผิดพลาดที่ต้องห้าม


160

ฉันมีรหัสนี้:

res.sendfile( '../../temp/index.html' )

อย่างไรก็ตามมันจะพ่นข้อผิดพลาดนี้:

Error: Forbidden
at SendStream.error (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.pipe (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:307:39)
at ServerResponse.res.sendfile (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/response.js:339:8)
at exports.boot (/Users/Oliver/Development/Personal/Reader/server/config/routes.js:18:9)
at callbacks (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:161:37)
at param (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:33:10)
at next (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/connect/lib/proto.js:199:15)

มีใครบอกฉันได้ไหมว่าทำไมเรื่องนี้ถึงเป็นเช่นนั้น


3
ฉันเชื่อว่าเป็นเพราะเส้นทางญาติ "../" ถือว่าเป็นอันตราย แก้ไขเส้นทางท้องถิ่นก่อนแล้วจึงโทรres.sendfile
Joe

คุณจะแก้ไขเส้นทางท้องถิ่นได้อย่างไร

4
path.resolveควรทำสิ่งที่คุณต้องการ
Joe

1
นั่นมัน ต้องการที่จะผ่านมาว่าเป็นคำตอบ?

คำตอบ:


286

ฉันเชื่อว่าเป็นเพราะเส้นทางญาติ "../" ถือว่าเป็นอันตราย res.sendfileแก้ไขเส้นทางภายในครั้งแรกแล้วโทร คุณสามารถแก้ไขเส้นทางด้วยpath.resolveล่วงหน้า

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));

31
รายละเอียดเพิ่มเติมจะมีประโยชน์สำหรับมือใหม่ที่นี่อย่างฉัน
Adam Waite

5
Express พิจารณาเส้นทางที่สัมพันธ์กันในsendfileสภาพที่ไม่ดี ยกเว้นว่าคุณระบุrootพารามิเตอร์ไดเรกทอรีตามที่เห็นที่นี่: github.com/visionmedia/express/issues/1465
Joe

2
var path = require ('path');
Matt Harrison

1
ใช่ codE สุดท้าย !!
SuperUberDuper

2
การอัพเดท @MattHarrison ES6 สำหรับการนำเข้าแพ็คเกจconstเป็นสิ่งที่ต้องการมากกว่าvar
Nino Filiu

39

คำตอบนี้รวบรวมข้อมูลจากคำตอบ / ความคิดเห็นอื่น ๆ

ขึ้นอยู่กับว่าคุณต้องการรวมบางสิ่งที่สัมพันธ์กับไดเร็กทอรีการทำงานของกระบวนการ (cwd) หรือไดเร็กทอรีไฟล์ ทั้งสองใช้path.resolveฟังก์ชัน (วางvar path = require('path')ที่ด้านบนของไฟล์

  • สัมพันธ์กับ cwd: path.resolve('../../some/path/to/file.txt');
  • สัมพันธ์กับไฟล์: path.resolve(__dirname+'../../some/path/to/file.txt');

จากการอ่านลิงก์จากความคิดเห็นของ @ Joe ดูเหมือนว่าเส้นทางที่สัมพันธ์กันมีความเสี่ยงด้านความปลอดภัยหากคุณยอมรับการป้อนข้อมูลของผู้ใช้สำหรับเส้นทาง (เช่นsendfile('../.ssh/id_rsa')อาจเป็นการพยายามครั้งแรกของแฮ็กเกอร์)


1
ในฐานะมือใหม่ฉันอยากรู้ว่าสถานการณ์แฮ็กเกอร์มาที่นี่ได้อย่างไร
bharath muppa

2
หากคุณอนุญาตให้ผู้ใช้ป้อนเส้นทางของไฟล์ที่พวกเขาต้องการดาวน์โหลดพวกเขาสามารถดาวน์โหลดไฟล์ใด ๆ ในระบบของคุณ (ฉันให้ตัวอย่างของรหัสส่วนตัว ssh - ซึ่งจะทำให้พวกเขาสามารถแกล้งเป็นพีซีของคุณได้) คนกลาง ฯลฯ )) การมีข้อ จำกัด .. ไม่อนุญาตให้มีความเป็นไปได้เนื่องจากไฟล์เท่านั้นจากเว็บไซต์ที่สามารถเข้าถึงได้
derekdreery

30

เอกสารด่วนที่แสดงให้เห็นการทำมันเป็นวิธีที่แตกต่างกันและในความคิดของฉันมันทำให้รู้สึกมากขึ้นกว่าการแก้ปัญหาในปัจจุบัน

res.sendFile('index.html', {root: './temp'});

ดูเหมือนว่าตัวเลือกรูทจะตั้ง./เป็นไดเรกทอรีหลักของโครงการของคุณ ดังนั้นฉันจึงไม่สามารถบอกได้อย่างเต็มที่ว่าไฟล์ของคุณเกี่ยวข้องกับรูทโครงการหรือไม่ถ้าโฟลเดอร์ temp ของคุณอยู่ที่นั่นคุณสามารถตั้งค่า./tempเป็นรูทสำหรับไฟล์ที่คุณกำลังส่ง


1
สิ่งนี้เป็นจริง แต่ใช้ sendFile (ตัวใหญ่ F สนับสนุนโดย Express v4.8.0 เป็นต้นไป) แทนที่จะเป็น sendfile รุ่นเก่าที่ OP ใช้อยู่ เพียงแค่พูดว่า ... =]
RemyNL

อ่า ... จับได้ดี ฉันไม่ได้สังเกตเห็นความแตกต่างเล็กน้อยนี้ ฉันยังสงสัยว่าคำตอบที่เลือกไม่ได้เพราะมันใช้.sendfileแต่เพราะมันขึ้นอยู่กับสิ่งอื่นอย่างสมบูรณ์ (เส้นทาง) ขอบคุณที่ชี้นำสิ่งนี้
tenor528

เรียบง่ายและมีประสิทธิภาพ ขอบคุณ! สิ่งนี้ใช้ได้สำหรับฉันอย่างสมบูรณ์แบบ!
Emanuela Colta
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.