Hooks

Hook interpreter: sinalize pontos de execução dinâmica de código

Varra um código em busca de pontos de execução dinâmica de código em várias linguagens, ou avalie um único trecho, direto da linha de comando.

O hook interpreter sinaliza pontos de execução dinâmica de código (sinks): construções que transformam dados em código em execução ou os entregam a um shell, de eval à desserialização nativa. Ele reconhece a linguagem e lê cada arquivo pelas regras dela, e é o engine determinístico por trás da especialização interpreter, que você mesmo pode executar no modo scan ou check.

Como executar​

npx lagune read interpreter # scans the whole project
npx lagune read interpreter --dir src # scans a directory
npx lagune read interpreter --file app.py # scans a single file

Esses sinks têm uso duplo: uma varredura estática não consegue decidir se uma entrada influenciada por um atacante chega até eles, então cada ocorrência é um alerta para revisar, nunca um achado confirmado. A varredura imprime uma única seção, Dynamic-execution sinks to review, agrupada por arquivo. Uma execução sem achados imprime no dynamic-execution sinks found.

Leia o código sinalizado, nunca o execute!

Analise cada sink de forma estática, rastreando se uma entrada não confiável chega até ele. Nunca execute nem passe por eval o código sinalizado, nem qualquer código remoto ou baixado em tempo de execução que ele traga, para "testar" o que ele faz.

Como ler o veredito​

VereditoSignificado
carefulO trecho contém um ponto de execução dinâmica para a linguagem dele. Revise-o lendo, nunca executando.
safeNenhum ponto de execução dinâmica foi encontrado para a linguagem informada.

Opções da CLI​

OpçãoValorDescrição
--patternum trecho de códigoVerifica um trecho. Repita para verificar vários, com um veredito por linha.
--languma linguagemObrigatória com --pattern: javascript, python, php, ruby, java, kotlin, go, rust, c, cpp ou csharp.
--dirum diretórioLimita a varredura a um diretório. Pode ser repetida e combinada com --file.
--fileum arquivoLimita a varredura a um único arquivo. Pode ser repetida e combinada com --dir.

Sem nenhuma opção, ele varre o projeto inteiro. --pattern exige --lang e não pode ser combinado com --dir nem com --file.

Linguagens suportadas​

A varredura lê estas linguagens, identificadas pela extensão do arquivo, e confere cada uma com o próprio conjunto de pontos de execução dinâmica.

#LinguagemExtensõesSinks que ela sinaliza
1JavaScript / TypeScript.js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts, .astro, .vue, .svelte, .marko, .rioteval(), construtor Function, setTimeout/setInterval com corpo em string, módulo vm, exec de child_process, require() dinâmico, import() dinâmico
2Python.py, .pyieval/exec, __import__(), os.system/os.popen, subprocess com shell=True, pickle.load/loads, yaml.load (inseguro)
3Ruby.rbfamília eval (instance_eval/class_eval/module_eval/eval), system/exec, crases ou %x, Kernel#open / IO.popen/read/binread / Open3, Process.spawn, Marshal.load
4Go.goexec.Command/exec.CommandContext, plugin.Open
5PHP.phpeval(), assert() com string, create_function(), execução de shell (system/exec/shell_exec/passthru/popen/proc_open), call_user_func/call_user_func_array, include/require com caminho definido em tempo de execução
6Rust.rsCommand::new, process::Command
7Java.javaRuntime.exec, ProcessBuilder, ScriptEngine, ObjectInputStream.readObject
8Kotlin.kt, .ktsOs sinks da JVM: Runtime.exec, ProcessBuilder, ScriptEngine, ObjectInputStream.readObject
9C#.csProcess.Start / new Process, BinaryFormatter, Assembly.Load
10C.c, .hsystem(), popen(), a família exec* (execl, execve, execvp, …)
11C++.cc, .cpp, .cxx, .hpp, .hh, .hxxsystem(), popen(), a família exec* (execl, execve, execvp, …)
Melhor esforço, não exaustivo

Ele lê o código-fonte como texto, então um sink montado em tempo de execução, escondido atrás de um alias ou escrito de uma forma que ele não reconhece pode passar despercebido. Trate a tabela como um ponto de partida sólido, não como um inventário completo.

dica

O hook garante o mínimo (que esses sinks existem e onde estão): saber se um valor não confiável realmente chega a um deles é o julgamento que a especialização interpreter cobre.

Perguntas frequentes

Não. Ele sinaliza pontos de execução dinâmica como um alerta para revisar, nunca como um achado confirmado, porque uma varredura estática não consegue decidir se uma entrada influenciada por um atacante chega até eles.

Ele lê as linguagens da tabela de linguagens suportadas, identificadas pela extensão do arquivo, e confere cada uma com o próprio conjunto de sinks. Outras linguagens não geram sinks.