Guia Educacional Cybersecurity OWASP Top 10

WEB APPLICATION SECURITY · DOCUMENTAÇÃO TÉCNICA

Entendendo
Local File Inclusion

Um guia técnico sobre a anatomia do LFI, seus impactos e as estratégias de defesa que reduzem a superfície de ataque.

PÚBLICO-ALVOComputação, Segurança, Engenharia, Pentest e Desenvolvimento Web
FOCOTeoria, código vulnerável, exploração autorizada e remediação
Ambiente controlado

Este conteúdo é destinado a ensino e testes autorizados. Não aplique as técnicas em sistemas de terceiros ou fora do escopo formalmente definido.

01 · FUNDAMENTOS

Introdução Teórica e Contextualização

A vulnerabilidade de Local File Inclusion (LFI) é uma falha de segurança de alta severidade que ocorre quando uma aplicação web permite que dados não sanitizados ou não validados, fornecidos pelo usuário, sejam passados diretamente a funções internas do servidor responsáveis por carregar, incluir ou ler arquivos no sistema de arquivos local.

Enquadramento no OWASP Top 10

No padrão internacional de riscos de segurança da OWASP (Open Web Application Security Project), o LFI classifica-se primariamente sob duas categorias estratégicas:

  • A03
    A03:2021 — Injection

    Ocorre devido ao tratamento inadequado de entradas de dados não confiáveis que alteram a lógica de interpretação de comandos ou caminhos do servidor.

  • A05
    A05:2021 — Security Misconfiguration

    Muitas vezes intensificado por configurações inseguras no servidor web ou runtime da linguagem, como permissões excessivas do processo web ou diretivas ativas como allow_url_include.

Diferença fundamental: Path Traversal vs. LFI

Embora os termos sejam frequentemente usados como sinônimos na prática de testes de penetração, existe uma distinção técnica crucial entre ambos:

CaracterísticaPath Traversal / Directory TraversalLocal File Inclusion (LFI)
Objetivo primárioNavegar na estrutura de diretórios para ler ou extrair bytes de um arquivo.Solicitar que o motor do servidor carregue, interprete ou execute o arquivo.
Mecanismo internoFunções de leitura estática, como file_get_contents, readfile, fs.readFile e send_file.Funções do runtime que podem executar código, como include e require no PHP.
ResultadoVazamento de dados ou leitura de arquivo texto.Leitura de arquivo ou execução de código caso o arquivo contenha instruções interpretáveis.

LFI vs. RFI (Remote File Inclusion)

LOCAL

LFI

O arquivo acessado deve existir no sistema de arquivos local do servidor, mesmo que seja temporário, log ou upload.

REMOTO

RFI

O servidor é induzido a buscar conteúdo externo via HTTP/FTP. No PHP, depende de configurações inseguras, como allow_url_include.

02 · CÓDIGO

Anatomia do Código Vulnerável

A raiz de toda vulnerabilidade LFI é a confiança cega da aplicação nas entradas do usuário. Veja como o padrão vulnerável aparece em diferentes ecossistemas web.

A. PHP — a linguagem clássica

Devido ao modelo de renderização dinâmica do PHP, funções nativas de inclusão são muito utilizadas para criar sistemas de templates ou carregar componentes modulares.

PHP · EXEMPLO DIDÁTICO
<?php
$page = isset($_GET['page']) ? $_GET['page'] : 'pages/home.php';

// Vulnerável: entrada do usuário chega diretamente à inclusão.
include($page);
?>
Funções perigosas no PHP

Inclusão/execução: include(), require(), include_once() e require_once(). Leitura: file_get_contents(), readfile(), file(), fopen() e copy().

B. Python — Flask e Django

Embora Python não execute código arbitrário ao ler arquivos como o PHP faz, o uso incorreto de funções de manipulação de arquivo pode resultar em vazamento de código e credenciais via Path Traversal/LFI.

PYTHON · FLASK
from flask import Flask, request, send_file
import os

app = Flask(__name__)

@app.route('/download')
def download_file():
    filename = request.args.get('file')
    file_path = os.path.join('/var/www/static/', filename)
    return send_file(file_path)
Cenário didático

Em um laboratório autorizado, uma entrada como ?file=../../../../etc/passwd demonstra como a resolução do caminho pode sair da pasta prevista.

C. Node.js — Express

No ecossistema Node.js, erros ao servir arquivos estáticos ou manipular o sistema de arquivos (fs) geram vulnerabilidades graves de leitura arbitrária.

