Express res.sendfile lançando erro proibido


160

Eu tenho este código:

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

No entanto, ele lança este erro:

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)

Alguém pode me dizer por que isso pode ser?


3
Eu acredito que é por causa do caminho relativo; o "../" é considerado malicioso. Resolver o caminho local em primeiro lugar, em seguida, chamarres.sendfile
Joe

Como você resolve o caminho local?

4
path.resolvedeve fazer o que você precisa.
Joe

1
Isso foi o que aconteceu. Quer deixar isso como resposta?

Respostas:


285

Eu acredito que é por causa do caminho relativo; o "../" é considerado malicioso. Resolva o caminho local primeiro e depois ligue res.sendfile. Você pode resolver o caminho com path.resolveantecedência.

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

31
mais detalhes seria útil aqui para iniciantes como eu
Adam Waite

5
O Express considera os caminhos relativos sendfileruins. A menos que você especificar o rootparâmetro de diretório, como visto aqui: github.com/visionmedia/express/issues/1465
Joe

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

1
sim o código final !!
SuperUberDuper

2
Atualização @MattHarrison ES6, para as importações pacotes, consté preferido sobrevar
Nino Filiu

39

Esta resposta reúne as informações das outras respostas / comentários.

Depende se você deseja incluir algo relativo ao diretório ativo do processo (cwd) ou ao diretório do arquivo. Ambos usam a path.resolvefunção (coloque var path = require('path')na parte superior do arquivo.

  • em relação ao cwd: path.resolve('../../some/path/to/file.txt');
  • em relação ao arquivo: path.resolve(__dirname+'../../some/path/to/file.txt');

Ao ler o link do comentário de @ Joe, parece que os caminhos relativos são um risco de segurança se você aceitar a entrada do usuário para o caminho (por exemplo, sendfile('../.ssh/id_rsa')pode ser a primeira tentativa de um hacker).


1
Como um novato, quero saber como o cenário hacker chegou aqui?
bharath muppa

2
Se você acidentalmente permitir que o usuário insira o caminho do arquivo que deseja baixar, ele poderá fazer o download de qualquer arquivo em seu sistema (dei o exemplo de uma chave privada ssh - que permitiria fingir ser seu PC ( homem do meio, etc)). Tendo a restrição .. não permite essa possibilidade, pois apenas os arquivos do site podem ser acessados.
derekdreery

30

A documentação do Express sugere fazê-lo de uma maneira diferente e, na minha opinião, faz mais sentido depois da solução atual.

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

A opção raiz parece definir ./como o diretório raiz do seu projeto. Portanto, não sei exatamente onde está o seu arquivo em relação à raiz do projeto, mas se a sua pasta temporária estiver lá, você poderá definir ./tempcomo a raiz do arquivo que está enviando.


1
Isso é verdade, mas usa sendFile (capital F, suportado pelo Express v4.8.0 em diante) em vez do arquivo de envio mais antigo que o OP estava usando. Apenas dizendo ... =]
RemyNL 10/02

Ahh ... boa captura. Não notei essa pequena diferença. Também me pergunto se a resposta selecionada funciona não porque usa, .sendfilemas porque depende de outra coisa completamente (caminho). Obrigado por apontar isso.
tenor528

Simples e eficiente. Obrigado! Isso funcionou para mim perfeitamente!
Emanuela Colta
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.