
Un análisis de código estático para WordPress (y PHP)

Un análisis estático de código para Plugins/Temas de WordPress (y PHP)
Simplemente clona el repositorio, instala los requisitos y ejecuta el script
$ git clone https://github.com/webarx-security/wpbullet wpbullet$ cd wpbullet$ pip install -r requirements.txt$ python wpbullet.pyOpciones disponibles:
--path (required) System path or download URL
Examples:
--path="/path/to/plugin"
--path="https://wordpress.org/plugins/example-plugin"
--path="https://downloads.wordpress.org/plugin/example-plugin.1.5.zip"
--enabled (optional) Check only for given modules, ex. --enabled="SQLInjection,CrossSiteScripting"
--disabled (optional) Don't check for given modules, ex. --disabled="SQLInjection,CrossSiteScripting"
--cleanup (optional) Automatically remove content of .temp folder after scanning remotely downloaded plugin (boolean)
--report (optional) Saves result inside reports/ directory in JSON format (boolean)
$ python wpbullet.py --path="/var/www/wp-content/plugins/plugin-name"
Crear un módulo es flexible y permite sobrescribir los métodos de BaseClass para cada módulo, así como crear sus propios métodos.
Cada módulo en el directorio Modules implementa propiedades y métodos de core.modules.BaseClass, por lo tanto, el parámetro requerido de cada módulo es BaseClass.
Una vez creado, el módulo debe importarse en modules/__init__.py. El nombre del módulo y de la clase deben ser consistentes para que el módulo se cargue.
Si estás abriendo un pull request para añadir un nuevo módulo, por favor proporciona también pruebas unitarias para tu módulo.
Modules/ExampleVulnerability.py
from core.modules import BaseClass
class ExampleVulnerability(object):
# Vulnerability name
name = "Cross-site Scripting"
# Vulnerability severity
severity = "Low-Medium"
# Functions causing vulnerability
functions = [
"print"
"echo"
]
# Functions/regex that prevent exploitation
blacklist = [
"htmlspecialchars",
"esc_attr"
]
El patrón de expresión regular se genera en core.modules.BaseClass.build_pattern y, por lo tanto, puede sobrescribirse en cada clase de módulo.
Modules/ExampleVulnerability.py
import copy
...
# Build dynamic regex pattern to locate vulnerabilities in given content
def build_pattern(self, content, file):
user_input = copy.deepcopy(self.user_input)
variables = self.get_input_variables(self, content)
if variables:
user_input.extend(variables)
if self.blacklist:
blacklist_pattern = r"(?!(\s?)+(.*(" + '|'.join(self.blacklist) + ")))"
else:
blacklist_pattern = ""
self.functions = [self.functions_prefix + x for x in self.functions]
pattern = r"((" + '|'.join(self.functions) + ")\s{0,}\(?\s{0,1}" + blacklist_pattern + ".*(" + '|'.join(user_input) + ").*)"
return pattern
Ejecutando pruebas unitarias: $ python3 -m unittest