JAVASCRIPT · EXPRESS
const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();

app.get('/view', (req, res) => {
  const fileName = req.query.file;
  const filePath = path.join(__dirname, 'public', fileName);

  fs.readFile(filePath, 'utf8', (err, data) => {
    if (err) return res.status(404).send('Arquivo não encontrado');
    res.send(data);
  });
});

D. Java — Servlets e JSP

Aplicações Java corporativas baseadas em Servlets ou JSP podem ser afetadas ao utilizar o RequestDispatcher com entrada não confiável.

JAVA · SERVLET
String page = request.getParameter("page");

RequestDispatcher dispatcher = request.getRequestDispatcher(
    "/WEB-INF/views/" + page
);
dispatcher.forward(request, response);

Se o parâmetro page aceitar segmentos de subida de diretório, o acesso pode escapar do local originalmente esperado.

03 · IMPACTO

Mapeamento de Arquivos Sensíveis

Ao confirmar a presença de uma falha de LFI, testes autorizados buscam compreender o impacto sem coletar mais dados do que o necessário. O acesso depende das permissões do processo web.

Dados de alto risco

Chaves privadas, hashes, variáveis de ambiente e históricos podem conter credenciais reais. Em laboratório, use dados fictícios e registre apenas a evidência mínima.

Targets críticos em sistemas Linux

CaminhoDescrição e importância
/etc/passwdLista usuários, diretórios home e shells padrão; útil para demonstrar enumeração de contas.
/etc/shadowContém hashes de senhas e normalmente exige privilégios de root.
/proc/self/environVariáveis de ambiente do processo web; podem conter segredos e credenciais.
/proc/self/cmdlineComando utilizado para iniciar o processo web atual.
/proc/self/fd/NDescritores de arquivos abertos pelo processo, incluindo temporários.
~/.ssh/id_rsa / id_ed25519Chaves privadas SSH; exposição representa comprometimento crítico.
~/.bash_history / .zsh_historyHistórico de comandos executados no terminal.
/var/log/apache2/access.logLog de acessos do Apache e superfície associada a log poisoning.
/var/log/nginx/access.logLog de acessos do Nginx.
/var/log/auth.log / sshd.logLogs de autenticação SSH.
04 · CANONICALIZAÇÃO

Técnicas de Traversal e Bypasses de Filtros

Filtros frágeis procuram uma sequência específica, enquanto o sistema de arquivos trabalha com o caminho já decodificado e normalizado. A diferença entre essas duas representações cria oportunidades de bypass.

O problema da ordem de processamento

01Entrada HTTPTexto controlado pelo cliente
02DecodificaçãoURL encoding e framework
03NormalizaçãoSeparadores e segmentos
04AcessoArquivo finalmente resolvido

Uma validação feita antes da última transformação pode analisar um valor diferente daquele que chegará à função de arquivo. Por isso, bloquear apenas a cadeia ../ não estabelece uma fronteira de segurança.

Variações relevantes em laboratório

CategoriaExemplo didáticoPor que filtros simples falham
URL encoding%2e%2e%2fO filtro pode executar antes da decodificação feita pelo framework.
Codificação dupla%252e%252e%252fCamadas diferentes podem decodificar a entrada mais de uma vez.
Separador alternativo..\Em Windows, a barra invertida também separa diretórios.
Caminho absoluto/etc/passwd ou C:\Windows\win.iniNão depende de segmentos de subida para sair da pasta prevista.
Prefixos redundantes....//Uma única substituição textual pode produzir novamente ../.
Esquemasphp://filter/...Não é um caminho tradicional e pode ser interpretado pelo runtime.
Null byte é contexto histórico

O sufixo %00 contornava extensões forçadas em versões antigas do PHP e de bibliotecas C. Runtimes modernos normalmente rejeitam esse byte, mas sistemas legados ainda devem ser avaliados.

Como testar sem extrapolar o escopo

  • 01
    Defina uma linha de base

    Compare tamanho, código HTTP, título e tempo de resposta de uma página válida com uma página inexistente.

  • 02
    Use arquivos-cobaia

    Crie no laboratório um arquivo sem dados reais, como /opt/lab/marcador.txt, e limite o objetivo à leitura desse marcador.

  • 03
    Varie uma dimensão por vez

    Teste codificação, profundidade e separadores separadamente para saber qual transformação causou o resultado.

  • 04
    Registre e interrompa

    Ao demonstrar a falha, preserve a requisição mínima, pare a enumeração e avance para a remediação.

