Skip to main content

Desarrollo en C y C++ sin vulnerabilidades en la fabricación de automóviles y vehículos definidos por software (SDV)

Escrito por

23 de octubre de 2024

0 minutos de lectura

La industria automovilística se encuentra en un punto de inflexión único en su historia con la llegada del vehículo definido por software (SDV). Durante el Congreso Mundial de la Sociedad de Ingenieros de Automoción (SAE) celebrado en Detroit del 16 al 18 de abril de 2024, se afirmó explícitamente que existe un mercado de más de $500 000 millones en el que se invertirá en I+D y en avances tecnológicos para la industria automovilística. El cambio al SDV potenciará nuevas fuentes de ingresos a través de suscripciones a funciones y servicios que eran imposibles con el modelo heredado de “compra única” inherente a la industria automovilística desde sus inicios. 

Los fabricantes de automóviles y sus proveedores se propusieron convertirse en empresas tecnológicas impulsadas por la arquitectura eléctrica/electrónica (E/E), con los semiconductores en el centro de estas innovaciones.  Además, los microservicios, la arquitectura en contenedores y la presencia significativa de la computación en nube son elementos fundamentales de los SDV. 

Este sector depende casi exclusivamente del desarrollo de software en C y C++ como lenguajes de programación confiables, eficientes y robustos. Sin embargo, estos lenguajes presentan riesgos de seguridad, como desbordamientos de búfer y problemas de seguridad de memoria que se remontan a décadas atrás. El mercado de SDV está directamente relacionado con la misión de Snyk de garantizar la seguridad del software. Los fabricantes de automóviles se benefician de las ofertas de infraestructura como código (IaC) y contenedores de Snyk, así como de la integración natural de Snyk con varios proveedores de nube.

Por ejemplo, Mercedes va por delante con su sistema operativo MB.

Integramos rápidamente el mejor hardware disponible con el Qualcomm Gen4 8295, que se puso a disposición de los consumidores solo seis meses antes. Se trataba de un proyecto ambicioso y estoy enormemente orgulloso del equipo por aceptar el desafío, crear 20 GB de código compilado y llevar este precursor de MB.OS a la Clase E, porque las lecciones aprendidas son cruciales para el lanzamiento de nuestro MB.OS 1.0 completo.

Cumplimiento de MISRA para C y C++

Las directrices MISRA C:2023 se centran principalmente en la seguridad y la confiabilidad de los sistemas críticos, incluidos los aspectos relacionados con la seguridad de las aplicaciones, especialmente cuando las vulnerabilidades pueden provocar riesgos para la seguridad. Aunque las directrices MISRA C:2023 abarcan una amplia gama de temas, ciertas reglas y directivas son particularmente relevantes para mejorar la seguridad de las aplicaciones mediante la promoción de prácticas que eviten comportamientos indefinidos, corrupción de memoria, accesos no autorizados y otras vulnerabilidades comunes.

De forma similar a las directrices C, la estructura y el contenido de la especificación MISRA C++:2023 esboza varias normas y directivas relacionadas con la seguridad de las aplicaciones, acompañadas de ejemplos de código conforme y no conforme.

Algunas de las directrices de cumplimiento de MISRA para el desarrollo en C y C++ citan directivas y reglas, como las siguientes, sobre la seguridad de las aplicaciones y la creación de software C y C++ seguro:

  • Directiva 4.12 de MISRA - No debe utilizarse la asignación dinámica de memoria: restringir la asignación dinámica de memoria puede prevenir una clase de vulnerabilidades relacionadas con errores de gestión de memoria.

  • Regla 1.3 de MISRA - No debe haber comportamientos indefinidos o críticos no especificados: un comportamiento indefinido puede dar lugar a vulnerabilidades de seguridad, por lo que esta regla es crucial para la seguridad.

  • Regla 18.1 de MISRA - Un puntero resultante de cálculos aritméticos sobre un operando puntero debe dirigirse a un elemento de la misma matriz que dicho operando puntero: esta regla pretende evitar el acceso fuera de los límites, una vulnerabilidad común en los programas C.

  • Regla 21.3 de MISRA - No se utilizarán las funciones de asignación y desasignación de memoria de <stdlib.h>: de forma similar a la Directiva 4.12, evitar la asignación dinámica de memoria reduce los riesgos relacionados con vulnerabilidades en la gestión de memoria.

  • Reglas 22.1 a 22.20 de MISRA (recursos): una gestión adecuada de los recursos, incluida la gestión de errores y la liberación de recursos, es fundamental para evitar fugas y agotamientos, que pueden aprovecharse en ataques de denegación de servicio o dar lugar a comportamientos indefinidos explotables por los atacantes.

