
Vulnerabilidade de Path Traversal em TahaBakhtari/SubtitleGenerator - CVE-2026-51592
Uma vulnerabilidade de path traversal existe no endpoint /update_subtitle do
TahaBakhtari/SubtitleGenerator.
O endpoint aceita um parâmetro file_name de um cliente não autenticado e o
combina com um diretório base fixo usando os.path.join() sem sanitizar
sequências de path traversal. Como resultado, um atacante remoto não autenticado pode
escrever arquivos arbitrários fora do diretório pretendido data/subtitles/,
dentro das permissões do processo em execução.
2e2553a (mais recente no momento do teste)app.py, função update_subtitle (linhas 225–238)@app.route('/update_subtitle', methods=['POST'])
def update_subtitle():
file_type = request.form.get('file_type', 'srt')
new_content = request.form.get('new_content')
file_name = request.form.get('file_name')
if not file_name:
return jsonify({'status': 'error', 'message': '...'}), 400
file_path = os.path.join("data/subtitles", file_name)
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
return jsonify({'status': 'success', 'message': '...'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
O parâmetro file_name é usado para construir um caminho de arquivo sem qualquer validação.
Um atacante pode fornecer um valor como ../../pwned.txt para escapar do
diretório data/subtitles/ e escrever em um local arbitrário ao qual o processo
tem acesso de gravação.
Por padrão, a aplicação vincula-se a 0.0.0.0:5000 (veja app.py), o que significa
que é acessível pela rede e não restrita ao localhost.
CWE-22: Limitação Incorreta de um Nome de Caminho para um Diretório Restrito ('Path Traversal')
Escrita arbitrária de arquivos dentro das permissões do processo Flask
Sobrescrita de arquivos de configuração ou da aplicação existentes
Possível sobrescrita de arquivos fonte da aplicação (ex.: app.py),
o que poderia levar à execução de código na próxima reinicialização
Negação de Serviço através da corrupção de arquivos críticos
Vetor de ataque: Remoto
Autenticação necessária: Não
Interação do usuário necessária: Não
Severidade (preliminar): Alta
curl -X POST "http://target:5000/update_subtitle" \
--data "file_name=../../pwned.txt&new_content=HACKED"
Resposta:
{"status": "success", "message": "..."}
Verificação no servidor:
$ ls
... pwned.txt ...
$ cat pwned.txt
HACKED
O arquivo pwned.txt é escrito no diretório raiz do projeto, dois níveis
acima do diretório pretendido data/subtitles/ — confirmando o path
traversal.
Consulte poc.sh para uma versão executável desta prova de conceito.
Valide que o caminho resolvido permanece dentro de data/subtitles/ usando
os.path.realpath() antes de abrir o arquivo:
base_dir = os.path.realpath("data/subtitles")
target = os.path.realpath(os.path.join("data/subtitles", file_name))
if not target.startswith(base_dir + os.sep):
return jsonify({'status': 'error', 'message': 'invalid filename'}), 400
file_path = target
Isso garante que o caminho resultante sempre resolva dentro de data/subtitles/,
bloqueando efetivamente sequências de path traversal como ../../.
O patch completo está disponível em patch.diff. Esta correção foi implementada e
verificada contra uma instância de teste local: o mesmo payload usado na PoC
acima agora retorna um erro "invalid filename" em vez de escrever o arquivo.
Descoberto e reportado por Arda Kuruoglu.
Esta vulnerabilidade foi divulgada seguindo um prazo de divulgação responsável de 90 dias, a partir da data do reporte inicial ao mantenedor.
README.md — este relatóriopoc.sh — script de prova de conceito demonstrando a vulnerabilidadepatch.diff — patch sugerido, validado contra uma instância de teste localEste relatório e arquivos acompanhantes são lançados sob a Licença MIT.