05 · PHP STREAMS

PHP Wrappers e Pseudo-Protocolos

Wrappers são interfaces nativas que permitem ao PHP tratar diferentes fontes de dados como fluxos. Quando uma entrada não confiável alcança include(), require() ou funções de leitura, esses esquemas podem ampliar o impacto da falha.

php://filter: leitura transformada

O wrapper php://filter aplica filtros a um recurso antes de entregá-lo à aplicação. Em laboratório, a transformação Base64 demonstra a leitura do código-fonte de um arquivo PHP sem que ele seja interpretado.

HTTP · LABORATÓRIO LOCAL
GET /index.php?page=php://filter/convert.base64-encode/resource=index.php HTTP/1.1
Host: 127.0.0.1
Connection: close
Interpretação do resultado

Uma resposta com texto Base64 que decodifica para o código da aplicação comprova exposição de fonte. Não é necessário procurar credenciais ou arquivos adicionais.

Principais wrappers e condições

WrapperUso legítimoRisco quando a entrada é controladaControle principal
php://filterTransformar dados em fluxo.Exposição de código-fonte e arquivos legíveis.Não permitir que o usuário componha o recurso.
php://inputLer o corpo bruto da requisição.Inclusão de conteúdo enviado no corpo em configurações vulneráveis.Allowlist de rotas e runtime atualizado.
data://Representar dados inline.Conteúdo interpretável quando opções perigosas estão habilitadas.Manter allow_url_include=Off.
zip:// / phar://Acessar recursos empacotados.Processamento inesperado de arquivos controlados.Separar uploads, validar formato e evitar inclusão dinâmica.
file://Acessar arquivos locais por URI.Leitura absoluta fora da pasta esperada.Mapear identificadores para caminhos internos fixos.

Configuração defensiva do PHP

INI · ENDURECIMENTO
allow_url_fopen = Off
allow_url_include = Off
display_errors = Off
log_errors = On
open_basedir = /var/www/app:/var/lib/php/sessions:/tmp
Configuração não substitui código seguro

open_basedir e diretivas de URL reduzem impacto, mas a defesa principal continua sendo impedir que dados do usuário sejam usados como nomes de arquivos ou recursos.

06 · CADEIA DE IMPACTO

Escalada de LFI para Execução de Código

LFI não implica automaticamente execução remota de código. A escalada ocorre apenas quando o atacante consegue fazer conteúdo interpretável existir em um arquivo local que a aplicação vulnerável posteriormente inclui.

Pré-condições da cadeia

01GravaçãoConteúdo controlado chega a um arquivo
02LocalizaçãoO caminho desse arquivo é conhecido
03LeituraO processo web possui permissão
04InclusãoO runtime interpreta o conteúdo

Fontes de conteúdo controlável

LOGS

Log poisoning

Cabeçalhos ou caminhos registrados pelo servidor podem chegar ao arquivo de log. A escalada exige que esse log seja legível e incluído pelo PHP.

SESSÕES

Arquivos de sessão

Dados persistidos em sessões podem ser controláveis. O formato, o nome e o diretório variam conforme a configuração.

UPLOADS

Arquivos enviados

Um upload aceito como imagem ou documento pode conter conteúdo inesperado. A exploração depende de conhecer o caminho e incluí-lo.

PROCESSO

Ambiente e temporários

Variáveis, descritores e arquivos temporários podem expor conteúdo, mas permissões e ciclo de vida limitam a cadeia.

Prova de conceito segura

Em uma VM descartável, use somente um marcador inofensivo para demonstrar interpretação. O objetivo é observar LAB_OK, não executar comandos do sistema.

PHP · MARCADOR INOFENSIVO
<?php
// Arquivo criado exclusivamente dentro do laboratório.
echo 'LAB_OK';
?>
Pare na confirmação

Se o marcador for interpretado, a cadeia está comprovada. Não use webshells, reverse shells, persistência ou comandos de pós-exploração em uma atividade didática.

Como quebrar a cadeia

  • A
    Remova a inclusão controlável

    Troque caminhos fornecidos pelo usuário por chaves de uma allowlist interna.

  • B
    Isole conteúdo gravável

    Logs, sessões e uploads não devem ficar dentro de diretórios interpretáveis pelo servidor web.

  • C
    Reduza permissões

    O usuário do serviço deve ler apenas os arquivos estritamente necessários à aplicação.

  • D
    Desative interpretação em uploads

    Sirva arquivos enviados por um domínio estático, armazenamento de objetos ou diretório sem execução.