Aunque la especificación MISRA C no etiqueta explícitamente las directrices como medidas de “seguridad”, el cumplimiento de sus exhaustivas reglas y directivas aumenta la postura de seguridad del software al eliminar muchas fuentes comunes de vulnerabilidades de seguridad en el código C y C++. Las directrices ayudan a desarrollar sistemas seguros y confiables fomentando un comportamiento sólido y bien definido.

Por qué Snyk está aquí para ayudar

Snyk se dedica a ayudar a los desarrolladores a proteger su código, incluidos los que trabajan con C y C++. Al integrar la seguridad en el ciclo de vida del desarrollo como métodos DevSecOps, Snyk permite a los desarrolladores detectar vulnerabilidades antes de que se conviertan en problemas críticos. Aún más, Snyk ayuda a los desarrolladores a detectar patrones de código inseguro cuando guardan su código en el IDE y no tienen que esperar a que pasen la integración continua (CI) y los pipelines de compilación, ni requieren un paso de compilación del código.

Con herramientas como Snyk Code, puedes escanear los códigos base C y C++ en busca de vulnerabilidades y obtener información práctica para corregirlas.

Por ejemplo, consideremos una vulnerabilidad común en C++: el desbordamiento del búfer. El siguiente es un simple fragmento de código que demuestra este problema:

#include <iostream>
#include <cstring>

void vulnerableFunction(char* input) {
    char buffer[10];
    // ❌ Potential buffer overflow
    strcpy(buffer, input);
}

int main() {
    char input[20] = "This is a long string";
    vulnerableFunction(input);
    return 0;
}

En este programa C++ de ejemplo, la función strcpy puede provocar un desbordamiento del búfer si la cadena de entrada supera el tamaño del búfer. Snyk puede ayudar a identificar tales vulnerabilidades y proporcionar recomendaciones de alternativas más seguras, como el uso de strncpy:

void secureFunction(char* input) {
    char buffer[10];
    strncpy(buffer, input, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0'; // Ensure null-termination
}

Pero con Snyk instalado en el IDE obtienes dos superpoderes:

  1. Snyk detectará código vulnerable como este desbordamiento de búfer, sin requerir un paso de compilación.

  2. Snyk te propondrá arreglarlo utilizando Snyk Agent Fix.

¿Quieres ver este truco mágico en acción? Míralo aquí:

Al adoptar prácticas de programación seguras y aprovechar herramientas como Snyk, los desarrolladores pueden reducir significativamente el riesgo de vulnerabilidades en sus códigos base C y C++. Regístrate en Snyk hoy mismo y empieza a proteger tus proyectos de software críticos.

Ejemplos de código C y C++ seguro y conforme frente a inseguro y vulnerable

Para mostrar cómo las directrices y especificaciones de MISRA se relacionan con el código y las vulnerabilidades del mundo real, exploraremos un programa en C, program2.c, que muestra un ejemplo de Comportamiento no deseado (Regla 1.3 de MISRA) de la lista anterior.

Este es el código del programa en C:

#include <stdio.h>

void undefinedBehavior() {
    int x = 5 / 0;
    printf("Value of x: %d\n", x);
}

int main() {
    undefinedBehavior();
    return 0;
}

La división por cero es un comportamiento indefinido en C que puede conducir a resultados impredecibles. Las directrices de MISRA, con razón, prohíben este tipo de operaciones para garantizar la seguridad del código y del software crítico.

Primero compila el programa y después ejecútalo:

$ gcc program2.c -o program2
$ ./program2

Observarás que el compilador GCC lanzará una advertencia sobre la división por cero:

program2.c:5:15: warning: division by zero is undefined [-Wdivision-by-zero]
    int x = 5 / 0;
              ^ ~
1 warning generated.

Sin embargo, este es un código de programa sencillo y pequeño. En el mundo real, estos problemas pueden ser difíciles de encontrar en un código base de gran tamaño y con muchas advertencias del compilador en la salida estándar.

Encuentra la vulnerabilidad con Snyk Code

El mensaje de error de comportamiento indefinido de una advertencia del compilador sobre la _división por cero_ y otros problemas pueden ser difíciles de detectar o pueden detectarse en una fase tardía del ciclo de desarrollo. Snyk Code puede ayudarte a identificarlos en una fase temprana del ciclo de desarrollo escaneando el código base en busca de vulnerabilidades antes de compilar el código.

La razón es que Snyk utiliza técnicas de aprendizaje automático en su motor de seguridad para análisis estático de código, con el fin de entender los flujos de llamadas del programa y conectar los recorridos del código desde el origen hasta el destino. De este modo, detecta código inseguro y posibles vulnerabilidades en el código base sin necesidad de compilar el código.

Vulnerable C program code showing undefined behavior

Herramientas para el cumplimiento de la seguridad en C y C++ y el código seguro

Algunas opciones de código abierto para comprobar el cumplimiento de MISRA en código C y C++ incluyen las siguientes herramientas:

  • OpenMRC: OpenMRC es un verificador de reglas MISRA-C de código abierto desarrollado como un complemento de Eclipse CDT (herramientas de desarrollo C/C++). Está diseñado para analizar el código de los vehículos definidos por software en función de las directrices MISRA-C:2004 y generar mensajes de infracción para ayudar a los desarrolladores a actualizar su código fuente con el fin de cumplir las normas de seguridad funcional.

  • Clang-misracpp2008: Este proyecto, aunque ya archivado, pretendía crear un verificador de código abierto para las reglas MISRA C++:2008 utilizando la infraestructura LLVM/Clang. Aunque archivado y ya no activo, los desarrolladores recomiendan el uso de clang-tidy-misra como alternativa. clang-misracpp2008 se implementó como un complemento LLVM/Clang, lo que demuestra un esfuerzo para cubrir las reglas MISRA C ++ a través de la lógica personalizada y las marcas proporcionadas por el compilador.

Aparte de las opciones anteriores, incluso si se mantienen de acuerdo con tus estándares y mantienen las barreras de calidad y el umbral exhaustivo de sus pruebas de seguridad, Snyk es otra opción a explorar.

La plataforma de seguridad de Snyk incluye Snyk Code, una SAST en tiempo real centrada en el desarrollador que optimiza la seguridad del código con una experiencia fácil de usar para el desarrollador. Los hallazgos de Snyk incluyen recursos de aprendizaje, ejemplos de correcciones para consejos de remediación y, a veces, incluso una corrección automática basada en Snyk Agent Fix.

Snyk es gratuito y puede emplearse en diferentes métodos para escanear código C y C++, como la instalación de la extensión Snyk IDE, la importación de repositorios Git desde Bitbucket o GitHub y el uso de la CLI de Snyk.

En el caso de los programas C y C++, otro vector de vulnerabilidades de seguridad en un código base puede ir más allá del código del desarrollador: el código importado a través de bibliotecas de código abierto.

Por último, recomiendo repasar las lecciones educativas sobre vulnerabilidades de Snyk Learn C, breves y concisas, para disfrutar de experiencias interactivas de aprendizaje sobre seguridad. Las lecciones abordan distintas vulnerabilidades en C y C++, como la desreferenciación de punteros nulos, la doble liberación de memoria, malas prácticas de codificación y demás.

Protege tu código con inteligencia de vanguardia

Descubre todas las funciones de Snyk Code SAST en solo 30 minutos.

Snyk Top 10: Vulnerabilites you should know

Find out which types of vulnerabilities are most likely to appear in your projects based on Snyk scan results and security research.