10 puntos por GN⁺ 2024-11-05 | 1 comentarios | Compartir por WhatsApp
  • Tener en cuenta la seguridad al escribir código Go es una tarea compleja
  • Se presentan varias prácticas concretas que, si se aplican de forma continua, ayudan a escribir código robusto, seguro y de alto rendimiento

Mantener actualizada la versión de Go

  • Debes mantener actualizada la versión de Go que usa tu proyecto
  • Aunque no uses las funciones más recientes del lenguaje, al actualizar la versión de Go puedes recibir todos los parches de seguridad para las vulnerabilidades descubiertas
  • Las nuevas versiones de Go también garantizan compatibilidad con las dependencias más recientes
  • En el sitio del historial de lanzamientos de Go puedes revisar qué problemas de seguridad y CVE se resolvieron en cada release de Go y actualizar a la versión más reciente en el archivo go.mod de tu proyecto
  • Después de actualizar la versión de Go, debes comprobar que no aparezcan problemas de compatibilidad ni de dependencias
  • Puedes usar analizadores estáticos de código para evaluar la calidad y la seguridad del código

vet

  • Puedes analizar código Go con el comando go vet, incluido en Go
  • Si ejecutas go vet sin argumentos, se ejecuta con todas las opciones permitidas por defecto
  • Escanea el código fuente y reporta problemas potenciales
  • Entre los problemas más comunes están errores con goroutines, variables sin usar y secciones de código inalcanzables

staticcheck

  • Staticcheck, un linter de terceros, encuentra bugs, detecta problemas de rendimiento y también aplica el estilo del lenguaje Go
  • Explica los problemas encontrados y sugiere correcciones con ejemplos
  • Además de ejecutarlo en el pipeline de CI, puedes instalarlo como binario independiente para escanear código en local
  • Verifica la versión instalada y confirma que esté listo para ejecutar el escaneo
  • Si se ejecuta sin argumentos, invoca por defecto todos los analizadores de código
  • Revisa como ejemplo qué puede encontrar en el repositorio de GitHub de NGINX Agent
  • Los resultados del escaneo pueden clasificarse en tres tipos: paquetes/métodos/funciones deprecated, variables/campos sin usar y problemas relacionados con la calidad del código

golangci-lint

  • golangci-lint se puede instalar con el comando go install
  • Revisa la versión para confirmar que la instalación salió bien
  • Si lo llamas sin argumentos, se ejecutan todos los linters
  • Revisa qué advertencias y sugerencias muestra en el repositorio agent que clonaste antes
  • El linter señala el archivo y la línea exactos
  • Evalúa el código y haz cambios; luego vuelve a ejecutar el linter y corre todas las pruebas unitarias
  • Si las pruebas pasan, haz commit del código actualizado y haz push al remoto

Detección de condiciones de carrera

  • Las condiciones de carrera pueden ocurrir cuando varias goroutines intentan acceder a un recurso al mismo tiempo
  • Se detectan cuando al menos una de las goroutines intenta modificar el recurso
  • Go ofrece soporte nativo para probar estos casos usando la herramienta test junto con el argumento -race
  • El detector de carreras solo evalúa el código que se ejecuta e ignora las rutas de código no ejecutadas, por lo que primero conviene correr un analizador estático para comprobar que no haya código muerto
  • Ejecutar las pruebas en paralelo aumenta la probabilidad de detectar problemas de concurrencia

Escaneo del código fuente en busca de vulnerabilidades

govulncheck

  • Es una herramienta que escanea la base de código en busca de vulnerabilidades conocidas listadas en la base de datos de CVEs
  • La desarrolla el equipo de Go, y una base de datos dedicada a vulnerabilidades de Go proporciona la información al escáner
  • Después de instalar la versión más reciente, prueba la funcionalidad básica
  • Clona el repositorio habit y ejecuta la herramienta desde el directorio raíz
  • No se detectan vulnerabilidades
  • Si escaneas el binario, podrían encontrarse otras vulnerabilidades
  • Actualiza Go a la versión más reciente, trae las dependencias y verifica que ni el software ni las dependencias tengan CVE

gosec

  • Es un analizador estático de código que ayuda a encontrar configuraciones inseguras en el código
  • Puede ejecutarse en el sistema local o en el pipeline de CI mediante GitHub Action
  • Tiene una amplia variedad de opciones y reglas para configurar el escaneo
  • Clona un repositorio de GitHub que contenga código Go y comienza el escaneo desde el directorio raíz
  • En el reporte de escaneo puedes ver una lista de problemas potenciales ordenados por severidad y nivel de confianza
  • Revisa los CWE reportados y aprende más sobre las debilidades listadas

Fuzzing

  • Es la última forma de comprobar la calidad del código y descubrir vulnerabilidades
  • Son pruebas automatizadas especializadas que manipulan datos de entrada generados aleatoriamente usando la cobertura de pruebas del código
  • Es muy útil para encontrar fallas de seguridad potenciales como buffer overflows, inyección SQL, ataques DoS y ataques XSS
  • Como se generan automáticamente muchas combinaciones de entrada, el desarrollador no necesita pensar manualmente en cientos o miles de combinaciones de datos de entrada

1 comentarios

 
GN⁺ 2024-11-05
Comentarios en Hacker News
  • govulncheck es una herramienta que verifica si el código vulnerable realmente es alcanzable, por lo que resulta más útil que solo revisar las dependencias del programa
  • Conviene no olvidar revisar también el proyecto capslock de Google
  • Incluye consejos útiles sobre go vet y go test -race
  • Go no es seguro a nivel de memoria, pero es más fácil escribir código seguro en él que en otros lenguajes
    • Gracias a la sintaxis clara de Go, es fácil entender el comportamiento de las funciones y las estructuras de datos
    • La razón por la que las herramientas de IA funcionan bien con Go es que el contexto dentro de las funciones es claro
  • Semgrep es una excelente herramienta que realiza verificaciones sobre lenguajes y frameworks comunes mediante análisis estático
    • Se pueden consultar las reglas abiertas de Semgrep en GitHub
  • Se plantean dudas sobre la reputación de Go en materia de seguridad
    • En general, Go se considera seguro y estable, en un nivel similar al de otras herramientas como .NET
  • Recién me enteré de gosec
  • Tras mantener aplicaciones en Go durante 9 años, fue posible actualizar con facilidad las versiones de Go y los módulos
    • GitHub notifica automáticamente las vulnerabilidades y, en el 99% de los casos, todo funciona sin cambios
  • Go en realidad no es seguro a nivel de memoria
    • La atomicidad solo está garantizada para valores del tamaño de una palabra; los valores de doble palabra, como punteros de interfaz o slices, pueden afectar la seguridad de memoria en escenarios de concurrencia
  • Go es bueno, pero últimamente el uso creciente de genéricos está reduciendo la legibilidad del código
    • Se ha vuelto más difícil de leer que el código Go anterior, que casi no usaba genéricos