07 · TESTES CONTROLADOS

Automação, Fuzzing e Reconhecimento

Automação ajuda a encontrar variações, mas também multiplica tráfego e impacto. Em aula, restrinja o alvo a 127.0.0.1 ou a uma VM isolada, use uma lista curta e pare assim que a hipótese for confirmada.

Fluxo de trabalho reproduzível

  1. 1
    Documente o escopo

    Registre host, porta, endpoint, janela de teste e arquivos-cobaia autorizados.

  2. 2
    Capture respostas-base

    Faça uma requisição válida e outra inválida para identificar tamanho, status e texto característicos.

  3. 3
    Construa uma wordlist mínima

    Inclua somente o marcador do laboratório, profundidades necessárias e representações que respondam à hipótese.

  4. 4
    Limite taxa e concorrência

    Evite indisponibilidade acidental e facilite a correlação com os logs do servidor.

  5. 5
    Valide manualmente

    Um resultado diferente é apenas um indício; reproduza a requisição isoladamente antes de concluir.

Linha de base com cURL

BASH · SOMENTE LAB LOCAL
# Página válida
curl -i 'http://127.0.0.1:8080/index.php?page=pages/home.php'

# Entrada inválida para comparação
curl -i 'http://127.0.0.1:8080/index.php?page=nao-existe.php'

Fuzzing com lista curta

TEXT · lfi-lab.txt
pages/home.php
../marcador.txt
../../marcador.txt
%2e%2e%2fmarcador.txt
php://filter/convert.base64-encode/resource=index.php
BASH · FFUF
ffuf \
  -u 'http://127.0.0.1:8080/index.php?page=FUZZ' \
  -w lfi-lab.txt \
  -rate 5 \
  -t 1 \
  -mc all
Não confie apenas em status HTTP

Aplicações vulneráveis frequentemente retornam 200 OK até em erros. Compare corpo, tamanho, hashes, mensagens e comportamento com as respostas-base.

Evidências mínimas para o relatório

CampoO que registrar
LocalizaçãoEndpoint, parâmetro e método HTTP afetados.
ReproduçãoUma requisição mínima e uma resposta com o marcador do laboratório.
ImpactoTipo de dado acessível e permissões observadas, sem coletar dados reais desnecessários.
Causa raizFluxo da entrada até a função de arquivo vulnerável.
CorreçãoPatch proposto, teste negativo e evidência de que a rota legítima continua funcionando.
08 · FATECSEG CORP

Estudo de Caso Prático

O portal fictício FatecSeg Corp usa um parâmetro para escolher o conteúdo da página. O exercício conduz da identificação à correção, sempre em uma VM isolada e com um arquivo-cobaia criado pelo professor.

Objetivo da prática

Demonstrar que o parâmetro page alcança uma operação de inclusão, ler apenas o marcador autorizado e substituir a implementação por um mapa fechado de rotas.

1. Reconhecer o fluxo normal

Abra as páginas pelo menu e observe valores como pages/home.php e pages/company.php. A aplicação revela que o nome do arquivo é transportado na URL.

HTTP · NAVEGAÇÃO LEGÍTIMA
GET /fatecseg/index.php?page=pages/company.php HTTP/1.1
Host: 127.0.0.1

2. Localizar a causa raiz

PHP · IMPLEMENTAÇÃO VULNERÁVEL
<?php
$page = isset($_GET['page']) ? $_GET['page'] : 'pages/home.php';
include($page);
?>

O valor externo chega a include() sem passar por uma decisão interna. A aplicação delega ao visitante a escolha do recurso que o runtime tentará abrir.

3. Confirmar com o marcador autorizado

O professor prepara /opt/fatecseg/contrato-interno.txt com conteúdo fictício. Os alunos ajustam apenas a profundidade do caminho até obter o marcador, registram a evidência e interrompem a exploração.

Limite do exercício

Não acesse /etc/shadow, chaves SSH, históricos, variáveis com segredos ou dados de outros usuários. O marcador já é evidência suficiente.

4. Aplicar a correção

