Este es un complemento para PHAN para tratar de detectar problemas de seguridad (como XSS). Realiza un seguimiento de cualquier momento que un usuario pueda modificar una variable, y verifica que tales variables se escapen antes de ser salidas como HTML o utilizadas como una consulta SQL, etc.
Admite proyectos PHP genéricos, y también tiene un modo dedicado para el código MediaWiki (analiza ganchos, htmlforms y métodos de base de datos).
Una demostración web está disponible.
$ composer require --dev mediawiki/phan-taint-check-plugin
El complemento se puede usar tanto en modo "manual" como "independiente". El primero es la mejor opción si su proyecto ya está ejecutando PHAN, y casi no se necesita configuración. Este último solo debe usarse si no desea agregar PHAN a su proyecto, y no es compatible con el código relacionado con MediaWiki. Para obtener más información sobre el uso de Wikimedia de este complemento, consulte https://www.mediawiki.org/wiki/phan-taint-check-plugin.
Simplemente tiene que agregar una verificación de mancha a la sección plugins de su configuración PHAN. Suponiendo que la verificación de Taint está en la ubicación estándar del proveedor, por ejemplo $seccheckPath = 'vendor/mediawiki/phan-taint-check-plugin/'; , el archivo a incluir es "$seccheckPath/GenericSecurityCheckPlugin.php" para un proyecto genérico, y "$seccheckPath/MediaWikiSecurityCheckPlugin.php" para un proyecto MediaWiki.
Además, asegúrese de que el modo rápido esté deshabilitado o el complemento no funcionará:
' quick_mode ' => false También debe agregar SecurityCheck-LikelyFalsePositive y SecurityCheck-PHPSerializeInjection a suppress_issue_types (este último tiene una alta tasa de falsos positivos).
Luego ejecute Phan como lo harías normalmente:
$ vendor/bin/phan -d . --long-progress-bar
Ejecutar Phan con --analyze-twice atrapará problemas de seguridad adicionales que podrían pasar desapercibidos en la fase de análisis normal. Una limitación conocida de esto es que el mismo problema podría informarse más de una vez con diferentes líneas causadas.
Puede ejecutar la verificación de Taint a través de:
$ ./vendor/bin/seccheck
Es posible que desee agregar un alias de script compositor para eso:
"scripts" : {
"seccheck" : " seccheck "
}Tenga en cuenta que los falsos positivos están deshabilitados de forma predeterminada.
El complemento generará varios tipos de problemas dependiendo de lo que detecte. Los tipos de problemas que emite son:
SecurityCheck-XSSSecurityCheck-SQLInjectionSecurityCheck-ShellInjectionSecurityCheck-PHPSerializeInjection - para cuando alguien hace unserialize( $_GET['d'] ); Este tipo de problema parece tener una alta tasa de falsos positivos actualmente.SecurityCheck-CUSTOM1 : para permitir que las personas tengan tipos de mancha personalizadosSecurityCheck-CUSTOM2 - ídemSecurityCheck-DoubleEscaped : detectando que HTML se está escapando dobleSecurityCheck-RCE - Ejecución de código remoto, por ejemplo, eval( $_GET['foo'] )SecurityCheck-PathTraversal - Path Traversal, por ejemplo, require $_GET['foo']SecurityCheck-ReDoS - Denegación de servicio de expresión regular (redos), por ejemplo, preg_match( $_GET['foo'], 'foo')SecurityCheck-LikelyFalsePositive : un problema potencial, pero probablemente no. Sobre todo sucede cuando el complemento se confunde. El campo de gravedad generalmente se marca como Issue::SEVERITY_NORMAL (5) . Los falsos positivos obtienen Issue::SEVERITY_LOW (0) . Los problemas que pueden resultar en el compromiso del servidor (en oposición al compromiso del usuario final), como la inyección de shell o sql, se marcan como Issue::SEVERITY_CRITICAL (10) . La inyección de serialización normalmente sería "crítica", pero actualmente se denota como una gravedad de lo normal porque el cheque parece tener una alta tasa de falsos positivos en este momento.
Puede usar la opción de línea de comandos -y de PHAN para filtrar por severidad.
Si necesita suprimir un falso positivo, puede poner @suppress NAME-OF-WARNING en el DocBlock para una función/método. Alternativamente, puede usar otros tipos de supresión, como @phan-suppress-next-line . Vea el readme de Phan para una lista completa. La sección @param-taint y @return-taint (ver "personalización") también son muy útiles para tratar con falsos positivos.
Tenga en cuenta que el complemento informará las posibles vulnerabilidades de XSS en el contexto CLI. Para evitarlos, puede suprimir el archivo SecurityCheck-XSS con @phan-file-suppress en scripts CLI, o para toda la aplicación (usando la opción suppress_issue_types Config) si la aplicación solo consiste en scripts CLI. Alternativamente, si toda la salida ocurre desde una función interna, puede usar @param-taint de la siguiente manera:
/**
* @param-taint $stuffToPrint none
*/
public function printMyStuff ( string $ stuffToPrint ) {
echo $ stuffToPrint ;
}Al depurar problemas de seguridad, puede usar:
'@phan-debug-var-taintedness $varname';
Esto emitirá un problema SecurityCheckDebugTaintedness que contiene la mancha de $varname en la línea donde se encuentra la anotación. Tenga en cuenta que debe insertar la anotación en una cadena literal; Los comentarios no funcionarán. Ver también Anotación de Phan @phan-debug-var .
@return-taint html .$options ) y el sexto ( $join_cond ) de IDatabase::select() de MediaWiki si se proporciona directamente como una matriz literal, o devuelve directamente como una matriz literal desde un método getQueryInfo() . El complemento admite ser personalizado, subclasificando la clase Security CheckPlugin. Para un ejemplo complejo de hacerlo, consulte MediaWikiseCurityCheckPlugin.
A veces tiene métodos en su base de código que alteran la mancha de una variable. Por ejemplo, una función de escape HTML personalizada debe borrar el bit HTML Taint. Del mismo modo, a veces Phan-Taint-Check puede confundirse y desea anular la mancha calculada para una función específica.
Puede hacer esto agregando una directiva de contaminación en un comentario de DocBlock. Por ejemplo:
/**
* My function description
*
* @param string $html the text to be escaped
* @param-taint $html escapes_html
*/
function escapeHtml ( $ html ) {
}Los métodos también heredan estas directivas a partir de definiciones abstractas en interfaces de antepasados, pero no de implementaciones concretas en clases de antepasados.
Las directivas Taint tienen prefijo con @param-taint $parametername o @return-taint . Si hay múltiples directivas, pueden separarse por una coma. @param-taint se usa para marcar cómo se transmite Taint desde el parámetro al valor de retorno de métodos, o cuando se usa con las directivas exec_ , para marcar lugares donde los parámetros se emiten/ejecutan. @return-taint se usa para ajustar la mancha del valor de retorno independientemente de los parámetros de entrada.
El tipo de directivas incluye:
exec_$TYPE : si un parámetro está marcado como exec_$TYPE entonces alimentar ese parámetro un valor con $TYPE taint dará como resultado una advertencia activada. Por lo general, usaría esto cuando una función que emite o ejecuta su parámetroescapes_$TYPE - Se utiliza para parámetros donde la función escapa y luego devuelve el parámetro. Por lo tanto, escapes_sql borraría el bit SQL Taint, pero dejaría otros bits de mancha solos.onlysafefor_$TYPE - Para usar en @return-taint , marca el tipo de retorno como seguro para un $TYPE específico pero inseguro para los otros tipos.$TYPE : si solo se especifica el tipo en un parámetro, se mueve y con la mancha de la variable de entrada. Normalmente no querría hacer esto, pero puede ser útil cuando $TYPE es none para especificar que el parámetro no se usa para generar el valor de retorno. En un @return esto podría usarse para enumerar qué banderas contaminantes tiene el valor de retorno, lo que generalmente solo es útil cuando se especifica como tainted para decir que tiene todas las banderas.array_ok : bandera de propósito especial para decir ignorar argumentos contaminados si están en una matriz.allow_override -Taint-Check si Phan-Taint-Check debe anular el indicador de propósito especial para especificar que la anotación de muñeca debe ser anulada por Phan-Taint-Check si puede detectar una mancha específica. El valor para $TYPE puede ser uno de htmlnoent , html , sql , shell , serialize , custom1 , custom2 , code , path , regex , sql_numkey , escaped , none , tainted . La mayoría de ellas son categorías de contaminación, excepto:
htmlnoent : como html pero deshabilite la detección de doble escape que se usa con html . Cuando se especifica escapes_html , la escapada se agrega automáticamente a @return , y exec_escaped se agrega a @param . Del mismo modo, onlysafefor_html es equivalente a solo a onlysafefor_htmlnoent,escaped .none - significa que no hay manchatainted - significa todas las categorías de contaminación excepto categorías especiales (equivalente a SecurityCheckPlugin::YES_TAINT )escaped : se usa para significar que el valor ya está escapado (para rastrear doble escape)sql_numkey - es un propósito bastante especial para MediaWiki. Ignora la mancha en matrices si son para claves asociativas. El valor predeterminado para @param-taint está tainted si es una cadena (u otro tipo peligroso), y none si es algo así como un entero. El valor predeterminado para @return-taint es allow_override (que es equivalente a none a menos que algo mejor pueda ser autodetectado).
En lugar de anotar métodos en su base de código, también puede personalizar Phan-Taint-Check para tener un conocimiento creado de manchas de métodos. Además, puede extender el complemento para tener un comportamiento bastante arbitrario.
Para hacer esto, anula el método getCustomFuncTaints() . Este método devuelve una matriz asociativa de nombres de métodos totalmente calificados a una matriz que describe cómo la mancha del valor de retorno de la función en términos de sus argumentos. Las claves numéricas corresponden al número de un argumento, y una clave 'general' agrega mancha que no está presente en ninguno de los argumentos. Básicamente, para cada argumento, el complemento toma la mancha del argumento, a bit a su entrada en la matriz, y luego a bitwise o es la clave general. Si alguna de las claves en la matriz tiene un indicador EXEC, entonces se plantea inmediatamente un problema si la mancha correspondiente se alimenta de la función (por ejemplo, una función de salida). Las banderas ejecutivas no funcionan en la clave 'general'.
Por ejemplo, HTMLSpecialChars que elimina HTML Taint, escapa de su argumento y devuelve el valor escapado se vería como:
' htmlspecialchars ' => [
( self :: YES_TAINT & ~ self :: HTML_TAINT ) | self :: ESCAPED_EXEC_TAINT ,
' overall ' => self :: ESCAPED ,
];Las siguientes variables de entorno afectan el complemento. Normalmente no tendrías que ajustarlos.
SECURITY_CHECK_EXT_PATH : ruta al directorio que contiene extension.json / skin.json cuando está en modo MediaWiki. Si no se establece, asume el directorio raíz del proyecto.SECCHECK_DEBUG - Archivo para obtener información de depuración adicional (si se ejecuta desde shell , /dev/stderr es conveniente) Licencia pública general de GNU, versión 2 o posterior