Skip to content

Repository for OWASP Uruguay Meetup: ZAP and Defect Dojo WorkshopRepositorio para el Meetup organizado por OWASP Uruguay: Workshop ZAP y Defect Dojo

Notifications You must be signed in to change notification settings

OWASP-Uruguay/AntiSamy-SonarQube-Workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 

Repository files navigation

OWASP AntiSamy y SonarQube Workshop

Repository for OWASP Uruguay Meetup: Workshop OWASP AntiSamy y SonarQube 101

Repositorio para el Meetup organizado por OWASP Uruguay: Workshop OWASP AntiSamy y SonarQube 101

Introducción

En este workshop aprenderemos acerca del proyecto de OWASP AntiSamy y sobre la herramienta de SAST SonarQube

Video aquí

OWASP AntiSamy

Presentación AntiSamy aquí

Inicio de ambiente local

Se utilizará un fork del proyecto simplecommerce/SimplCommerce como proyecto de ejemplo a modificar.

Los requisitos del paso a paso para el ambiente de demo pueden variar, aquí se describe uno de ellos:

  1. Descargar e instalar NodeJS.
  2. Descargar e instalar Visual Studio 2019 con el SDK y runtime de .NET 5.0. En caso de seleccionar componentes indviduales en la instalación, asegurarse de marcar ".NET Core cross-platform development", esto debería instalar lo necesario para usar .NET 5.0.
  3. Descargar e instalar SQL Server. La forma más sencilla y descartable es utilizar Docker, siguiendo la guía en contenedores Linux (puede ser también con contenedores Windows):
    1. Descargar la imagen oficial en su última versión:
      docker pull mcr.microsoft.com/mssql/server:2019-latest
    2. Iniciar un contenedor estableciendo una contraseña para el usuario SA:
      docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=<YourStrong@Passw0rd>" `
      -p 1433:1433 --name sql-server -h sql-server `
      -d mcr.microsoft.com/mssql/server:2019-latest
    3. Probar el servicio y conexión con el comando:
      docker exec -it sql-server /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "<YourStrong@Passw0rd>"
      Si se muestra la línea 1>, el login fue exitoso. Se puede salir con el comando exit.
  4. Clonar el repositorio del proyecto:
    git clone https://github.com/spassarop/SimplCommerce.git
  5. Abrir la solución y modificar el string de conexión en SimplCommerce\src\SimplCommerce.WebHost\appsettings.json:
    "ConnectionStrings": {
        "DefaultConnection": "Server=.;Database=SimplCommerce;MultipleActiveResultSets=true;User Id=sa;Password=<YourStrong@Passw0rd>;"  
    }
  6. Compilar la solución.
  7. Establecer SimplCommerce.WebHost como Startup Project si no lo está.
  8. Abrir la ventana Package Manager Console. Allí ejecutar el comando Update-Database. Esto crea la base de datos a base de migraciones existentes en la solución.
  9. En Visual Studio presionar "Control + F5".
  10. Entrar a la URL de la aplicación y crear datos para la industria de tipo "Fashion". El back-office del sitio es accesible vía /Admin con las el usuario [email protected] y contraseña 1qazZAQ!.

Ejecutando el ataque

  1. Con sesion iniciada como administrador, acceder a un nuevo producto mediante el cabezal de la web en Catalog > Products y luego con el botón "+ Create Product", o accediendo directamente en /Admin#!/product-create.
  2. Cargar datos arbitrarios para el producto. Particularmente en cualquiera de los campos que permiten ingresar "texto enriquecido" (HTML a fin de cuentas) presionar el botón </> (Code View) para ver el HTML resultante de la escritura.
  3. Allí insertar el siguiente HTML:
    <p>Una camiseta <b>con toda la onda</b>.</p><p><script>alert(document.cookie)</script>Unisex.</p>
  4. Guardar el producto, dirigirse al nuevo producto en la raíz del sitio web y acceder a la publicación.
  5. Ver la alerta al cargar la página, con las cookies accesibles por JavaScript.

Mitigando

Implementar el código sanitizador

Aquí entra en juego OWASP AntiSamy .NET. La forma más sencilla de incluirlo es instalando su correspondiente paquete NuGet. Esto puede hacerse con los siguientes pasos:

  1. Click derecho sobre el proyecto SimplCommerce\src\Modules\SimplCommerce.Module.Catalog.
  2. Click en "Manage NuGet packages...".
  3. Buscar "antisamy", seleccionar el paquete "OWASP.AntiSamy" y hacer click en instalar.

Una vez instalado, puede crearse una nueva clase en el mismo proyecto llamada HtmlSanitizer.cs con la siguiente estructura:

using OWASP.AntiSamy.Html;

namespace SimplCommerce.Module.Catalog
{
    internal static class HtmlSanitizer
    {
        public static string Santize(string badHtml)
        {
        }
    }
}

Dentro de la función Sanitize el código más simple se construye con los siguientes pasos:

  1. Retornar si badHtml es nulo o vacío:
if (string.IsNullOrEmpty(badHtml))
{
    return badHtml;
}
  1. Crear una instancia de AntiSamy:
var antisamy = new AntiSamy();
  1. Ejecutar el escaneo con la política por defecto:
CleanResults results = antisamy.Scan(badHtml, Policy.GetInstance());
  1. Retornar el HTML sanitizado:
return results.GetCleanHtml();

Aplicar la sanitización

Para mitigar se deben cubrir dos frentes. La salida de la información (cuando se muestra en la vista) y la entrada (cuando es editado el producto). Como el texto malicioso ya fue ingresado, mitigar las salidas implica sanitizar el HTML en la carga del modelo y retorno de la API para el método GET:

  • ProductController.cs > ProductOverview(long id) y ProductDetail(long id):
    ShortDescription = _contentLocalizationService.GetLocalizedProperty(product, nameof(product.ShortDescription), HtmlSanitizer.Santize(product.ShortDescription)),
  • ProductApiController.cs > Get(long id)
    ShortDescription = HtmlSanitizer.Santize(product.ShortDescription),

Con esto, para la propiedad ShortDescription (también debería hacerse para Description y Specification) se evita la ejecución de código JavaScript para el ejemplo de ataque utilizado. De hecho, el resultado pasa a ser:

<p>Una camiseta <b>con toda la onda</b>.</p><p>Unisex.</p>

Para mitigar la inyección en futuras creaciones/modificaciones de producto, aplicar en:

  • ProductApiController.cs > Post(ProductForm model):
    ShortDescription = HtmlSanitizer.Santize(model.Product.ShortDescription),
  • ProductApiController.cs > Put(long id, ProductForm model):
    product.ShortDescription = HtmlSanitizer.Santize(model.Product.ShortDescription);

Mejoras en el proceso de depuración

Puede irse un paso más allá basarse en los resultados del escaneo para retornar un error al detectar entradas maliciosas. Para esto, se agrega en la clase HtmlSanitizer una nueva función:

public static List<string> ValidateHtml(string badHtml)
{
    if (string.IsNullOrEmpty(badHtml))
    {
        return new List<string>();
    }

    var antisamy = new AntiSamy();
    CleanResults results = antisamy.Scan(badHtml, Policy.GetInstance());
    return results.GetErrorMessages();
}

Es similar a Sanitize pero retorna una lista con los errores detectados en lugar del HTML sanitizado. Luego puede aplicarse de la siguiente forma para retornar los errores al cliente y facilitar la comprensión del error:

  • ProductApiController.cs > Put(long id, ProductForm model) y Post(ProductForm model):
    var errors = HtmlSanitizer.ValidateHtml(model.Product.ShortDescription);
    if (errors.Count > 0)
    {
        return BadRequest(new { error = new string[] { "Errors in short description: " + string.Join(",\n", errors) } });
    }

SonarQube

Presentación SonarQube 101 aquí

Links de interes:

Otros links:

About

Repository for OWASP Uruguay Meetup: ZAP and Defect Dojo WorkshopRepositorio para el Meetup organizado por OWASP Uruguay: Workshop ZAP y Defect Dojo

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published