Mengekspresikan res.sendfile melemparkan kesalahan terlarang

160

Saya punya kode ini:

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

Namun, ini melempar kesalahan ini:

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)

Adakah yang bisa memberi tahu saya mengapa ini terjadi?


sumber
3
Saya percaya itu karena jalur relatif; "../" dianggap berbahaya. Selesaikan jalur lokal terlebih dahulu, lalu hubungires.sendfile
Joe
Bagaimana Anda menyelesaikan jalur lokal?
4
path.resolveharus melakukan apa yang Anda butuhkan.
Joe
1
Itu berhasil. Ingin melewatinya sebagai jawaban?

Jawaban:

285

Saya percaya itu karena jalur relatif; "../" dianggap berbahaya. Selesaikan jalur lokal terlebih dahulu, lalu panggil res.sendfile. Anda dapat menyelesaikan jalur dengan path.resolvesebelumnya.

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));
Joe
sumber
31
lebih detail akan berguna di sini untuk pemula seperti saya
Adam Waite
5
Ekspres menganggap jalur relatif sendfilesebagai buruk. Kecuali Anda menentukan rootparameter direktori, seperti yang terlihat di sini: github.com/visionmedia/express/issues/1465
Joe
2
var path = butuhkan ('path');
Matt Harrison
1
ya codE terakhir !!
SuperUberDuper
2
Pembaruan @MattHarrison ES6, untuk impor paket, constlebih disukai daripadavar
Nino Filiu
39

Jawaban ini mengumpulkan info dari jawaban / komentar lainnya.

Itu tergantung apakah Anda ingin memasukkan sesuatu yang relatif ke direktori kerja proses (cwd) atau direktori file. Keduanya menggunakan path.resolvefungsi (diletakkan var path = require('path')di bagian atas file.

  • relatif terhadap cwd: path.resolve('../../some/path/to/file.txt');
  • relatif terhadap file: path.resolve(__dirname+'../../some/path/to/file.txt');

Dari membaca tautan dari komentar @ Joe, sepertinya jalur relatif adalah risiko keamanan jika Anda menerima input pengguna untuk jalur tersebut (mis. sendfile('../.ssh/id_rsa')Mungkin percobaan pertama peretas).

derekdreery
sumber
1
SEBAGAI seorang pemula saya ingin tahu bagaimana skenario hacker datang ke sini?
bharath muppa
2
Jika Anda secara tidak sengaja mengizinkan pengguna untuk memasukkan jalur file yang ingin mereka unduh, mereka dapat mengunduh file apa saja di sistem Anda (saya berikan contoh kunci pribadi ssh - yang akan memberi mereka kemampuan untuk berpura-pura menjadi PC Anda ( man-in-the-middle dll)). Memiliki .. pembatasan melarang kemungkinan ini karena hanya file dari situs web yang dapat diakses.
derekdreery
30

The dokumentasi Ekspres menyarankan melakukannya dengan cara yang berbeda, dan menurut saya itu lebih masuk akal kemudian daripada solusi saat ini.

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

Opsi root tampaknya ditetapkan ./sebagai direktori root proyek Anda. Jadi saya tidak bisa sepenuhnya tahu di mana file Anda terkait dengan root proyek, tetapi jika folder temp Anda ada di sana, Anda dapat mengatur ./tempsebagai root untuk file yang Anda kirim.

tenor528
sumber
1
Ini benar, tetapi ia menggunakan sendFile (huruf kapital F, didukung oleh Express v4.8.0 dan seterusnya) alih-alih dari sendfile lama yang digunakan OP. Hanya mengatakan ... =]
RemyNL
Ahh ... tangkapan yang bagus. Saya tidak melihat perbedaan kecil ini. Saya juga bertanya-tanya apakah jawaban yang dipilih bekerja bukan karena menggunakan .sendfiletetapi karena ia bergantung pada sesuatu yang lain sepenuhnya (jalan). Terima kasih telah menunjukkan ini.
tenor528
Sederhana dan efisien. Terima kasih! Ini bekerja dengan baik untuk saya!
Emanuela Colta