In this article
Ops, criei um recurso e introduzi uma vulnerabilidade de redirecionamento aberto em um app Deno
Vamos seguir um passo a passo para configurar um aplicativo web simples de “Hello World” com Deno, um runtime cada vez mais popular para JavaScript e TypeScript. Mais especificamente.
Vamos criar um aplicativo web com Deno que aceita um parâmetro de consulta para redirecionamento e entender como desenvolvedores podem, sem querer, abrir brechas de segurança ao seguir planos de desenvolvimento e criar recursos.
Primeiros passos: tutorial de código “Hello World” com Deno
Como pré-requisito, verifique se você tem acesso a um ambiente de desenvolvimento web com Deno e às ferramentas necessárias para executar projetos Deno e interagir com o aplicativo web.
Siga estas etapas para criar seu aplicativo “Hello World” com Deno:
1. Instale o Deno no seu ambiente de desenvolvimento. Se ainda não tiver feito isso, consulte as instruções de instalação no [site oficial do Deno](https://deno.land/#installation).
2. Crie um novo projeto Deno. Para isso, crie um diretório e inicialize-o com um arquivo deps.ts. Esse arquivo armazenará as dependências, embora não tenhamos nenhuma, pois este é um aplicativo simples.
```bash
mkdir deno-hello-world
cd deno-hello-world
echo "" > deps.ts
```
3. Crie um novo arquivo server.ts. Ele conterá a lógica do servidor. Nesse arquivo, vamos importar a função serve do módulo std/http, configurar um servidor e aguardar as solicitações recebidas.
4. Adicione a lógica do servidor. No arquivo server.ts, adicione o código a seguir:
```typescript
import { serve } from "https://deno.land/std/http/server.ts";
const httpHandler = async (request: Request): Promise<Response> => {
let bodyContent = 'Hello World';
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
};
serve(httpHandler, { hostname: "0.0.0.0", port: 8080 });
console.log("HTTP server is running on http://localhost:8080/");
```5. Execute o servidor. Salve o arquivo server.ts e inicie o servidor executando o comando a seguir no terminal:
```bash
deno run --allow-net server.ts
```
Pronto! Agora você tem um aplicativo web simples com Deno que exibe “Hello World!”
Redirecionamento de solicitações em um aplicativo Deno
Vamos atualizar o código funcional acima para aceitar um parâmetro de consulta e redirecionar da rota principal / para a rota /user, que exibe os dados do usuário.
Primeiro, adicione a segunda rota /user. Para evitar a introdução de dependências ou frameworks web mais complexos, vamos usar uma verificação condicional simples do caminho solicitado.
Atualize o código de httpHandler da seguinte forma:
```typescript
const httpHandler = async (request: Request): Promise<Response> => {
let bodyContent = 'Hello World';
const requestURL = new URL(request.url);
if (requestURL.pathname === "/user") {
bodyContent = `
<h1> User: admin </h1>
<ul>
<li> Name: Roberto </li>
<li> Email: roberto@example.com </li>
</ul>
`
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
} else {
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
}
};
```
Agora, podemos implementar um recurso de redirecionamento para que, ao receber solicitações para /?redirect=/user, nosso aplicativo web analise o parâmetro de consulta redirect e redirecione a solicitação para a página com os dados do usuário.
No início da função httpHandler, vamos ampliar a variável requestURL para incluir também uma verificação condicional do parâmetro de consulta de redirecionamento e agir de acordo, respondendo com uma resposta HTTP que inclui um cabeçalho de redirecionamento Location:
```js
const requestURL = new URL(request.url);
const redirectTo = requestURL.searchParams.get('redirect');
if (redirectTo) {
return new Response(null, {
status: 302,
headers: {
'location': redirectTo
}
})
}
```Para testar se o recurso de redirecionamento funciona como esperado, redirecione da página de índice principal para a página com os dados do usuário solicitando a página: /?redirect=/user. Veja como funciona usando curl:
```bash
@lirantal ➜ /workspaces/deno-open-redirect-vulnerability-blog-post (main) $ curl "http://localhost:8080/?redirect=/user" -vv
v
* Trying ::1:8080...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /?redirect=/user HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< location: /user
< vary: Accept-Encoding
< content-length: 0
< date: Mon, 06 Nov 2023 14:19:36 GMT
<
* Connection #0 to host localhost left intact
```Pronto para colocar em produção?
Vale a pena analisar isso com mais atenção…
Vulnerabilidade de segurança de redirecionamento aberto em um aplicativo Deno
Uma vulnerabilidade de redirecionamento aberto, também conhecida como redirecionamento e encaminhamento não validados, é uma falha de segurança grave e comum em aplicativos web. Ela pode levar a sérios problemas de cibersegurança, como ataques de phishing, roubo de credenciais e distribuição de conteúdo malicioso.
Recomendo muito que você acesse a lição do Snyk Learn sobre redirecionamento aberto para saber mais e conhecer as boas práticas de programação segura em JavaScript e outras linguagens, como Java, Python etc.
O que é uma vulnerabilidade de redirecionamento aberto?
Uma vulnerabilidade de redirecionamento aberto ocorre quando um aplicativo recebe um parâmetro e redireciona o usuário para o valor desse parâmetro sem validá-lo. Essa vulnerabilidade pode permitir que um invasor redirecione as vítimas do site original para um site malicioso de sua escolha. Veja um exemplo simples de como seria um redirecionamento aberto em um aplicativo Node.js:
```javascript
app.get('/dashboard, function(req, res){
var redirect = req.query.redirect;
res.redirect(redirect);
});
```
Em um projeto Deno, o código é parecido:
```javascript
const httpHandler = async (request: Request): Promise<Response> => {
const requestURL = new URL(request.url);
const redirectTo = requestURL.searchParams.get('redirect');
if (redirectTo) {
return new Response(null, {
status: 302,
headers: {
'location': redirectTo
}
})
}
});
serve(httpHandler);
```No código acima, o aplicativo redireciona o usuário para a URL indicada no parâmetro de consulta redirect. Um invasor pode explorar esse comportamento fornecendo uma URL maliciosa como destino e redirecionando o usuário para um local não esperado.
Se você precisar de um exemplo completo e funcional do código do aplicativo Deno que criamos, acesse: https://github.com/snyk-snippets/deno-open-redirect-vulnerability-blog-post
Como explorar uma vulnerabilidade de redirecionamento aberto
Em nosso aplicativo web simples com Deno, uma pessoa mal-intencionada pode explorar o recurso de redirecionamento criando um link como este:
```
https://example.com/?dummyParameter1=value1&dummyParameter2=value2&redirect=https://attacker.com/
```Usar um parâmetro de consulta fictício, como dummyParameter1, não afeta o código do aplicativo Deno, mas cria uma URL mais longa. Assim, fica mais difícil para os usuários perceberem o parâmetro de redirecionamento e seu valor, que são sinais de alerta.
Além disso, pessoas mal-intencionadas podem esconder suas intenções usando serviços de encurtamento de URL. É bem provável que usuários desavisados não expandam a URL para descobrir para onde serão redirecionados.
Como o Snyk pode detectar uma vulnerabilidade de redirecionamento aberto no seu app web com Deno
Snyk é uma poderosa ferramenta de segurança voltada para desenvolvedores, que ajuda a identificar e corrigir vulnerabilidades na sua base de código e em dependências de código aberto. Ela é especialmente útil para detectar falhas de segurança, como vulnerabilidades de redirecionamento aberto.
Atualmente, o Snyk oferece suporte a projetos TypeScript e Node.js, mas não especificamente a Deno. Ainda assim, se você estiver criando aplicativos com JavaScript, vale a pena analisar tanto o arquivo package.json em busca de dependências de código aberto vulneráveis quanto seu próprio código JavaScript, que pode introduzir falhas de segurança, como esta vulnerabilidade de redirecionamento aberto.
Para detectar uma vulnerabilidade de redirecionamento aberto em um aplicativo JavaScript com o Snyk, você precisa integrar o Snyk ao seu pipeline de desenvolvimento e implantação. Para isso, instale o Snyk CLI e execute o teste do Snyk no seu aplicativo JavaScript, TypeScript ou Node.js. Veja um exemplo:
1. Instale o Snyk CLI globalmente:
```bash
npm install -g snyk
```2. Execute o teste do Snyk no diretório do seu aplicativo:
```bash
snyk code test
```O Snyk analisará o código do seu aplicativo e informará as vulnerabilidades encontradas, incluindo as de redirecionamento aberto. A ferramenta também fornece informações detalhadas sobre como corrigir as vulnerabilidades, sendo essencial para manter a segurança do seu aplicativo.

Na verdade, o Snyk pode encontrar vulnerabilidades de código inseguro diretamente no IDE, enquanto você programa. No código a seguir, de um aplicativo web Node.js criado com a biblioteca Express, um middleware controlador redireciona o usuário depois que a conta de administrador faz login. Podemos ver que o Snyk encontra várias vulnerabilidades de segurança, incluindo um problema de redirecionamento aberto.
No painel à direita, você pode ver os insights do Snyk sobre a vulnerabilidade de redirecionamento aberto:
Explicando como entradas não sanitizadas fluem entre diferentes arquivos e caminhos do código e indicando a linha específica vulnerável.
Fornecendo um link para saber mais sobre essa vulnerabilidade de redirecionamento aberto (acesse a lição do Snyk aqui!)
Apresentando vários exemplos de código que mostram como essa vulnerabilidade de redirecionamento aberto foi corrigida em outros projetos de código aberto, além do diff do código.

Lembre-se: prevenir é sempre melhor do que remediar, especialmente em cibersegurança. Ao entender a vulnerabilidade de redirecionamento aberto e usar ferramentas como o Snyk, você pode garantir que seus aplicativos web continuem seguros e confiáveis.
Configurando o Dev Container do Deno
Nesta seção, veremos como configurar o contêiner de desenvolvimento do Deno no GitHub Codespaces. Isso envolve modificar configurações específicas, como postCreateCommand e forwardedPorts, no arquivo devcontainer.json. Ao longo desta seção, vamos apresentar exemplos práticos e sugestões para ajudar você a configurar um aplicativo web funcional com Deno no seu ambiente de desenvolvimento.
Como usar a configuração postCreateCommand de um Dev Container
O postCreateCommand no arquivo devcontainer.json é um comando ou uma série de comandos executados depois que o contêiner de desenvolvimento é criado e iniciado. Essa configuração é importante porque permite automatizar tarefas que você normalmente executaria manualmente sempre que inicia o contêiner.
Por exemplo, você pode usar o postCreateCommand para instalar dependências do projeto, compilá-lo ou iniciar o servidor do aplicativo.
Em um projeto Deno, você pode usar o postCreateCommand para iniciar automaticamente o aplicativo web dentro do contêiner de desenvolvimento. Veja um exemplo de como poderia ser sua configuração de postCreateCommand:
```json
{
"postCreateCommand": "deno run --allow-net server.ts"
}
```Configuração de portas encaminhadas no Deno
Como não se trata apenas de um programa Deno de linha de comando, mas de um aplicativo web, precisamos expor as portas que recebem as solicitações no Dev Container e que devem estar acessíveis no ambiente host. É aí que entra a configuração de portas encaminhadas de um Dev Container.
A configuração forwardedPorts no arquivo devcontainer.json especifica quais portas do contêiner devem ser expostas à máquina host.
Por exemplo, o aplicativo web com Deno que apresentamos neste artigo escuta na porta 8080. Nesse caso, precisamos encaminhar essa porta para a máquina host usando a configuração forwardedPorts.
Para configurar o encaminhamento de portas no seu app web com Deno, adicione a configuração forwardedPorts ao arquivo devcontainer.json. Veja um exemplo:
```json
{
"forwardedPorts": [8080]
}
```Agora, seu aplicativo web com Deno está em execução na porta 8080 do contêiner, e você pode acessá-lo em http://localhost:8080 na máquina host. Lembre-se: se estiver executando o aplicativo em um ambiente de nuvem remoto, como o GitHub Codespaces, você precisará acessá-lo pela própria URL do Codespace, por exemplo, https://orange-invention-pe8918638bd1nf81-8080.app.github.dev/
E agora?
Aprendemos sobre Deno, Dev Containers e, o mais importante, sobre como evitar introduzir uma vulnerabilidade de segurança ao criar um recurso. Ufa, foi bastante coisa!
Você encontra o código completo e funcional deste artigo no repositório de código Snyk Snippets no GitHub: https://github.com/snyk-snippets/deno-open-redirect-vulnerability-blog-post
Comece a usar o Snyk gratuitamente
Não é necessário informar um cartão de crédito.
Crie uma conta com Bitbucket e veja mais opções
Ao usar o Snyk, você concorda em cumprir nossas políticas, incluindo os Termos de Serviço e a Política de Privacidade.