PHP · MAPA FECHADO DE ROTAS
<?php
$routes = array(
    'home'     => __DIR__ . '/pages/home.php',
    'company'  => __DIR__ . '/pages/company.php',
    'services' => __DIR__ . '/pages/services.php',
    'news'     => __DIR__ . '/pages/news.php',
    'contact'  => __DIR__ . '/pages/contact.php'
);

$route = isset($_GET['page']) ? $_GET['page'] : 'home';

if (!isset($routes[$route])) {
    http_response_code(404);
    exit('Página não encontrada');
}

include $routes[$route];
?>

5. Executar testes de regressão

CasoEntradaResultado esperado
Rota válidapage=companyPágina da empresa com HTTP 200.
Rota inexistentepage=nao-existeHTTP 404 sem detalhes internos.
Traversalpage=../../marcador.txtHTTP 404; nenhum conteúdo do arquivo.
Wrapperpage=php://filter/...HTTP 404; esquema não é avaliado.
Separador Windowspage=..\marcador.txtHTTP 404; entrada ausente do mapa.
09 · REMEDIAÇÃO

Defesa em Profundidade e Código Seguro

A correção mais forte elimina a relação direta entre a entrada do usuário e o sistema de arquivos. Controles adicionais reduzem o impacto caso outra falha apareça, mas não substituem essa mudança de arquitetura.

Prioridade 1: identificadores, não caminhos

O cliente envia uma chave curta, como company. Somente o servidor conhece o caminho correspondente. Isso impede traversal, caminhos absolutos e wrappers por construção.

EVITE

Caminho vindo da URL

?page=pages/company.php expõe estrutura interna e permite que a entrada influencie a resolução.

PREFIRA

Identificador de negócio

?page=company é convertido por um mapa imutável mantido no código da aplicação.

Quando o caminho dinâmico for inevitável

Normalize o destino, resolva o caminho real e verifique a contenção dentro de uma pasta base. A existência e o tipo do arquivo também devem ser confirmados.

PHP · CONTENÇÃO COM REALPATH
<?php
$base = realpath(__DIR__ . '/documents');
$name = isset($_GET['file']) ? $_GET['file'] : '';
$candidate = realpath($base . DIRECTORY_SEPARATOR . $name);

$insideBase = $candidate !== false
    && strpos($candidate, $base . DIRECTORY_SEPARATOR) === 0
    && is_file($candidate);

if (!$insideBase) {
    http_response_code(404);
    exit('Arquivo não encontrado');
}

readfile($candidate);
?>
Atenção a links simbólicos e prefixos

Compare caminhos canônicos com o separador ao final da base. Uma comparação ingênua com strpos($candidate, $base) === 0 também aceitaria uma pasta vizinha chamada, por exemplo, documents-backup.

Camadas complementares

  • 01
    Menor privilégio

    Execute o serviço com usuário dedicado, sem shell interativo e sem acesso a chaves, backups ou diretórios administrativos.

  • 02
    Separação de uploads

    Armazene arquivos enviados fora do DocumentRoot, gere nomes internos e sirva-os como conteúdo estático sem interpretação.

  • 03
    Erros discretos

    Não exponha caminhos absolutos, stack traces ou avisos de inclusão ao cliente. Envie detalhes apenas para logs protegidos.

  • 04
    Runtime endurecido

    Mantenha dependências atualizadas, desative inclusão remota e restrinja o acesso do PHP quando compatível com a aplicação.

  • 05
    Monitoramento

    Detecte sequências de traversal, esquemas inesperados e picos de erros, correlacionando-os por origem e endpoint.

  • 06
    Testes contínuos

    Inclua casos negativos para traversal, encoding, caminhos absolutos, separadores alternativos e wrappers na suíte de segurança.

Checklist de revisão

Princípio central

A aplicação deve decidir quais recursos podem ser acessados. A entrada do usuário pode selecionar uma opção conhecida, mas nunca construir livremente o caminho que o servidor abrirá.

LAB · SIMULAÇÃO LOCAL

Simulador e Validador de Payloads LFI

Compare, no navegador, como quatro estratégias fictícias tratam uma entrada. Nenhum arquivo ou servidor real é acessado.

Estratégia do backend
Testar:
RESULTADOAGUARDANDO
Entrada recebida
—
Caminho processado
—

Escolha uma estratégia e execute a simulação.

Conclusão defensiva

Remover sequências específicas é insuficiente. Prefira identificadores mapeados em allowlist e, quando caminhos forem indispensáveis, normalize-os e confirme que permanecem dentro de uma pasta base confiável.