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
それで終わりました。それを答えとして貼り付けたいですか?

回答:


285

それは相対パスのせいだと思います。「../」は悪意があると見なされます。最初にローカルパスを解決してから、を呼び出しますres.sendfilepath.resolve事前にパスを解決できます。

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

31
詳細は、私のような初心者にとってここで便利です
アダムウェイト2013

5
Expressは相対パスsendfileを不良と見なします。次のように、rootディレクトリパラメータを指定しない限り:github.com/visionmedia/express/issues/1465
Joe

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

1
ええ、最後のコードです!!
SuperUberDuper 2016年

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 2015

2
ユーザーがダウンロードしたいファイルのパスを誤って入力することをユーザーに許可した場合、ユーザーはシステム上の任意のファイルをダウンロードする可能性があります(私はssh秘密鍵の例を示しました-これにより、PCのふりをすることができます(中間者など))。..制限を設けると、Webサイトからのファイルのみにアクセスできるため、この可能性が拒否されます。
derekdreery 2015年

30

Expressのドキュメントには、それを別の方法をやって示唆し、私の意見では、それは後に現在のソリューションよりも多くの意味があります。

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

rootオプション./は、プロジェクトのルートディレクトリとして設定されているようです。そのため、ファイルがプロジェクトルートとの関係でどこにあるのか完全にはわかりませんが、一時フォルダーがそこにある場合は、./temp送信するファイルのルートとして設定できます。


1
これは本当ですが、OPが使用していた古いsendfileの代わりにsendFile(大文字のF、Express v4.8.0以降でサポート)を使用します。ただ言って... =]
RemyNL

ああ...良いキャッチ。この小さな違いに気づきませんでした。また、選択した回答が機能するのでは.sendfileなく、完全に別のもの(パス)に依存しているために機能するかどうかも疑問です。これを指摘してくれてありがとう。
tenor528 2016

シンプルで効率的。ありがとうございました!これは完璧に機能しました!
エマヌエラコルタ2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.