금지 된 오류를 던지는 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를 나쁜 것으로 간주 합니다. github.com/visionmedia/express/issues/1465root
Joe

2
var path = require ( '경로');
매트 해리슨

1
그래, 마지막 대구!
SuperUberDuper

2
@MattHarrison ES6 업데이트 패키지 수입을 위해, const이상이 바람직하다var
니노 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 개인 키의 예를 들었습니다. man-in-the-middle 등)). .. 제한이 있으면 웹 사이트의 파일에만 액세스 할 수 있으므로이 가능성이 허용되지 않습니다.
데케 드레

30

Express 설명서는 그것을 다른 방식으로 일을 제안하고, 내 의견으로는 나중에 현재의 솔루션보다 더 의미가 있습니다.

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

루트 옵션은 ./프로젝트의 루트 디렉토리 로 설정된 것 같습니다 . 따라서 프로젝트 루트와 관련하여 파일이 어디에 있는지 완전히 알 수는 없지만 임시 폴더가 있으면 ./temp보내는 파일의 루트로 설정할 수 있습니다 .


1
이것은 사실이지만 OP가 사용하던 이전 sendfile 대신 sendFile (Express v4.8.0에서 지원되는 대문자 F)을 사용합니다. 그냥 말하면 ... =]
RemyNL

아 .. 잘 잡았습니다. 나는이 작은 차이를 눈치 채지 못했습니다. 또한 선택한 답변이 사용 .sendfile하기 때문이 아니라 다른 것에 완전히 의존하기 때문에 작동하는지 궁금합니다 (경로). 이것을 지적 해 주셔서 감사합니다.
tenor528

간단하고 효율적입니다. 감사합니다! 이것은 나를 위해 완벽하게 작동했습니다!
Emanuela Colta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.