Este é um plug -in para Phan para tentar detectar problemas de segurança (como XSS). Ele mantém o controle da época em que um usuário pode modificar uma variável e verifica para ver que essas variáveis são escapadas antes de ser produzidas como HTML ou usadas como uma consulta SQL, etc.
Ele suporta projetos PHP genéricos e também possui um modo dedicado para o código MediaWiki (analisa ganchos, htmlforms e métodos de banco de dados).
Uma demonstração da web está disponível.
$ composer require --dev mediawiki/phan-taint-check-plugin
O plug -in pode ser usado no modo "manual" e "independente". O primeiro é a melhor opção se o seu projeto já estiver executando Phan, e quase nenhuma configuração é necessária. Este último só deve ser usado se você não quiser adicionar Phan ao seu projeto e não for suportado para o código relacionado ao Mediawiki. Para obter mais informações sobre o uso da Wikimedia deste plugin, consulte https://www.mediawiki.org/wiki/Phan-Taint-Heck-plugin.
Você simplesmente precisa adicionar verificação de manchas à seção plugins da sua configuração Phan. Supondo que a verificação de mancha esteja na localização padrão do fornecedor, por exemplo $seccheckPath = 'vendor/mediawiki/phan-taint-check-plugin/'; , o arquivo a incluir é "$seccheckPath/GenericSecurityCheckPlugin.php" para um projeto genérico e "$seccheckPath/MediaWikiSecurityCheckPlugin.php" para um projeto Mediawiki.
Além disso, verifique se o modo rápido está desativado ou o plug -in não funcionará:
' quick_mode ' => false Você também deve adicionar SecurityCheck-LikelyFalsePositive e SecurityCheck-PHPSerializeInjection para suppress_issue_types (o último tem uma alta taxa de falsos positivos).
Em seguida, execute Phan como normalmente faria:
$ vendor/bin/phan -d . --long-progress-bar
A execução de Phan com --analyze-twice capturará problemas de segurança adicionais que podem passar despercebidos na fase de análise normal. Uma limitação conhecida disso é que o mesmo problema pode ser relatado mais de uma vez com diferentes linhas causadas.
Você pode executar a verificação de mancha via:
$ ./vendor/bin/seccheck
Você pode querer adicionar um pseudônimo de script compositor para isso:
"scripts" : {
"seccheck" : " seccheck "
}Observe que os falsos positivos são desativados por padrão.
O plug -in produzirá vários tipos de problemas, dependendo do que ele detecta. Os tipos de problemas que produzem são:
SecurityCheck-XSSSecurityCheck-SQLInjectionSecurityCheck-ShellInjectionSecurityCheck-PHPSerializeInjection - pois quando alguém não é unserialize( $_GET['d'] ); Esse tipo de problema parece ter uma alta taxa de falso positivo atualmente.SecurityCheck-CUSTOM1 - para permitir que as pessoas tenham tipos de mancha personalizadosSecurityCheck-CUSTOM2 - IdemSecurityCheck-DoubleEscaped - Detectando que o HTML está sendo escapar duploSecurityCheck-RCE - Execução de código remoto, por exemplo, eval( $_GET['foo'] )SecurityCheck-PathTraversal - Traversal do caminho, por exemplo, require $_GET['foo']SecurityCheck-ReDoS - Negação de serviço regular de expressão (reduz), por exemplo, preg_match( $_GET['foo'], 'foo')SecurityCheck-LikelyFalsePositive - uma questão potencial, mas provavelmente não. Acontece principalmente quando o plug -in fica confuso. O campo de gravidade geralmente é marcado como Issue::SEVERITY_NORMAL (5) . FALSE POSITIVOS Issue::SEVERITY_LOW (0) . Problemas que podem resultar em compromisso do servidor (em oposição a apenas compromisso do usuário final), como a injeção de shell ou SQL, são marcados como Issue::SEVERITY_CRITICAL (10) . A injeção de serialização normalmente seria "crítica", mas atualmente é denotada como uma gravidade do normal, porque a verificação parece ter uma alta taxa de falsos positivos no momento.
Você pode usar a opção de linha de comando -y de Phan para filtrar por gravidade.
Se você precisar suprimir um falso positivo, poderá colocar @suppress NAME-OF-WARNING no docblock para uma função/método. Como alternativa, você pode usar outros tipos de supressão, como @phan-suppress-next-line . Veja o Readme de Phan para obter uma lista completa. A seção @param-taint e @return-taint (consulte "Customizing") também são muito úteis para lidar com falsos positivos.
Observe que o plug -in reportará possíveis vulnerabilidades XSS no contexto da CLI. Para evitá-los, você pode suprimir SecurityCheck-XSS em todo o arquivo com @phan-file-suppress em scripts da CLI ou para todo o aplicativo (usando a opção de configuração suppress_issue_types ) se o aplicativo consistir apenas em scripts da CLI. Como alternativa, se toda a saída acontecer de uma função interna, você poderá usar @param-taint da seguinte maneira:
/**
* @param-taint $stuffToPrint none
*/
public function printMyStuff ( string $ stuffToPrint ) {
echo $ stuffToPrint ;
}Ao depurar problemas de segurança, você pode usar:
'@phan-debug-var-taintedness $varname';
Isso emitirá uma questão de SecurityCheckDebugTaintedness que contém a mancheta de $varname na linha em que a anotação é encontrada. Observe que você deve inserir a anotação em uma string literal; Comentários não funcionarão. Veja também a anotação @phan-debug-var .
@return-taint html .$options ) e o sexto ( $join_cond ) do IDatabase::select() do Mediawiki se for fornecido diretamente como um literal da matriz ou devolvido diretamente como uma matriz literal de um método getQueryInfo() . O plug -in suporta ser personalizado, subclassificando a classe SecurityCheckPlugin. Para um exemplo complexo de fazer isso, consulte MediawikisecurityCheckPlugin.
Às vezes, você tem métodos na sua base de código que alteram a mancha de uma variável. Por exemplo, uma função de fuga HTML personalizada deve limpar o bit em mancha HTML. Da mesma forma, às vezes a verificação de Phan-Taint pode ficar confusa e você deseja substituir a mancha calculada para uma função específica.
Você pode fazer isso adicionando uma diretiva em mancha em um comentário de documentos. Por exemplo:
/**
* My function description
*
* @param string $html the text to be escaped
* @param-taint $html escapes_html
*/
function escapeHtml ( $ html ) {
}Os métodos também herdam essas diretrizes de definições abstratas nas interfaces ancestrais, mas não de implementações concretas nas classes ancestrais.
As diretrizes Taint são prefixadas com @param-taint $parametername ou @return-taint . Se houver várias diretrizes, eles podem ser separados por uma vírgula. @param-taint é usado para marcar como a Taint é transmitida do parâmetro para o valor de retorno dos métodos ou quando usado com as diretivas exec_ , para marcar locais onde os parâmetros são emitidos/executados. @return-taint é usado para ajustar a mancha do valor de retorno, independentemente dos parâmetros de entrada.
O tipo de diretrizes incluem:
exec_$TYPE - Se um parâmetro estiver marcado como exec_$TYPE , alimentando esse parâmetro Um valor com $TYPE Taint resultará em um aviso acionado. Normalmente você usaria isso quando uma função que produza ou execute seu parâmetroescapes_$TYPE - usado para parâmetros em que a função escapa e depois retorna o parâmetro. Portanto, escapes_sql limparia a parte da mancha do SQL, mas deixaria outros pedaços de mancha em paz.onlysafefor_$TYPE - Para uso em @return-taint , marca o tipo de retorno como seguro para um $TYPE específico, mas inseguro para os outros tipos.$TYPE - Se apenas o tipo for especificado em um parâmetro, ele será bitwised e com a mancha da variável de entrada. Normalmente, você não gostaria de fazer isso, mas pode ser útil quando $TYPE none é para especificar que o parâmetro não é usado para gerar o valor de retorno. Em um @return isso pode ser usado para enumerar quais sinalizações em mancha o valor de retorno tem, o que geralmente é útil apenas quando especificado como tainted para dizer que ele tem todos os sinalizadores.array_ok - Sinalizador de propósito especial para dizer ignorar argumentos contaminados, se eles estiverem em uma matriz.allow_override -Sinalizador de propósito especial para especificar que essa anotação em mancha deve ser substituída por Phan-Taint-check se puder detectar uma mancha específica. O valor para $TYPE pode ser um dos htmlnoent , html , sql , shell , serialize , custom1 , custom2 , code , path , regex , sql_numkey , escaped , none , tainted . A maioria dessas são categorias de mancha, exceto:
htmlnoent - como html , mas desative a detecção de escapamento duplo que é usado com html . Quando escapes_html é especificado, o escape é adicionado automaticamente ao @return e exec_escaped é adicionado ao @param . Da mesma forma, onlysafefor_html é equivalente a onlysafefor_htmlnoent,escaped .none - significa que não há manchatainted - significa todas as categorias de mancha, exceto categorias especiais (equivalente a SecurityCheckPlugin::YES_TAINT )escaped - é usado para significar que o valor já está escapado (para rastrear a fuga dupla)sql_numkey - é um propósito bastante especial para mediawiki. Ignora mancha nas matrizes, se forem para chaves associativas. O valor padrão para @param-taint é tainted se for uma string (ou outro tipo perigoso), e none se for algo como um número inteiro. O valor padrão para @return-taint é allow_override (que é equivalente a none a menos que algo melhor possa ser auto-modificado).
Em vez de anotar os métodos na sua base de código, você também pode personalizar a verificação de Phan-Taint para ter o conhecimento construído de manchas de métodos. Além disso, você pode estender o plug -in para ter um comportamento bastante arbitrário.
Para fazer isso, você substitui o método getCustomFuncTaints() . Este método retorna uma matriz associativa de nomes de métodos totalmente qualificados para uma matriz descrevendo como a mancha do valor de retorno da função em termos de seus argumentos. As teclas numéricas correspondem ao número de um argumento, e uma chave 'geral' adiciona mancha que não está presente em nenhum dos argumentos. Basicamente, para cada argumento, o plug -in toma a mancha do argumento, bit e é para sua entrada na matriz e depois bitwise ou é a chave geral. Se alguma das chaves da matriz tiver um sinalizador EXEC, um problema será levantado imediatamente se a mancha correspondente for alimentada com a função (por exemplo, uma função de saída). Os sinalizadores EXEC não funcionam na tecla 'Geral'.
Por exemplo, htmlspecialchars, que remove a mancha html, escapa de seu argumento e retorna a aparência escapada:
' htmlspecialchars ' => [
( self :: YES_TAINT & ~ self :: HTML_TAINT ) | self :: ESCAPED_EXEC_TAINT ,
' overall ' => self :: ESCAPED ,
];As seguintes variáveis de ambiente afetam o plug -in. Normalmente você não precisaria ajustá -los.
SECURITY_CHECK_EXT_PATH - caminho para o diretório contendo extension.json / skin.json quando no modo mediawiki. Se não estiver definido, assume o diretório raiz do projeto.SECCHECK_DEBUG - Arquivo para produzir informações de depuração extra (se for executado do shell , /dev/stderr for conveniente) GNU Licença pública em geral, versão 2 ou posterior