Laboratorio: Integración de Proyectos de Código Abierto con OSS-Fuzz

Objetivo:

En este laboratorio, aprenderás a integrar un proyecto de código abierto con OSS-Fuzz para mejorar su seguridad y estabilidad mediante técnicas modernas de fuzzing y ejecución distribuida. Al final del laboratorio, habrás configurado un proyecto de JavaScript para Node.js y lo habrás integrado con OSS-Fuzz utilizando Jazzer.js, siguiendo un ejemplo práctico.

Requisitos Previos

  • Conocimientos básicos de programación en JavaScript.
  • Familiaridad con Docker y manejo de imágenes Docker.
  • Acceso a una cuenta de GitHub para subir configuraciones y código.
  • Un proyecto de código abierto en JavaScript o TypeScript (puede ser un proyecto de ejemplo).

Temas del Laboratorio

  • Introducción a OSS-Fuzz
  • Configuración del Entorno
  • Integración de un Proyecto en OSS-Fuzz
    • Archivos de Configuración
    • Dockerfile
    • Fuzzers
  • Ejecución de Fuzzing y Análisis de Resultados

1. Introducción a OSS-Fuzz

OSS-Fuzz es un servicio gratuito ofrecido por Google para mejorar la seguridad y estabilidad de los proyectos de código abierto mediante técnicas de fuzzing. Desde su lanzamiento en 2016, ha ayudado a descubrir y corregir más de 10,000 vulnerabilidades y 36,000 bugs en más de 1,000 proyectos.

El fuzzing es una técnica que alimenta a un programa con entradas aleatorias para encontrar errores como desbordamientos de buffer y otros problemas de seguridad.

Arquitectura de OSS-Fuzz

Arquitectura de OSS-Fuzz

El proceso de integración en OSS-Fuzz sigue estos pasos:

  1. Un mantenedor crea objetivos de fuzzing y los integra con el sistema de compilación del proyecto.
  2. El proyecto es aceptado en OSS-Fuzz y las configuraciones de compilación se suben.
  3. OSS-Fuzz construye el proyecto y sube los objetivos de fuzzing a un bucket de GCS.
  4. ClusterFuzz descarga los objetivos y comienza el fuzzing.
  5. Si se encuentra un bug, ClusterFuzz lo reporta en el issue tracker de OSS-Fuzz.
  6. Los desarrolladores corrigen el bug y lo acreditan a OSS-Fuzz.
  7. ClusterFuzz verifica la corrección y cierra el issue.

2. Configuración del Entorno

2.1. Clonar el Proyecto de Ejemplo

Clona el proyecto de ejemplo de JavaScript proporcionado por OSS-Fuzz para utilizarlo como referencia.

git clone https://github.com/google/oss-fuzz.git
cd oss-fuzz/projects/javascript-example

2.2. Instalación de Dependencias

Asegúrate de tener Docker instalado en tu máquina:

sudo dnf install docker

Luego, instala Node.js si aún no lo tienes:

sudo dnf install nodejs

3. Integración de un Proyecto en OSS-Fuzz

3.1. Archivos de Configuración

Dentro del proyecto, crea un archivo project.yaml con el siguiente contenido:

language: javascript

fuzzing_engines:
  - libfuzzer

sanitizers:
  - none

3.2. Dockerfile

Crea un archivo Dockerfile que utilice la imagen base de OSS-Fuzz para JavaScript:

FROM gcr.io/oss-fuzz-base/base-builder-javascript

COPY . $SRC/
WORKDIR $SRC

RUN npm install

3.3. Fuzzers

Crea un fuzzer simple en fuzz_string_compare.js:

module.exports.fuzz = function (data) {
    const s = data.toString();
    if (s.length !== 16) {
        return;
    }
    if (s.slice(0, 8) === "Awesome " && s.slice(8, 15) === "Fuzzing" && s[15] === "!") {
        throw Error("Welcome to Awesome Fuzzing!");
    }
};

3.4. build.sh

Crea un archivo build.sh que utilice el script de compilación de OSS-Fuzz:

#!/bin/bash -eu

compile_javascript_fuzzer $SRC example/fuzz_string_compare.js --sync

4. Ejecución de Fuzzing y Análisis de Resultados

4.1. Compilar y Ejecutar el Fuzzer

Compila y ejecuta el fuzzer usando Docker:

docker build -t oss-fuzz-javascript .
docker run --rm -it oss-fuzz-javascript

4.2. Análisis de Resultados

Si ClusterFuzz encuentra algún problema, recibirás una notificación en el issue tracker de OSS-Fuzz, donde podrás ver los detalles del bug encontrado y tomar acción para corregirlo.

Conclusión

Al completar este laboratorio, habrás configurado con éxito un proyecto de JavaScript para Node.js utilizando OSS-Fuzz. Esto contribuirá a la seguridad y estabilidad del proyecto, siguiendo las mejores prácticas en fuzzing.