Express res.sendfile wirft verbotenen Fehler

160

Ich habe diesen Code:

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

Es wird jedoch der folgende Fehler ausgegeben:

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)

Kann mir jemand sagen, warum das so sein könnte?


quelle
3
Ich glaube, es liegt am relativen Weg; Das "../" wird als bösartig angesehen. Lösen Sie zuerst den lokalen Pfad auf und rufen Sie dannres.sendfile
Joe
Wie lösen Sie den lokalen Pfad auf?
4
path.resolvesollte tun, was Sie brauchen.
Joe
1
Das hat es geschafft. Möchten Sie das als Antwort hinter sich lassen?

Antworten:

285

Ich glaube, es liegt am relativen Weg; Das "../" wird als bösartig angesehen. Lösen Sie zuerst den lokalen Pfad auf und rufen Sie dann auf res.sendfile. Sie können den Pfad mit im path.resolveVoraus auflösen .

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));
Joe
quelle
31
Weitere Details wären hier praktisch für Neulinge wie mich
Adam Waite
5
Express betrachtet relative Pfade sendfileals schlecht. Es sei denn, Sie geben den rootVerzeichnisparameter an, wie hier zu sehen: github.com/visionmedia/express/issues/1465
Joe
2
var path = require ('path');
Matt Harrison
1
Ja, der endgültige Code !!
SuperUberDuper
2
@MattHarrison ES6 Update für Pakete , die Einfuhr, constwird bevorzugt übervar
Nino Filiu
39

Diese Antwort sammelt die Informationen aus den anderen Antworten / Kommentaren.

Es hängt davon ab, ob Sie etwas relativ zum Prozessarbeitsverzeichnis (cwd) oder zum Dateiverzeichnis einfügen möchten. Beide verwenden die path.resolveFunktion ( var path = require('path')oben in der Datei.

  • relativ zu cwd: path.resolve('../../some/path/to/file.txt');
  • relativ zur Datei: path.resolve(__dirname+'../../some/path/to/file.txt');

Wenn Sie den Link aus @ Joes Kommentar lesen, klingt es so, als ob relative Pfade ein Sicherheitsrisiko darstellen, wenn Sie Benutzereingaben für den Pfad akzeptieren (z. B. sendfile('../.ssh/id_rsa')könnte dies der erste Versuch eines Hackers sein).

derekdreery
quelle
1
Als Neuling möchte ich wissen, wie das Hacker-Szenario hierher kam?
Bharath Muppa
2
Wenn Sie dem Benutzer versehentlich erlauben, den Pfad der Datei einzugeben, die er herunterladen möchte, kann er jede Datei auf Ihrem System herunterladen (ich habe das Beispiel eines privaten SSH-Schlüssels angegeben, der ihm die Möglichkeit gibt, sich als Ihr PC auszugeben). Mann in der Mitte usw.)). Mit der Einschränkung .. wird diese Möglichkeit nicht zugelassen, da nur auf Dateien von der Website zugegriffen werden kann.
Derekdreery
30

Die Express-Dokumentation schlägt vor, es anders zu machen, und meiner Meinung nach ist es später sinnvoller als die aktuelle Lösung.

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

Die Root-Option scheint ./als Root-Verzeichnis Ihres Projekts festgelegt zu sein. Ich kann also nicht vollständig sagen, wo sich Ihre Datei in Bezug auf das Projektstammverzeichnis befindet. Wenn sich Ihr temporärer Ordner dort befindet, können Sie ihn ./tempals Stammverzeichnis für die Datei festlegen , die Sie senden.

Tenor528
quelle
1
Dies ist richtig, verwendet jedoch sendFile (Großbuchstabe F, unterstützt von Express v4.8.0) anstelle der älteren Sendedatei, die das OP verwendet hat.
Ich
Ahh ... guter Fang. Ich habe diesen kleinen Unterschied nicht bemerkt. Ich frage mich auch, ob die ausgewählte Antwort nicht funktioniert, weil sie verwendet wird, .sendfilesondern weil sie sich vollständig auf etwas anderes stützt (Pfad). Vielen Dank für den Hinweis.
Tenor528
Einfach und effizient. Danke dir! Das hat bei mir perfekt funktioniert!
Emanuela Colta