Está en la página 1de 102

AUNQUE LA GARANTÍA DEL SOFTWARE es más que simplemente escribir código

seguro, escribir código seguro es un componente importante y crítico para


garantizar la resistencia de los controles de seguridad del software. Informes en
divulgación completa y las listas de correo de seguridad son evidencia de que el
software escrito hoy está plagado de vulnerabilidades que pueden explotarse. La
mayoría de estas debilidades pueden atribuirse a un diseño y / o implementación de
software inseguro y es es de vital importancia que el software escrito sea ante todo
confiable, y en segundo lugar, menos propenso a los ataques y resistente cuando lo
es. Hackers exitosos hoy se identifican como personas que tienen un conocimiento
profundo de programación. Por tanto, es imperativo que los desarrolladores de
software que escriben código también deben tener un conocimiento profundo de
cómo su el código puede ser explotado, para que puedan proteger eficazmente su
software y datos. El panorama actual de la seguridad requiere que los
desarrolladores de software además, tengan una mentalidad de seguridad. Este
capítulo cubrirá los conceptos básicos de conceptos de programación; profundizar
en temas que tratan sobre software común codificación de vulnerabilidades y
técnicas y procesos de codificación defensiva; cubrir el análisis de código y las
técnicas de protección de código y finalmente discutir Construir consideraciones de
seguridad ambiental que deben tenerse en cuenta en el software que está escrito.

¿A quién culpar por el software inseguro?

Aunque pueda parecer que la responsabilidad del software inseguro recae


principalmente sobre los desarrolladores de software que escriben el código, las
opiniones varían y el debate sobre quién es el responsable final de una infracción de
software. Sosteniendo el el codificador único responsable sería irrazonable ya que el
software no está desarrollado en un silo. El software tiene muchas partes
interesadas como se muestra en la Figura 4.1 y eventualmente todos juegan un
papel crucial en el desarrollo de software seguro. En última instancia, es la
organización (o empresa) que será culpada de los problemas de seguridad del
software y tal estado no puede ser ignorado.
Conceptos fundamentales de programación

¿Quién es programador? ¿Cuál es su habilidad más importante? Un programador


es esencialmente alguien que utiliza sus conocimientos técnicos y habilidades para
resolver problemas que el negocio tiene. Las habilidades más importantes de un
programador (utilizadas como sinónimo con un codificador) tiene es la resolución de
problemas. Usan sus habilidades para construir negocios programas de resolución
de problemas (software) para automatizar procesos manuales, mejorando la
eficiencia del negocio. Los programadores usan lenguajes de programación para
escribir programas. En la siguiente sección aprenderemos sobre arquitectura
informática, tipos de códigos y lenguajes de programación, y utilidades de programa
como ensamblador, compiladores e intérpretes. También aprenderemos brevemente
sobre la entrada validación y canonicalización, que son dos aspectos importantes de
la programación.

Arquitectura de Computadores

La mayoría de las computadoras modernas se componen principalmente del


procesador de la computadora, memoria del sistema y dispositivos de entrada /
salida (E / S). La figura 4.2 muestra un simplificado Ilustración de la arquitectura
informática moderna.
El procesador de la computadora se conoce más comúnmente como procesamiento
central unidad (CPU). La CPU se compone de

■ Unidad Aritmética Lógica (ALU), que es un circuito especializado que se utiliza


para realizar operaciones matemáticas y lógicas en los datos.
■ Unidad de control que actúa como mediador que controla el procesamiento de
instrucciones. La propia unidad de control no ejecuta ninguna instrucción pero
instruye y dirige otras partes del sistema como el que se registra para hacerlo.
■ Registros que son espacios de almacenamiento de memoria interna
especializados dentro del propio procesador. Estas son áreas de almacenamiento
temporal para instrucción o datos y proporcionan la ventaja de la velocidad.

Debido a que los registros de la CPU tienen solo un espacio de memoria limitado, la
memoria es aumentada por la memoria del sistema y dispositivos de
almacenamiento secundarios como el disco duro discos, discos de video digital
(DVD), discos compactos (CD) y llaves / llaveros USB. La memoria del sistema
también se conoce comúnmente como memoria de acceso aleatorio (RAM). La
RAM es el componente principal con el que se comunica la CPU. Entrada/ Los
dispositivos de salida son utilizados por el sistema informático para interactuar con
dispositivos externos. interfaces. Algunos ejemplos comunes de dispositivos de
entrada incluye teclado, mouse, etc. y algunos ejemplos comunes de dispositivos de
salida incluyen el monitor, impresoras, etc. La comunicación entre cada uno de
estos componentes se realiza a través de una puerta de enlace canal que se llama
Bus.

La CPU, en su nivel más básico de operación, procesa datos basados ​en binarios
códigos definidos internamente por el fabricante del chip del procesador. Estás
códigos de instrucción se componen de varios códigos operativos denominados
Opcodes. Los códigos de operación le dicen a la CPU qué funciones puede realizar.
Para que un programa de software ejecute, lee códigos de instrucción y datos que
se almacenan en el sistema informático memoria y realiza la operación deseada en
los datos. Lo primero que debe suceder es que la instrucción y los datos se carguen
en el sistema memoria desde un dispositivo de entrada o un dispositivo de
almacenamiento secundario. Una vez que esto sucede, la CPU realiza las
siguientes cuatro funciones para cada instrucción:

■ Obtención: la unidad de control recibe las instrucciones del sistema memoria. La


ubicación de cada instrucción y datos en el sistema. La memoria se identifica
mediante una dirección única y la unidad de control utiliza la dirección de memoria
para obtener la instrucción del programa. La instrucción del puntero es utilizada por
el procesador para realizar un seguimiento de qué instrucción se han procesado los
códigos y cuáles se van a procesar después. El puntero de datos realiza un
seguimiento de dónde se encuentra el área de datos almacenado en la memoria de
la computadora, es decir, apunta a la dirección de memoria.
■ Decodificación: la unidad de control descifra la instrucción y dirige los datos
necesarios para ser movidos de la memoria del sistema a la ALU.
■ Ejecución: el control se mueve de la unidad de control a la ALU y la ALU realiza la
operación matemática o lógica sobre los datos.
■ Almacenamiento: la ALU almacena el resultado de la operación en la memoria o
en un registro. La unidad de control finalmente dirige la memoria para liberar el
resultado a un dispositivo de salida o un dispositivo de almacenamiento secundario.

El ciclo de buscar-decodificar-ejecutar-almacenar también se conoce como ciclo de


máquina. Una comprensión básica de este proceso es necesaria para un CSSLP
porque necesitan estar al tanto de lo que sucede con el código escrito por un
programador en el nivel de la máquina.

Cuando se ejecuta el programa de software, el programa asigna espacio de


almacenamiento en memoria para que el código del programa y los datos se puedan
cargar y procesar como programador pretendía que fuera. Los registros de la CPU
se utilizan para almacenar la mayoría datos inmediatos; los compiladores utilizan los
registros para almacenar en caché las funciones de uso frecuente valores y
variables locales que se definen en el código fuente del programa. Sin embargo,
dado que solo hay un número limitado de registros, la mayoría de los programas,
especialmente los grandes, coloque sus valores de datos en la memoria del sistema
(RAM) y utilice estos valores haciendo referencia a sus direcciones únicas. Memoria
interna el diseño tiene los siguientes segmentos: texto del programa, datos, pila y
montón como se muestra en la Figura 4.3. Físicamente, la pila y el montón se
asignan áreas en la RAM. La asignación de espacio de almacenamiento en la
memoria (también conocida como objeto de memoria) es llamado instanciación. El
código del programa utiliza las variables definidas en el código fuente para acceder
a los objetos de la memoria.
La serie de instrucciones de ejecución (código de programa) está contenida en el
segmento de texto del programa. El siguiente segmento es el segmento de datos de
lectura-escritura que es el área en la memoria que contiene tanto el global
inicializado como el no inicializado datos. Variables de función, datos locales y
algunos valores de registro especiales como el El puntero de la pila de ejecución
(ESP) se coloca en la parte de la pila de la RAM. ESP apunta a la ubicación de la
dirección de memoria del programa que se está ejecutando actualmente. Objetos de
tamaño variable y objetos que son demasiado grandes para ser colocados en la pila
se asigna dinámicamente en la parte del montón de la RAM. El montón proporciona
la capacidad de ejecutar más de un proceso a la vez, pero en su mayor parte con
software, los ataques de memoria en la pila son los más frecuentes.

La pila es un área de memoria que se utiliza para almacenar argumentos de función


y variables locales y se asigna cuando se llama a una función en el código fuente
ejecutar. Cuando comienza la ejecución de la función, se asigna espacio (empujado)
en la pila y cuando la función termina, el espacio asignado se elimina (salió) de la
pila. Esto se conoce como operación PUSH y POP. La pila se gestiona con una
estructura de datos LIFO (último en entrar, primero en salir). Esto significa que
cuando se llama una función, la memoria se asigna primero en las direcciones
superiores y se utiliza

primero. La dirección PUSH es de direcciones de memoria más altas a direcciones


de memoria más bajas y la dirección POP es de direcciones de memoria inferiores a
direcciones superiores direcciones de memoria. Es importante comprender esto
porque la pila de ejecución El puntero se mueve de una memoria superior a
direcciones de memoria inferiores y sin una gestión adecuada, pueden ser evidentes
graves brechas de seguridad.
Los piratas informáticos suelen tener un conocimiento profundo de este ciclo de
máquina y cómo se realiza la gestión de la memoria, y sin la protección adecuada
mecanismos establecidos, pueden eludir los controles de seguridad de nivel
superior al manipular punteros de instrucciones y datos en el nivel más bajo, como
es el caso de ataques de desbordamiento del búfer de memoria e ingeniería inversa.
Estos estarán cubiertos más adelante en este capítulo en la sección sobre
vulnerabilidades de software comunes y contramedidas.

Evolución de los lenguajes de programación

El conocimiento de todos los códigos de instrucciones del procesador puede ser


extremadamente oneroso en un programador, si es que es humanamente posible.
Incluso un programa extremadamente simple requeriría que el programador escriba
líneas de código que manipulen datos usando códigos de operación, y en una época
de ritmo rápido donde la velocidad de entrega es crítica importante para el éxito de
los negocios, programas de software como cualquier otro producto no puede tomar
una cantidad excesiva de tiempo. Para facilitar el esfuerzo del programador y
acortar el tiempo de entrega del desarrollo de software, programación más sencilla
se han desarrollado lenguajes que abstraen los códigos de instrucción del
procesador en bruto. Hay muchos lenguajes de programación que existen en la
actualidad.

Los desarrolladores de software utilizan un lenguaje de programación para crear


programas y pueden elegir un lenguaje de programación de bajo nivel. Una
programación de bajo nivel el lenguaje es un lenguaje que está estrechamente
relacionado con la instrucción del hardware (CPU). Ofrece poca o ninguna
abstracción del lenguaje que la máquina entiende cuáles son los códigos binarios (0
y 1). Cuando no hay abstracción y el programador escribe código en 0 y 1 para
manipular los datos y el procesador instrucciones, que es una rareza, es el lenguaje
de máquina en el que están codificando. Sin embargo, el lenguaje de programación
de bajo nivel más común en la actualidad es el lenguaje ensamblador que ofrece
poca abstracción del lenguaje máquina utilizando códigos de operación. El Apéndice
B tiene una lista de los códigos de operación comunes usados ​en ensamblaje
lenguaje para abstraer códigos de instrucción del procesador en un Intel 80186 o
chip superior de microprocesador (CPU). El lenguaje de máquina y el lenguaje
ensamblador son ambos ejemplos de lenguajes de programación de bajo nivel. Un
ensamblador convierte el ensamblaje código en código de máquina.

Por el contrario, los lenguajes de programación de alto nivel (HLL) aíslan el


programa detalles de la instrucción de ejecución y la semántica de la arquitectura de
la computadora la propia especificación funcional del programa. Lenguajes de
programación de alto nivel resumen los códigos de instrucción del procesador sin
procesar en una notación que el programador puede entender fácilmente. La
notación especializada con la que un programador abstrae códigos de instrucción de
bajo nivel se llama sintaxis y cada programación el lenguaje tiene su propia sintaxis.
De esta forma, el programador se centra en escribir código que aborda los requisitos
comerciales en lugar de preocuparse por cómo manipular las instrucciones y los
indicadores de datos a nivel de microprocesador. Esto hace que el desarrollo de
software sea ciertamente más simple y el programa de software más fácilmente
comprensible. Sin embargo, es importante reconocer que con la evolución de
lenguajes de programación y entornos de desarrollo integrados (IDE) y herramientas
que facilitan la creación de programas de software, incluso profesionales que
carecen del conocimiento interno de cómo su programa de software se ejecutarán a
nivel de máquina ahora son capaces de desarrollar software. Esta puede ser muy
perjudicial desde el punto de vista de la seguridad, porque los creadores de software
puede que no necesariamente comprenda o conozca los mecanismos de protección
y controles que deben desarrollarse y, por lo tanto, dejarlos fuera sin querer.

Hoy en día, la evolución de los lenguajes de programación nos ha proporcionado


lenguajes de programación que también se conocen como programación de muy
alto nivel idiomas (VHLL). El nivel de abstracción en algunos de los VHLL ha sido
tan aumentado que la sintaxis para programar en estos VHLL es como escribir en
Inglés. Además, lenguajes como el lenguaje natural ofrecen aún más abstracción y
se basan en la resolución de problemas utilizando lógica basada en restricciones
dado al programa en lugar de utilizar los algoritmos escritos en código por el

programador de software. Los lenguajes naturales se utilizan con poca frecuencia


en los negocios configuraciones y también se conocen como lenguajes de
programación lógica o basados ​en restricciones lenguajes de programación.

La figura 4.4 ilustra la evolución de los lenguajes de programación comenzando con


el lenguaje de máquina de bajo nivel al lenguaje natural de VHLL.
La sintaxis en la que un programador escribe su código de programa es la fuente de
código. El código fuente debe convertirse en un conjunto de códigos de
instrucciones que la computadora puede comprender y procesar. El código que
entiende la máquina es el código máquina que también se conoce como código
nativo. En algunos casos, en cambio de convertir el código fuente en código de
máquina, el código fuente es simplemente interpretado y ejecutado por un programa
separado. Dependiendo de cómo sea el programa ejecutado en la computadora,
HLL se puede clasificar en lenguajes compilados e idiomas interpretados.

Idiomas compilados

La forma predominante de lenguajes de programación son los lenguajes


compilados. Los ejemplos incluyen COBOL, Fortran, BASIC, Pascal, C, C ++ y
Visual Basic. El código fuente que escribe el programador se convierte en código
máquina. La conversión en sí es un proceso de dos pasos como se muestra en la
Figura 4.5 que incluye dos subprocesos, a saber. recopilación y vinculación.

■ La compilación es el proceso de convertir el código fuente textual escrito por el


programador en instrucciones específicas del procesador sin procesar códigos. La
salida del proceso de compilación se llama objeto código que es creado por el
programa compilador. En resumen, compilado el código fuente es el código objeto.
El código objeto en sí no puede ser ejecutado por la máquina a menos que tenga
todos los archivos de código necesarios y dependencias proporcionadas a la
máquina.
■ Vincular es el proceso de combinar las funciones necesarias, variables y
dependencias archivos y bibliotecas necesarios para la máquina para ejecutar el
programa. La salida que resulta del proceso de vinculación es el programa
ejecutable o código / archivo de máquina que la máquina puede comprender y
procesar. En resumen, el objeto vinculado al código es el ejecutable. Los editores de
enlaces que combinan códigos de objeto son conocidos como enlazadores. Una vez
finalizado el proceso de compilación, el compilador invoca al enlazador para realizar
su función.

Hay dos tipos de enlaces: enlaces estáticos y enlaces dinámicos. Cuando el


vinculador copia todas las funciones, variables y bibliotecas necesarias para que el
programa se ejecute, en el propio ejecutable, se hace referencia a como enlace
estático. La vinculación estática ofrece la ventaja de un procesamiento más rápido
velocidad y facilidad de portabilidad y distribución porque el requerido las
dependencias están presentes dentro del propio ejecutable. Sin embargo, basado
en el tamaño y el número de otros archivos de dependencias, el final El ejecutable
puede estar inflado y las consideraciones de espacio adecuadas.
necesita ser tomado. A diferencia de los enlaces estáticos, solo en enlaces
dinámicos los nombres y ubicaciones respectivas de los archivos de código objeto
necesarios se colocan en el ejecutable final y la vinculación real no ocurre hasta el
tiempo de ejecución cuando tanto el ejecutable como los archivos de la biblioteca
están colocado en la memoria. Aunque esto requiere menos espacio,
dinámicamente los ejecutables vinculados pueden enfrentar problemas relacionados
con las dependencias si no se puede encontrar en tiempo de ejecución. Se debe
elegir el enlace dinámico sólo después de una cuidadosa consideración a la
seguridad, especialmente si los archivos de objetos vinculados se suministran desde
una ubicación remota y están abiertos fuente en la naturaleza. Un hacker puede
corromper maliciosamente a un dependiente biblioteca y cuando están vinculados
en tiempo de ejecución, pueden comprometer todos los programas que dependen
de esa biblioteca.

Idiomas interpretados

Si bien los programas escritos en lenguajes compilados se pueden ejecutar


directamente en el procesador, los lenguajes interpretados necesitan un programa
anfitrión intermediario para leer y ejecutar cada instrucción de instrucción línea por
línea. El código fuente es no compilado ni convertido en códigos de instrucción
específicos del procesador. Común ejemplos de lenguajes interpretados incluyen
REXX, PostScript, Perl, Ruby y Pitón. Los programas escritos en lenguajes
interpretados son más lentos en ejecución velocidad, pero proporcionan el beneficio
de cambios más rápidos porque no es necesario para volver a compilar y volver a
vincular como es el caso de los escritos en compilado Idiomas.

Idiomas híbridos

Aprovechar los beneficios que brindan los lenguajes compilados e interpretados


idiomas, también hay una combinación (híbrida) de compilados e interpretados
Idiomas En esto, el código fuente se compila en una etapa intermedia que se
asemeja al código objeto. A continuación, el código de la etapa intermedia se
interpreta según sea necesario Java es un ejemplo común de lenguaje híbrido. En
Java, la etapa intermedia el código que resulta de la compilación del código fuente
se conoce como código de bytes. El código de bytes se parece a los códigos de
instrucción del procesador pero no se puede ejecutar como tal requiere un programa
anfitrión independiente que se ejecute en la computadora para interpretar el código
de bytes y la máquina virtual Java (JVM) proporciona esto para Java. En los
lenguajes de programación .Net, el código fuente se compila en lo que se conoce
como lenguaje Intermedio Común (CIL), anteriormente conocido como lenguaje
intermedio de Microsoft (MSIL). En tiempo de ejecución, el lenguaje común el
compilador Just a tiempo del tiempo de ejecución convierte el código CIL en código
nativo, que luego es ejecutado por la máquina.

Controles y vulnerabilidades de software comunes


Si bien el software seguro es el resultado de una confluencia entre personas, el
proceso y tecnología, en este capítulo, nos centraremos principalmente en la
tecnología y procesar aspectos de la escritura de código seguro. Conoceremos los
más comunes vulnerabilidades que resultan de una codificación insegura; cómo un
atacante puede explotar esos vulnerabilidades; comprender la anatomía del ataque
en sí y discutir la seguridad controles que deben establecerse (en el código) para
resistir y frustrar las acciones de agentes de amenaza.

Hoy en día, la mayoría de los incidentes notificados de violaciones de seguridad


parecen tener una cosa en común: son ataques que explotan alguna debilidad en el
capa de software. El análisis de las infracciones indica invariablemente uno de los
siguientes ser la causa raíz de la infracción: fallas de diseño, problemas de
codificación (implementación), configuración y operaciones inadecuadas, con
predominio de ataques que explotan debilidades de codificación del software.

Las bases de datos de vulnerabilidades son repositorios de vulnerabilidades


descubiertas y conocidas que se ha observado que afectan los sistemas
informáticos y el software. La mayoría de se ha descubierto que las vulnerabilidades
son el resultado de deficiencias y defectos en software implementado (por ejemplo,
fallas y errores). Estas bases de datos incluyen en ellas, el nombre de la
vulnerabilidad que puede explotarse si no se aborda, la descripción de la
vulnerabilidad, cuán explotable es, el impacto potencial sobre la infracción y las
recomendaciones de mitigación (es decir, controles) para abordar la vulnerabilidad.

Algunos ejemplos bien conocidos y útiles de bases de datos y seguimiento de


vulnerabilidades los sistemas son:

■ La Base de datos nacional de vulnerabilidades (NVD): es un gobierno de los EE.


UU. repositorio de vulnerabilidades y datos de gestión de vulnerabilidades. Esta los
datos se representan mediante el protocolo de automatización de contenido de
seguridad (SCAP) como especificaciones interoperables que permiten la
automatización de gestión de vulnerabilidades, medición de seguridad y
cumplimiento. El NVD incluye listas de verificación de seguridad, fallas de software
relacionadas con la seguridad, configuraciones incorrectas de productos, productos
afectados y métricas de impacto.

■ Vulnerabilidad del equipo de respuesta ante emergencias informáticas de EE. UU.


(CERT) base de datos de notas: el proyecto de análisis de vulnerabilidad CERT
tiene como objetivo reducir los riesgos de seguridad debido a las vulnerabilidades
del software en ambos y software implementado. En el software que se está
desarrollando, se enfocan en el descubrimiento de vulnerabilidades y en software
que ya está implementado, sobre la remediación de vulnerabilidades. Las
vulnerabilidades recién descubiertas son agregadas a la base de datos de notas de
vulnerabilidad. Los existentes se actualizan según sea necesario.

■ Base de datos de vulnerabilidades de código abierto: una base de datos de origen


creada por y para la comunidad de seguridad, con el objetivo de proporcionar
información precisa, detallada, actual e imparcial información técnica sobre
vulnerabilidades de seguridad.
■ Vulnerabilidades y exposiciones comunes (CVE): un diccionario de
vulnerabilidades y exposiciones de seguridad de la información de conocimiento
público. Eso es de uso gratuito y de alcance internacional.
■ OWASP Top 10: la lista OWASP Top 10, además de considerar los problemas de
seguridad de aplicaciones más comunes de una debilidad o perspectiva de
vulnerabilidades, ve los problemas de seguridad de las aplicaciones desde una
perspectiva perspectiva de riesgos organizacionales (riesgo técnico e impacto
empresarial) como se tabula en la Tabla 4.1.
■ Enumeración de debilidades comunes (CWE ™): proporciona un lenguaje para
describir software arquitectónico, de diseño o de codificación de debilidades de
seguridad. Es de alcance internacional, disponible gratuitamente para uso público y
está destinado a proporcionar un estándar y definitivo Lista "formal" de debilidades
del software. Categorizaciones de software las debilidades de seguridad se derivan
de taxonomías de seguridad de software. Los 25 errores de programación más
peligrosos de CWE / SANS son se muestra en la Tabla 4.2.
La lista de los 25 errores de programación más peligrosos de CWE / SANS cae
en las siguientes tres categorías:

■ Interacción insegura entre componentes, que incluye debilidades que se


relacionan con formas inseguras en las que se envían los datos y recibidos entre
componentes, módulos, programas separados, proceso, hilos o sistemas.
■ Gestión de recursos de riesgo: que incluye debilidades que se relacionan a las
formas en que el software no gestiona correctamente la creación, uso, transferencia
o destrucción de importantes recursos del sistema.
■ Defensas porosas: incluye debilidades relacionadas con la defensa técnicas que a
menudo se usan incorrectamente, se abusan o simplemente se ignoran.

La categorización de los 25 CWE / SANS de 2009 más peligrosos los errores de


programación se muestran en la Tabla 4.3.

Se recomienda que visite los respectivos sitios web del OWASP Lista de los 10
principales y la lista de los 25 principales de CWE / SANS, ya que se espera que un
CSSLP sea familiarizado con los problemas de programación que pueden provocar
infracciones de seguridad y cómo abordarlos.
Las vulnerabilidades y riesgos de seguridad de software más comunes se tratan en
la siguiente sección. Cada vulnerabilidad o riesgo se describe primero en cuanto a lo
que es y cómo ocurre, seguido de una discusión de los controles de seguridad que
pueden ser implementados para mitigarlo.

Desbordamiento de búfer

Históricamente, uno de los ataques más peligrosos y graves contra el software ha


habido ataques de desbordamiento de búfer. Para comprender qué constituye un
búfer desbordamiento, primero es importante que haya leído y comprendido cómo
trabajos de ejecución y gestión de memoria. Esto se cubrió anteriormente en este
capítulo en la sección de arquitectura de la computadora.

Un desbordamiento de búfer es la condición que ocurre cuando los datos que se


están copiando en el búfer (espacio de almacenamiento contiguo asignado en la
memoria) es más de lo que el búfer puede manejar. Esto significa que la longitud de
los datos que se están copiando es igual a (en idiomas que necesitan un byte para
el terminador NULL) o es mayor que el recuento de bytes del búfer. Los dos tipos de
desbordamientos de búfer son:

■ desbordamiento de pila
■ desbordamiento del montón

Desbordamiento de pila

Cuando el búfer de memoria se ha desbordado en el espacio de la pila, se sabe


como desbordamiento de la pila. Cuando se ejecuta el programa de software, las
instrucciones de ejecución se colocan en el segmento de texto del programa de la
RAM, las variables globales se colocan en la sección de datos de lectura-escritura
de la RAM y datos (variables locales, función argumentos), y el valor del registro
ESP que es necesario para que la función complete se inserta en la pila, (a menos
que los datos sean un objeto de tamaño variable en cuyo caso se coloca en el
montón). A medida que el programa se ejecuta en la memoria, secuencialmente
llama a cada función y empuja los datos de esa función en la pila desde más alto
espacio de direcciones para reducir el espacio de direcciones, creando una cadena
de funciones que se ejecutarán en el orden previsto por el programador. Al
completar una función, que función y sus datos asociados se extraen de la pila y el
programa continúa ejecutando la siguiente función en la cadena. Pero, ¿cómo
funciona el programa? saber qué función debe ejecutar y a qué función debe ir una
vez la función actual ha completado su operación? El registro ESP (introducido
antes) le dice al programa qué función debe ejecutar. Otro especial registro dentro
de la CPU es el contador de instrucciones de ejecución (EIP) que es se utiliza para
mantener el orden de secuencia de las funciones, pero indica la dirección de la
siguiente instrucción a ejecutar. Esta es la dirección de retorno (RET) del función. La
dirección de retorno también se coloca en la pila cuando se llama a una función y la
protección de la dirección del remitente para que no se sobreescriba
incorrectamente es crítico desde el punto de vista de la seguridad. Si un usuario
malintencionado logra sobrescribir la dirección de retorno para apuntar a un espacio
de direcciones en la memoria, donde un exploit se ha inyectado el código (también
conocido como carga útil), luego de la finalización de una función, la dirección de
retorno sobrescrita (contaminada) se cargará en el EIP registro, y la ejecución del
programa se desbordara, potencialmente ejecutando el carga útil maliciosa.

El uso de funciones inseguras como strcpy () y strcat () puede resultar en pila


desbordamientos, ya que no realizan intrínsecamente comprobaciones de longitud
antes de copiar datos en el búfer de memoria.

Desbordamiento de montón

A diferencia de un desbordamiento de pila, en el que los datos fluyen de un espacio


de búfer a otro, haciendo que el puntero de instrucción de dirección de retorno se
sobrescribe, un montón los desbordamientos no necesariamente se desbordan, sino
que corrompen el espacio de memoria del montón (búfer), sobrescribiendo variables
y punteros de función en el montón. El corrupto la memoria del montón puede o no
ser utilizable o explotable. Un desbordamiento de montón no es realmente un
desbordamiento pero una corrupción de la memoria del montón y objetos de tamaño
variable o los objetos demasiado grandes para ser insertados en la pila se asignan
dinámicamente en el montón. La asignación de memoria del montón generalmente
requiere operadores de funciones especiales como malloc () (ANSI C), HeapAlloc ()
(Windows), new () (C ++) y desasignación de la memoria de pila utiliza otros
operadores de funciones especiales como free (), HeapFree (), y eliminar (). Dado
que no existen controles intrínsecos sobre los límites de memoria asignados, es
posible sobrescribir fragmentos de memoria adyacentes si no hay validación de
tamaño, codificado por el programador. La explotación del espacio del montón
requiere mucho más requisitos que cumplir, que en el caso del desbordamiento de
pila. Sin embargo, La corrupción del montón puede causar efectos secundarios
graves, incluida la denegación de servicio y Los mecanismos de protección y
ejecución de código de explotación no deben ignorarse.

Cualquiera de las siguientes razones puede atribuirse a causar desbordamientos de


búfer:

■ Copia de datos en el búfer sin verificar el tamaño de la entrada


■ Acceder al búfer con valores de longitud incorrectos
■ Validación incorrecta del índice de matriz (expresión más simple de un búfer):
Cuando no se realizan las comprobaciones adecuadas del índice de matriz fuera de
los límites, índices de referencia en búferes de matrices que no existen arrojaron un
Excepción fuera de límites y potencialmente puede causar desbordamientos.

■ Desbordamientos de enteros o envolventes: cuando se comprueba para


garantizar que las entradas numéricas están dentro del rango esperado (máximo y
valores mínimos), entonces el desbordamiento de enteros puede ocurren resultando
en cálculos defectuosos, bucles infinitos y arbitrarios ejecución de código.
■ Cálculo incorrecto del tamaño del búfer antes de su asignación: desbordamientos
puede resultar si el programa de software no calcula con precisión el tamaño de los
datos que se ingresarán en el espacio del búfer que se va a asignar. Sin esta
verificación de tamaño, el tamaño del búfer asignado puede ser insuficiente para
manejar los datos que se copian en él.

Independientemente de lo que causa un desbordamiento del búfer o si un


desbordamiento del búfer está en la pila o en el búfer de memoria del montón, lo
único que es común en el software que es susceptible a ataques de desbordamiento
es que el programa no realizar comprobaciones del tamaño adecuado de los datos
de entrada. La validación del tamaño de entrada es la Defensa de implementación
(programación) número uno contra búfer en general ataques de verificación doble
del tamaño del búfer para asegurarse de que sea lo suficientemente grande para
manejar los datos de entrada copiados en él, verificando los límites del búfer para
hacer asegúrese de que las funciones en un bucle no intenten escribir más allá del
espacio asignado, y realizar comprobaciones de tipo entero (tamaño, precisión,
firmado / no firmado) para realizar seguro de que están dentro del rango y los
valores esperados, son otros elementos defensivos implementaciones de controles
en código. Algunos programas están escritos para truncar el cadena de entrada a
una longitud especificada antes de leerlos en un búfer, pero cuando esto se hace,
se debe prestar especial atención para asegurar que la integridad de la los datos no
están comprometidos.

Además de los controles de implementación, existen otros controles, como


requisitos, arquitectura, compilación / compilación y controles de operaciones, que
se pueden implementado para defenderse de los ataques de desbordamiento del
búfer éstos incluyen:

■ Elija un lenguaje de programación que realice su propia memoria gestión y es de


tipo seguro. Los lenguajes de tipo seguro son aquellos que evitan errores de tipo no
deseados, que resultan de las operaciones (generalmente casting o conversión) en
valores que no son del tipo de datos apropiado. Tipo de seguridad (cubierto con más
detalle más adelante en este capítulo) está estrechamente relacionado con la
seguridad de la memoria como tipo inseguro los idiomas no evitarán que un entero
arbitrario se utilice como puntero en memoria. Los lenguajes de programación Ada,
Perl, Java y .Net son ejemplos de lenguajes que realizan la gestión de la memoria y
/ o escriba seguro. Sin embargo, es importante reconocer que la intrínseca
protección de desbordamiento proporcionada por algunos de estos lenguajes puede
ser sobrescrita por el programador. Además, aunque el idioma en sí pueden ser
seguras, las interfaces que proporcionan al código nativo pueden ser vulnerable a
varios ataques y al invocar funciones nativas de dichos lenguajes, se deben realizar
las pruebas adecuadas para garantizar que los ataques de desbordamiento no son
posibles.

■ Utilice una biblioteca o un marco comprobados y comprobados que incluyan


funciones de manipulación de cadenas como Safe C String (SafeStr) biblioteca, o
los paquetes de manejo de Safe Integer como SafeInt (C ++ _ o IntegerLib (C o C
++).
■ Reemplazar las funciones de API obsoletas, inseguras y prohibidas que
susceptibles a problemas de desbordamiento con alternativas más seguras que
funcionan verificaciones de tamaño antes de realizar sus operaciones. Es
recomendado que se familiarice con las funciones de API prohibidas y sus
alternativas más seguras para los idiomas que utiliza en su organización. Cuando se
utilizan funciones que toman el número de bytes para copiar como parámetro (como
strncpy () o strncat (), uno debe tener en cuenta que si el tamaño del búfer de
destino es igual al tamaño del búfer de origen, puede encontrarse con una condición
en la que la cadena es no terminado, porque no hay lugar en el búfer de destino
para sujetar el terminador NULL.
■ Diseñe el software para utilizar enteros sin signo siempre que sea posible y
cuando se utilizan enteros con signo, es importante asegurarse de que los controles
están codificados para validar tanto el máximo como el mínimo valores del rango.
■ Aproveche la seguridad del compilador si es posible. Ciertos compiladores y Las
extensiones proporcionan protección y mitigación de desbordamiento al incorporar
mecanismos para detectar desbordamientos de búfer en el código compilado (de
construcción). La bandera de Microsoft Visual Studio / GS, Fedora / Red Hat
FORTIFY_SOURCE Indicador GCC y StackGuard son algunos ejemplos de esto.
■ Aproveche las funciones del sistema operativo, como el diseño del espacio de
direcciones aleatorización, que obliga al atacante a tener que adivinar la dirección
de memoria ya que su diseño es aleatorio en cada ejecución del programa. Otra
característica del sistema operativo para aprovechar es la ejecución de datos
Protección (DEP) o Protección del espacio de ejecución (ESP) que realiza
comprobaciones adicionales en la memoria para evitar códigos maliciosos se
ejecute en un sistema. Sin embargo, esta protección puede quedarse corta cuando
el código malicioso tiene la capacidad de modificarse para parecer como un código
inocuo. ASLR y DEP / ESP se tratan en más detalles más adelante en este capítulo
bajo el tema de administración de memoria.
■ Uso de herramientas de verificación de memoria y otras herramientas que rodean
a todos fragmentos de memoria asignados dinámicamente con páginas no válidas
para que la memoria no puede desbordarse en ese espacio es un medio de defensa
contra la corrupción del montón. MemCheck, Memwatch, Memtest86, Valgrind y
ElectricFence son algunos ejemplos de tales herramientas.

Defectos de inyección

Considerada una de las debilidades de seguridad de software (o aplicación) más


frecuentes, las fallas de inyección ocurren cuando los datos proporcionados por el
usuario no se validan antes de ser procesado por un intérprete. El atacante
proporciona datos que se aceptan tal cual e interpretado como un comando o parte
de un comando, lo que permite al atacante ejecutar comandos usando cualquier
vector de inyección. Casi cualquier fuente de aceptación de datos es un vector de
inyección potencial si los datos no se validan antes de su procesamiento. Los
ejemplos comunes de vectores de inyección incluyen QueryStrings, entrada de
formulario y applets en aplicaciones web. Los defectos de inyección se pueden
descubrir fácilmente mediante código revisión y escáneres, incluidos los escaneos
fuzzing, se pueden emplear para detectarlos. Hay varios tipos diferentes de ataques
por inyección. Los más comunes incluyen:

■ inyección SQL
■ Inyección de comandos del sistema operativo
■ Inyección de LDAP y
■ inyección XML

Inyección SQL

Esta es probablemente la forma más conocida de ataques de inyección como las


bases de datos que almacenan datos comerciales se están convirtiendo en el
objetivo principal de los atacantes. En SQL inyección, los atacantes explotan la
forma en que se construyen las consultas de la base de datos. Suministran insumos,
que si no se desinfectan o validan pasan a formar parte del (Lenguaje de consulta
estructurado) consulta que las bases de datos procesan como un comando.
Consideremos un ejemplo de una implementación de código vulnerable en la que el
el texto del comando de consulta (sSQLQuery) se crea dinámicamente utilizando los
datos que se proporcionado desde los campos de entrada de texto (txtUserID y
txtPassword) del formulario web.

Cuerda sSQLQuery = "SELECCIONAR * DE USUARIOS DONDE usuario_id =" "+


txtUserID.Text + "‘ AND usuario_contraseña = ‘" + txt Constraseña.Text + "‘
Si el atacante proporciona "OR 1 = 1 - como el valor txtUserID, entonces el SQL
El texto del comando de consulta que se genera es el siguiente:

Cuerda sSQLQuery = "SELECT * FROM USERS WHERE user_id =" "+"


O 1 = 1 - - + ”‘ AND usuario_contraseña = ‘” + txtcontraseña.Text + ”‘

Esto da como resultado la sintaxis SQL como se muestra a continuación, que el


intérprete evaluará y ejecutará como un comando SQL válido. Todo después de - en
T-SQL es ignorado.

SELECCIONAR * DE USUARIOS DONDE user_id = "" O 1 = 1 - -

El flujo de ataque en SQL Injection consta de los siguientes pasos:

1. Exploración mediante la hipótesis de consultas SQL para determinar si el


el software es susceptible a la inyección SQL
2. Experimentar para enumerar el esquema de la base de datos interna forzando
errores de base de datos
3. Aprovechar la vulnerabilidad de inyección de SQL para evitar verificaciones o
modificar, agregar, recuperar o eliminar datos de la base de datos

Al determinar que la aplicación es susceptible a la inyección SQL, un atacante


intentará obligar a la base de datos a responder con mensajes que potencialmente
divulguen la estructura y los valores internos de la base de datos pasando SQL
comandos que provocan errores en la base de datos. Suprimir los mensajes de error
de la base de datos frustra considerablemente los ataques de inyección SQL, pero
se ha demostrado que esto no es suficiente para prevenir completamente la
inyección de SQL. Atacantes han encontrado una forma de evitar el uso de
mensajes de error para construir sus comandos SQL como es evidente en la
variante de inyección SQL, que se conoce como inyección SQL ciega. En inyección
SQL ciega, en lugar de usar información de mensajes de error para facilitar la
inyección de SQL, el atacante construye simples Expresiones SQL booleanas
(preguntas de verdadero / falso) para sondear iterativamente el objetivo base de
datos; dependiendo de si la consulta se ejecutó con éxito o no, el atacante puede
determinar la sintaxis y la estructura de la inyección. El atacante también puede
anotar el tiempo de respuesta a una consulta con una condición lógicamente
verdadera y uno con una condición falsa y use esa información para determinar si
una consulta se ejecuta con éxito o no.
Inyección de comandos del sistema operativo

Funciona con el mismo principio que los otros ataques de inyección donde el
comando la cadena se genera dinámicamente utilizando la entrada proporcionada
por el usuario cuando el software permite la ejecución de comandos de nivel del
sistema operativo (SO) utilizando la entrada de usuario proporcionada sin
desinfección o validación, se dice que es susceptible a la inyección de OS comando.
Esto podría ser seriamente devastador para el negocio si el principio de privilegio
mínimo no está diseñado en el medio ambiente que está siendo comprometido. Los
dos tipos principales de inyección de comandos del sistema operativo son como
sigue:

■ El software acepta argumentos del usuario para ejecutar una sola comando de
programa fijo. En tales casos, la inyección está contenida solo al comando que se le
permite ejecutar y el atacante puede cambiar la entrada pero no el comando en sí
aquí el error de programación es que el programador asume que la entrada
proporcionados por los usuarios para ser parte de los argumentos en el comando
para se ejecutará será confiable según lo previsto y no malicioso.
■ El software acepta argumentos del usuario que especifica qué comando del
programa que les gustaría que ejecute el sistema. Esto es mucho más grave que el
caso anterior, porque ahora el atacante puede encadenar varios comandos y causar
un daño grave al sistema ejecutando sus propios comandos compatibles con el
sistema. Aquí, el error de programación es que el programador asume que el
comando en sí no será accesible para usuarios que no sean de confianza.

Un ejemplo de una inyección de comando del sistema operativo que un atacante


proporciona como valor de un parámetro QueryString para ejecutar el comando bin /
ls para listar todos los archivos en el directorio "bin" se muestra a continuación:

http://www.mycompany.com/sensitive/cgi-bin/userData.pl?doc=%20%3B%20/bin/ls
%20-l

% 20 descodifica a un espacio y% 3B descodifica a a; y el comando que es


ejecutado será / bin / ls -l enumerando el contenido del directorio de trabajo del
programa.
Inyección LDAP

El Protocolo ligero de acceso a directorios (LDAP) es un protocolo que se utiliza


para almacenar información sobre usuarios, hosts y otros objetos. La inyección de
LDAP funciona en el mismo principio que la inyección SQL o la inyección de
comandos del sistema operativo. No higienizado y La entrada no válida se utiliza
para construir o modificar la sintaxis, el contenido y los comandos que se ejecutan
como una consulta LDAP. El compromiso puede llevar a la divulgación de
información sensible y privada, así como la manipulación de contenido dentro del
Estructura de árbol LDAP (jerárquica). Digamos que tiene la consulta ldap
(_sldapQuery) construida dinámicamente utilizando la entrada proporcionada por el
usuario (nombre de usuario) sin ninguna validación como se muestra en el siguiente
ejemplo.

Cuerda _sldapQuery = ’’ (cn = ’’ + $ UsuarioNombre + ’’) ’’;

Si el atacante proporciona el comodín "*", la información sobre todos los usuarios


enumerados en se divulgará el directorio. Si el usuario proporciona el valor como ""
"sjohnson) (| contraseña = *)) ", la ejecución de la consulta LDAP producirá la
contraseña para el usuario "sjohnson".

Inyección XML

La inyección de XML se produce cuando el software no filtra ni cita correctamente


caracteres especiales o palabras reservadas que se utilizan en XML, lo que permite
a un atacante modificar la sintaxis, el contenido o los comandos antes de la
ejecución. Los dos principales tipos de inyección XML son los siguientes:

■ Inyección XPATH
■ Inyección de XQuery

En la inyección XPATH, la expresión XPath que se utiliza para recuperar datos del
almacén de datos XML no está validado o desinfectado antes de su procesamiento
y construcción dinámicamente utilizando la entrada proporcionada por el usuario.
Por tanto, la estructura de la consulta ser controlado por el usuario, y un atacante
puede aprovechar esta debilidad mediante la inyección de expresiones XML mal
formadas, lo que permite al atacante realizar operaciones malintencionadas como
modificar y controlar el flujo lógico, recuperar datos no autorizados y / o eludir los
controles de autenticación. XQuery
La inyección funciona de la misma manera que una inyección XPath, excepto que
XQuery (no XPath) expresión que se utiliza para recuperar datos del almacén de
datos XML es no validado o desinfectado antes del procesamiento y construido
dinámicamente con el usuario entrada suministrada.

Considere el siguiente documento XML (accounts.xml) que almacena el información


de la cuenta y números de PIN de los clientes y un fragmento de código Java que
utiliza la consulta XPath para recuperar información de autenticación:

<clientes>
<cliente>
<usuario_nombre> andrew </usuario_nombre>
<accountnum> 1234987655551379 </accountnum>
<pin> 2358 </pin>
<homepage> / home / astrout </homepage>
</cliente>
<cliente>
<nombre_usuario> dave </nombre_usuario>
<accountnum> 9865124576149436 </accountnum>
<pin> 7523 </pin>

<homepage> / home / dclarke </homepage>


</cliente>
</clientes>
El código Java que se utiliza para recuperar el directorio de inicio en función de las
credenciales proporcionadas es:

XPath xpath = XPathFactory.newInstance (). NewXPath ();


XPathExpression xPathExp = xpath.compile ("// clientes / cliente [usuario_
name / text () = ’” + login.getUsuarionombre () + “’ y pin / text () = ‘” + login.
getPIN () + “’] / homepage / text () ”);
Documento doc = DocumentBuilderFactory.newInstance ().
newDocumentBuilder (). parse (nuevo archivo ("cuentas.xml"));
Cadena de página de inicio = xPathExp.evaluate (doc);
Al pasar el valor "andrew" al método getUsuarioNombre () y el valor "" o "" = "
en la llamada al método getPIN (), la expresión XPath se convierte
// clientes / cliente [nombre_usuario / text () = ’andrew" o ‘’ = ’’ y pin / text () = ‘’ o
‘’ = ’’] / Página de inicio / texto ()
Esto permitirá que el usuario inicie sesión como "andrew; para evitar la autenticación
sin proporcionar un PIN válido.

Independientemente de si una falla de inyección explota una base de datos, el


comando del sistema operativo, un protocolo y estructura de directorio o un
documento, todos se caracterizan por uno o más de los siguientes rasgos:

■ La entrada proporcionada por el usuario se interpreta como un comando o parte


de un comando que se ejecuta. En otras palabras, los datos se malinterpretan
por el intérprete como código.
■ La entrada del usuario no se desinfecta ni válida antes del procesamiento.
■ La consulta que se construye se genera dinámicamente usando el usuario
entrada suministrada.

Las consecuencias de los defectos de inyección son variadas y graves los más
comunes incluyen:

■divulgación, alteración o destrucción de datos


■ compromiso del sistema operativo
■ descubrimiento de la estructura interna (o esquema) de la base de datos o
Almacén de datos
■ enumeración de cuentas de usuario de un almacén de directorio
■ eludir los cortafuegos anidados
■ omitir la autenticación
■ ejecución de procedimientos extendidos y comandos privilegiados

Estrategias de mitigación y prevención y controles para fallas de inyección que son


comúnmente empleados se enumeran a continuación:

■ Considere que todas las entradas no son confiables y valide todas las entradas
del usuario. Desinfecte y filtre la entrada usando una lista blanca de caracteres
permitidos y sus formas no canónicas. Mientras usa una lista negra de Los
caracteres no permitidos pueden ser útiles para detectar posibles ataques o
determinando insumos mal formados, confiando únicamente en listas negras puede
resultar insuficiente ya que el atacante puede probar variaciones y representación
alternativa de la forma de lista negra la validación debe ser realizado tanto en el lado
del cliente como en el servidor o al menos en el del lado del servidor para que los
atacantes no puedan simplemente eludir el lado del cliente verificaciones de
validación y aún realizar ataques de inyección. Entrada del usuario debe ser
validado para el tipo de datos, rango, longitud, formato, valores y representaciones
canónicas. Palabras clave SQL como UNION, SELECT, INSERT, UPDATE,
DELETE, DROP, etc.debe ser filtrado además de caracteres como comillas simples
(‘) o SQL comentarios (-) basados ​en el contexto. La validación de entrada debe ser
una de las primeras líneas de defensa en una estrategia de defensa en profundidad
para prevenir o mitigar los ataques de inyección, ya que reduce significativamente
la superficie de ataque.

■ Codifique la salida utilizando el juego de caracteres apropiado, escape especial


caracteres y entrada de comillas, además de no permitir metacaracteres. En
algunos casos, cuando la entrada debe recopilarse de varias fuentes y es necesario
para admitir texto de forma libre, luego la entrada no puede ser limitada por razones
comerciales, esta puede ser la única solución eficaz para prevenir los ataques por
inyección. Además, proporciona protección incluso cuando algunas fuentes de
entrada no están cubiertas con comprobaciones de validación de entrada.
■ Utilice mecanismos estructurados para separar los datos del código.
■ Evite las consultas dinámicas (SQL, LDAP, expresión XPATH o
XQuery) construcción.
■ Utilice una API segura que evite el uso del intérprete por completo o que
proporcione sintaxis de escape para que el intérprete escape especial caracteres.
Un ejemplo bien conocido es el ESAPI publicado por OWASP.
■ Consultas parametrizadas por el usuario. Solo usando consultas parametrizadas
(procedimientos almacenados o declaraciones preparadas) no garantiza que el
software ya no es susceptible a ataques de inyección. Cuando utilice consultas
parametrizadas, asegúrese de que el diseño de las consultas parametrizadas
realmente aceptan la entrada proporcionada por el usuario como parámetros y no la
consulta en sí como un parámetro que será ejecutado sin ninguna validación
adicional.
■ Mostrar mensajes de error genéricos que producen un mínimo o ningún resultado
información.
■ Implementar la prueba de fallos redirigiendo todos los errores a una página de
error genérica y registrarlo para su posterior revisión.
■ Elimine cualquier función o procedimiento no utilizado de la base de datos servidor
si no es necesario. Elimine todos los procedimientos extendidos que permitir que un
usuario ejecute comandos del sistema.
■ Implementar el privilegio mínimo mediante el uso de vistas y la restricción de
tablas,
consultas y procedimientos a solo el conjunto autorizado de usuarios y / o
cuentas. Los usuarios de la base de datos deben estar autorizados a tener derechos
mínimos necesarios para usar su cuenta. Usando el lector de datos, cuentas de
escritor de datos en lugar de una cuenta de propietario de base de datos (dbo) al
acceder a la base de datos desde el software se recomienda opción.
■ Auditar y registrar las consultas que se ejecutan junto con sus tiempos de
respuesta para detectar ataques de inyección, especialmente ciegos ataques de
inyección.
■ Para mitigar la inyección de comandos del sistema operativo, ejecute el código en
una zona de pruebas entorno que impone límites estrictos entre los procesos en
ejecución y el sistema operativo. Algunos ejemplos incluyen Linux AppArmor y la
cárcel chroot de Unix. El código administrado es también conocido por proporcionar
cierto grado de protección de espacio aislado.
■ Utilice la aplicación de la política de tiempo de ejecución para crear la lista de
comandos (lista blanca) y rechazar cualquier comando que no coincidir con la lista
blanca.
■ Al tener que implementar defensas contra la inyección de LDAP ataques, el mejor
método para manejar adecuadamente la entrada del usuario es filtrar o cite la
sintaxis LDAP de la entrada controlada por el usuario. Esto es dependiente sobre si
la entrada del usuario se utiliza para crear el nombre distintivo (DN) o se utiliza
como parte del texto del filtro de búsqueda. Cuando la entrada se utiliza para crear
el DN, el método de escape de barra invertida (\) puede utilizarse y cuando la
entrada se utiliza como parte del filtro de búsqueda, entonces el equivalente ASCII
del carácter que se escapa necesita para ser utilizado. La tabla 4.4 enumera los
caracteres que deben escaparse y su respectivo método de escape. Es importante
asegurarse que el método de escape toma en consideración la alternativa
representaciones de la forma canónica de la entrada del usuario.

En el caso de que el código no se pueda arreglar, use un firewall de capa de


aplicación para detectar ataques de inyección puede ser un control compensatorio.
Autenticación rota y gestión de sesiones

Las debilidades en los mecanismos de autenticación y la gestión de sesiones no son


poco común en software. Las áreas que son susceptibles a estos defectos suelen
ser que se encuentran en funciones secundarias que se ocupan del cierre de
sesión, la gestión de contraseñas, tiempos de espera, recuérdame, pregunta secreta
y actualizaciones de cuenta. Vulnerabilidades en estas áreas pueden conducir al
descubrimiento y control de sesiones. Una vez que el atacante tiene el control de
una sesión (secuestro) que pueden interponerse en el medio, haciéndose pasar por
usuarios válidos y legítimos ante las dos partes que están involucrados en esa
transacción de sesión. El ataque Man-in-the-Middle (MITM) como se muestra en la
Figura 4.6 es un resultado clásico de autenticación rota y sesión administración.

Además del secuestro de sesiones, la suplantación de identidad y los ataques


MITM, estas vulnerabilidades también pueden permitir que un atacante eluda
cualquier autenticación y decisiones de autorización vigentes. En los casos en que
la cuenta se secuestrado es el de un usuario privilegiado, potencialmente puede
conducir a otorgar acceso a recursos restringidos y, consecuentemente,
compromiso total del sistema.

Algunas de las fallas comunes de programación de software que terminan


resultando en autenticación rota y gestión de sesión rota incluyen, pero no son
limitado a lo siguiente:
■ Permitir más de un conjunto de autenticación o sesión controles de gestión que
permiten el acceso a recursos críticos a través de múltiples canales o rutas de
comunicación.
■ Transmitir credenciales de autenticación e ID de sesión a través de la red en texto
sin formato.
■ Almacenamiento de credenciales de autenticación sin cifrado
■ Credenciales de codificación rígida o claves criptográficas en texto sin cifrar en
línea código, o en archivos de configuración.
■ No utilizar un mecanismo aleatorio para generar contraseñas generadas por el
sistema o ID de sesión.
■ Implementar funciones de administración de cuentas débiles que se ocupen de
creación de cuentas, cambio de contraseñas o recuperación de contraseñas.
■ Exponer los ID de sesión en la URL reescribiendo la URL.
■ Tiempos de espera de sesión y cierre de sesión de cuenta insuficientes o
incorrectos implementación.
■ No implementar protección de transporte o cifrado de datos.

Mitigación y prevención de autenticación y gestión de sesiones requieren una


planificación y un diseño cuidadosos. Algunos de los diseños más importantes las
consideraciones incluyen:

Uso de autenticación y gestión de sesiones integradas y probados mecanismos.


Esto respalda el principio de aprovechar los componentes también. Cuando los
desarrolladores implementan sus mecanismos de autenticación y gestión de
sesiones, aumenta la probabilidad de errores de programación.

■ Utilice un mecanismo de autenticación único y centralizado que admite


autenticación de múltiples factores y control de acceso basado en roles. Segmentar
el software para proporcionar funcionalidad basada en el nivel de privilegio
(anónimo, invitado, normal y administrador) es una opción preferida. Esto no solo
facilita la administración y los derechos configuración, pero también reduce
considerablemente la superficie de ataque.
■ Usar un identificador de sesión único, aleatorio y no adivinable para administrar el
estado y la sesión junto con la realización de la integridad de la sesión cheques. No
utilice para las credenciales, afirmaciones que se pueden falsificar y reproducir.
Algunos ejemplos de estos incluyen la dirección IP, direcciones MAC, DNS o
búsquedas de DNS inverso o encabezados de referencia. Los tokens basados ​en
hardware a prueba de manipulaciones también pueden proporcionar una alta grado
de protección.
■ Al almacenar credenciales de autenticación para llamadas salientes autenticación,
cifrado o hash las credenciales antes de almacenarlas en un archivo de
configuración o almacén de datos que también debe estar protegido de usuarios no
autorizados.
■ No codifique las cadenas de conexión, contraseñas o claves criptográficas en
texto plano en el código o archivos de configuración. La figura 4.7 ilustra un ejemplo
de una forma insegura y segura de almacenar cadenas de conexión de bases de
datos en un archivo de configuración.
■ Identificar y verificar usuarios tanto en la fuente como al final del canal de
comunicación para garantizar que ningún usuario malintencionado se interpusieron
en el medio. Autenticar siempre solo a los usuarios de una fuente encriptada (página
web).
■ No exponga el ID de sesión en las URL ni acepte valores preestablecidos o
agotados identificadores de sesión de la URL o solicitud HTTP.

Los ID de sesión de la URL pueden conducir a lo que se conoce como sesión


ataques de fijación y repetición de sesiones.
■ Asegúrese de que el mecanismo de protección XSS esté en su lugar y funcione
efectivamente, ya que los ataques XSS se pueden utilizar para robar la
autenticación credenciales e ID de sesión.
■ Solicitar al usuario que se vuelva a autenticar al actualizar la cuenta, como
cambios de contraseña y, si es posible, generar una nueva ID de sesión al
autenticación exitosa o cambio en el nivel de privilegios.
■ No implemente cookies personalizadas en el código para administrar el estado.
Utilizar Implementación segura de cookies cerrándose para evitar manipulación y
reproducción de cookies.
■ No almacene, almacene en caché ni mantenga información de estado en el cliente
sin la verificación de integridad o el cifrado adecuados. Si usted es necesario
almacenar en caché por motivos de experiencia del usuario, asegúrese de que el
caché está encriptado y es válido solo por un período de tiempo explícito después
que caducará. Esto se conoce como ventana de caché.
■ Asegúrese de que todas las páginas tengan un enlace para cerrar sesión. No
asuma que el el cierre de la ventana del navegador abandonará todas las sesiones
y el cliente galletas. Cuando el usuario cierra la ventana del navegador, pregunta al
usuario para cerrar sesión explícitamente antes de cerrar la ventana del navegador.
Mantener el principio de diseño de aceptabilidad psicológica en mente, cuando
planear implementar mecanismos de confirmación del usuario. El principio de
aceptabilidad psicológica establece que los mecanismos de seguridad deben no
dificultar el acceso al recurso que si la seguridad los mecanismos no estaban
presentes.
■ Establezca explícitamente un tiempo de espera y diseñe el software para que
registre automáticamente fuera de una sesión inactiva. La duración de la
configuración del tiempo de espera debe ser inversamente proporcional al valor de
los datos protegidos. Por ejemplo, si el software está ordenando y procesando
información confidencial, la duración de la configuración del tiempo de espera debe
ser más corto.
■ Implementar el número máximo de intentos de autenticación permitido y cuando
ese número haya pasado, niegue por defecto y desactivar (bloquear) la cuenta
durante un período de tiempo específico o hasta el usuario sigue un proceso fuera
de banda para reactivar (desbloquear) el cuenta. La implementación de niveles de
aceleración (recorte) no solo evita
contra ataques de fuerza bruta pero también denegación de servicio (DoS).
■ Cifre todas las comunicaciones cliente / servidor.
■ Implementar la protección de la capa de transporte en la capa de transporte (SSL /
TLS) o en la capa de red (IPSec) y cifre los datos incluso si se envía a través de un
canal de red protegido.

Secuencias de comandos entre sitios (XSS)

Los defectos de inyección y Cross Site Scripting (XSS) se pueden considerar como
dos debilidades explotables con mayor frecuencia que prevalecen en el software
actual. Algunos expertos se refieren a estos dos defectos como un "golpe 1-2" como
lo muestra el OWASP y Clasificación CWE.
XSS es el ataque de seguridad de aplicaciones web más frecuente en la actualidad.
Una red se dice que la aplicación es susceptible a la vulnerabilidad XSS cuando el
usuario proporcionó la entrada se envía de vuelta al cliente del navegador sin ser
validada correctamente y su contenido escapó. Un atacante proporcionará un script
(de ahí la parte del guión) en lugar de un valor legítimo y ese guión si no se escapó
antes de ser enviado para el cliente, se ejecuta. Cualquier fuente de entrada puede
ser el vector de ataque y el los agentes de amenazas incluyen a cualquier persona
que tenga acceso a suministrar información. Revisión de código y las pruebas se
pueden utilizar para detectar vulnerabilidades XSS en el software.

Los tres tipos principales de XSS son:

■ No persistente o reflejado
■ Persistente o almacenado
■ Basado en DOM

XSS no persistente o reflejado

Como su nombre lo indica, los XSS no persistentes o reflejados son ataques en los
que el guión de entrada proporcionado por el usuario que se inyecta (también
denominado carga útil) no almacenados pero simplemente incluidos en la respuesta
del servidor web, ya sea en el resultados de una búsqueda o un mensaje de error.
Hay dos formas principales en las que el atacante puede inyectar su guión
malicioso. Uno es que proporcionan la entrada script directamente en su aplicación
web. La otra forma es que pueden enviar un enlace con el guión incrustado y oculto
en él. Cuando un usuario hace clic en el enlace, el script inyectado aprovecha el
servidor web vulnerable que refleja el guión de vuelta al navegador del usuario
donde se ejecuta.

XSS persistente o almacenado

XSS persistente o almacenado se caracteriza por el hecho de que el script


inyectado es almacenados permanentemente en los servidores de destino, ya sea
en una base de datos, un foro de mensajes, un registro de visitantes o un campo de
entrada. Cada vez que las víctimas visitan la página que tiene el código inyectado
almacenado en él o servido desde el servidor web, el script de carga útil se ejecuta
en el navegador del usuario. El infame Samy Worm y el Flash gusano son ejemplos
bien conocidos de un ataque XSS persistente o almacenado.
XSS basado en DOM

XSS basado en DOM es un ataque XSS en el que la carga útil se ejecuta en el


navegador como resultado de modificaciones del entorno DOM en el lado del
cliente. La respuesta HTTP (o la página web) en sí no se modifica, pero las
debilidades en el el lado del cliente permite modificar el código contenido en el
cliente de la página web, para que se pueda ejecutar la carga útil. Esto es
sorprendentemente diferente de las versiones XSS no persistente (o reflejada) y
persistente (o almacenada) porque en estos casos, la carga útil del ataque se coloca
en la página de respuesta debido a debilidades en el lado del servidor.

Las consecuencias de un ataque XSS exitoso son variadas y graves. Atacantes


puede ejecutar un script en el navegador de la víctima y:

■ robar información de autenticación mediante la aplicación web


■ secuestrar y comprometer las sesiones y cuentas de los usuarios
■ cookies de autenticación y administración del estado de manipulación o
envenenamiento
■ causar denegación de servicio (DoS) al desfigurar los sitios web y redirigir
usuarios
■ insertar contenido hostil
■ cambiar la configuración del usuario
■ phishing y robar información confidencial mediante enlaces integrados
■ hacerse pasar por un usuario genuino
■ secuestrar el navegador del usuario con software malicioso

Los controles contra ataques XSS incluyen las siguientes estrategias defensivas y
implementaciones:

■ Maneje la salida al cliente sólo después de que se haya desinfectado. En otra


palabras, la respuesta de salida debe tener escape o codificarse. Esta puede
considerarse como la mejor forma de protegerse contra ataques XSS junto con la
validación de entrada. Escapar de todos los datos no confiables basado en el
contexto HTML (cuerpo, atributo, JavaScript, CSS o URL) es la opción preferida.
Además, establecer el apropiado La codificación de caracteres y la codificación de
la entrada proporcionada por el usuario carga útil que el atacante inyecta como
script en la salida basada en texto respuesta que el navegador simplemente tratará
como un literal y leerá pero
no ejecutar.
■ La validación de la entrada proporcionada por el usuario con una lista blanca
también proporciona protección adicional contra XSS. Todos los encabezados,
cookies, URL se deben validar los valores de la cadena de consulta, los campos de
formulario y los campos ocultos.

Esta validación debe decodificar cualquier entrada codificada y luego validar la


longitud, los caracteres, el formato y las reglas comerciales en los datos antes de
aceptar la entrada. Cada una de las solicitudes que son realizadas al servidor
también debe ser validado. En .Net, cuando el indicador valida la solicitud está
configurado en la aplicación, web o página nivel como se muestra en la Figura 4.8,
cualquier etiqueta de script no codificada que se envía al servidor se marca como
una solicitud potencialmente peligrosa al servidor y no se procesa.

■ No permitir la carga de extensiones .htm o .html


■ Utilice las propiedades innerText de los controles HTML en lugar de las innetHtml
al almacenar la entrada proporcionada, de modo que cuando esta información se
refleja en el cliente del navegador, los datos hace que la salida sea procesada por
los navegadores como literal y como contenido no ejecutable en lugar de scripts
ejecutables.
■ Utilice bibliotecas seguras y marcos de codificación que proporcionen protección
contra problemas XSS. El sitio Microsoft Anti-Cross Scripting, módulo de
codificación OWASP ESAPI, Apache Wicket y el marco de codificación de salida de
SAP son ejemplos bien conocidos.
■ El cliente puede protegerse desactivando la opción de secuencia de comandos
activa en el navegador para que los scripts no se ejecuten automáticamente en el
navegador. La Figura 4.7 muestra las opciones de configuración para activos
secuencias de comandos en el navegador Internet Explorer. También es
recomendable instalar complementos adicionales que evitarán la ejecución de
scripts en el navegador a menos que se otorguen explícitamente permisos para
ejecutarlos. NoScript es un complemento popular para el navegador Mozilla Firefox.
■ Utilice la marca HTTPOnly en la sesión o cualquier cookie personalizada para
que ningún código o secuencia de comandos del lado del cliente puede acceder a la
cookie (si el navegador lo admite) lo que mitiga los ataques XSS. Sin embargo, si el
navegador no admite cookies HTTPOnly, incluso si han establecido el indicador
HTTPOnly en la respuesta HTTP Set-Cookie encabezado, esta bandera se ignora y
la cookie aún puede ser susceptible

a modificaciones y robos de secuencias de comandos maliciosos. Además con la


prevalencia en las tecnologías Web 2.0, principalmente asincrónicas JavaScript y
XML (AJAX), XMLHTTPRequest ofrece lectura acceso a encabezados HTTP,
incluida la respuesta HTTP Set-Cookie encabezamiento.

■ Un firewall de capa de aplicación puede ser útil contra ataques XSS pero hay que
reconocer que aunque esto puede no ser preventivo en naturaleza, es útil cuando el
código no se puede arreglar (como en el caso de un componente de terceros).

Referencias de objetos directos inseguras

Un defecto de referencia de objeto directo inseguro es aquel en el que un usuario no


autorizado o El proceso puede invocar la funcionalidad interna del software
manipulando parámetros y otros valores de objeto que hacen referencia
directamente a esta funcionalidad. Dejar Echemos un vistazo a un ejemplo para
elaborar esto. Una aplicación web está diseñada para pasar el nombre del usuario
que inició sesión en texto sin cifrar como el valor de la clave "nombre de usuario"
e indicar si el usuario que ha iniciado sesión es administrador o no, pasando el valor
a la clave "isAdmin", en la cadena de consulta de la URL como se muestra en la
Figura 4.10.

Tras la carga de la página, esta página lee el valor de la clave del nombre de
usuario de la cadena de consulta y muestra información sobre el usuario cuyo
nombre fue pasado y lo muestra en la pantalla. También expone las opciones del
menú administrativo si el valor isAdmin es 1. En nuestro ejemplo, la información
sobre "reuben" será mostrada en la pantalla. También vemos que Reuben no es un
administrador como está indicado por el valor de la clave isAdmin. Sin la
autenticación adecuada y controles de autorización, un atacante puede cambiar el
valor de la clave de nombre de usuario de "reuben" a "jessica" y ver información
sobre Jessica. Además por manipular el valor de la clave isAdmin de 0 a 1, un no
administrador puede obtener acceso a la funcionalidad administrativa cuando la
aplicación web sea susceptible de un defecto de referencia de objeto directo
inseguro.

Tales fallas pueden ser seriamente perjudiciales para el negocio. Divulgación de


datos, omisión de controles de autorización, autenticación y escalado de privilegios,
y el acceso restringido a los recursos son algunos de los impactos más comunes
cuando esta falla es explotada. Esto también se puede aprovechar para realizar
otros tipos de ataques, incluidos los ataques de inyección y secuencias de
comandos.

El control más eficaz contra ataques de referencia de objetos directos inseguros es


evitar exponer la funcionalidad interna del software utilizando un objeto directo
referencia que se puede manipular fácilmente. Los siguientes son algunos
estrategias que se pueden tomar para lograr este objetivo:

■ Utilice una referencia de objeto indirecta mediante un índice del valor o un mapa
de referencia para que se represente la manipulación directa de parámetros inútil a
menos que el atacante también sepa cómo se asigna el parámetro a la
funcionalidad interna.
■ No exponga objetos internos directamente a través de URL o parámetros de
formulario al usuario final.
■ Enmascarar o proteger criptográficamente (cifrar / hash) expuestos parámetros,
especialmente pares clave-valor de cadenas de consulta.
■ Valide la entrada (cambio en el valor del objeto / parámetro) para garantizar que el
cambio está permitido según la lista blanca.
■ Realizar controles de acceso múltiple y verificaciones de autorización cada vez
que se cambia un parámetro, de acuerdo con el principio de mediación completa. Si
se debe utilizar una referencia de objeto directa, es importante asegurarse de que el
usuario esté autorizado antes de usarlo.
■ Utilice RBAC para hacer cumplir los roles en los límites apropiados y reducir
superficie de ataque al mapear roles con los datos y la funcionalidad. Esto protegerá
contra los atacantes que intentan atacar a los usuarios con un rol diferente
(autorización vertical) pero no contra los usuarios que tienen el mismo rol
(autorización horizontal)
■ Asegurarse de que exista un RBAC basado en el contexto y el contenido.

Las revisiones de código manual y las pruebas de manipulación de parámetros se


pueden utilizar para detectar y abordar fallas inseguras de referencia de objetos
directos. Herramientas automatizadas a menudo no detectan referencias directas a
objetos inseguros porque no son conscientes de qué objeto requiere protección y
cuáles son los valores seguros o inseguros.

Mala configuración de seguridad

Además de parchear el sistema operativo con actualizaciones/revisiones de


seguridad, es de vital importancia para fortalecer las aplicaciones y el software que
se ejecutan sobre estos sistemas operativos. El endurecimiento de las aplicaciones
de software implica determinar los ajustes de configuración necesarios y correctos y
la arquitectura del software para ser seguro por defecto. Analizamos el
endurecimiento del software con más detalle en el capítulo de implementación,
operaciones, mantenimiento e implementación de software. En este capítulo,
aprenderemos principalmente sobre las configuraciones erróneas de seguridad que
puede hacer que el software sea susceptible a ataques. Estas configuraciones
incorrectas pueden ocurrir en cualquier nivel de la pila de software y conducen
desde la divulgación de datos hasta el sistema total compromiso. Algunos de los
ejemplos comunes de errores de configuración de seguridad incluir:

■ Faltan parches de software y sistema operativo.


■ Falta de controles defensivos del perímetro y del host, como firewalls, filtros, etc.
■ Instalación de software con cuentas y configuraciones predeterminadas.
■ Instalación de la consola administrativa con configuración predeterminada
ajustes.
■ Instalación o configuración de servicios, puertos y protocolos, páginas no
utilizadas y archivos y directorios desprotegidos
■ No deshabilitar la lista de directorios en el servidor.
■ No configurar explícitamente el manejo de errores y excepciones que puede dar
lugar a la divulgación de la aplicación e implementación internas arquitectura a
través de seguimientos de pila y mensajes de error detallados.
■ Dejando atrás las aplicaciones de muestra, que tienen más probabilidades de ser
inseguro con fallas de seguridad, después de la instalación.
■ Implementar aplicaciones y sistemas de sistemas estrechamente acoplados.

Los controles efectivos contra problemas de mala configuración de seguridad


incluyen elementos que diseñan, desarrollan, implementan, operan, mantienen y
eliminan software de manera confiable, de manera resiliente y recuperable. Las
recomendaciones principales incluyen:

■ Cambiar los valores de configuración predeterminados.


■ Después de la instalación.
■ Eliminación de servicios y procesos innecesarios o innecesarios.
■ Establecer y mantener una configuración del nivel mínimo de seguridad que es
aceptable. Esto se conoce como el mínimo línea de base de seguridad (MSB).
■ Establecer un proceso que endurezca (bloquee) el sistema operativo y el
aplicaciones que se ejecutan sobre él. Preferiblemente, esto debe ser un proceso
automatizado utilizando el MSB establecido para asegurar que haya no hay errores
de usuario.
■ Establecer un proceso de parcheo controlado.
■ Establecer un proceso de escaneo para detectar e informar automáticamente en
software y sistemas que no cumplan con los requisitos establecidos MSB.
■ Manejo de errores mediante redireccionamientos y mensajes de error de manera
explícita que el incumplimiento de cualquier configuración incorrecta no da lugar a la
divulgación de más información de la necesaria.
■ Eliminar las aplicaciones de muestra de los sistemas de producción después de la
instalación.
■ Implementar aplicaciones y sistemas que tienen una conexión débil y arquitectura
altamente cohesiva, de modo que fallas de seguridad en la dependencia Los
componentes tienen un impacto mínimo en la aplicación general o sistema.

Exposición de datos sensibles

Sin los controles de confidencialidad adecuados, el software puede filtrarse


información sobre su configuración, estado y composición interna que el atacante
puede utilizar para robar información o lanzar más ataques. Porque los atacantes
usualmente tienen el beneficio del tiempo y pueden optar por atacar a voluntad, por
lo general pasan la mayor parte de su tiempo en actividades de reconocimiento
recolectando información sobre el software en sí.

Algunas de las razones principales de la exposición de datos sensibles incluyen:

■ Protección de datos en movimiento insuficiente


■ Protección de datos en reposo insuficiente y
■ Ingeniería social electrónica

Protección insuficiente de datos en movimiento

Monitorear el tráfico de la red mediante un rastreador pasivo es un medio común por


el cual los atacantes roban información cuando los datos están en movimiento (en
tránsito).

Aprovechamiento de la seguridad de la capa de transporte (SSL / TLS) y / o la capa


de red (IPSec) Las tecnologías aumentan la protección de seguridad del tráfico de la
red. Es insuficiente simplemente usar SSL / TLS sólo durante el proceso de
autenticación, como se observa para ser el caso de la mayoría de software /
aplicaciones. Cuando un usuario está autenticado a un sitio web a través de un
canal cifrado, por ejemplo, ​https://www.mybank.com y luego, inadvertidamente o
intencionalmente, va a su enlace de texto sin cifrar, es decir, http://
www.mybank.com​ con poco esfuerzo ahora se puede observar la cookie de sesión
por un atacante que está monitoreando la red. Esto se conoce como Surf Ataque de
levantamiento. A menudo se produce una falta o una protección insuficiente de la
capa de transporte en una violación de la confidencialidad divulgando datos. Se
sabe que los ataques de phishing toman ventaja de esto. También puede provocar
el secuestro de sesiones y ataques de repetición, una vez que el atacante determina
la cookie de sesión de la víctima autenticada.

La protección de la capa de transporte, como SSL, puede mitigar la divulgación de


información confidencial información cuando los datos se atraviesan en el cable,
pero este tipo de la protección no previene completamente los ataques MITM, a
menos que la protección es de principio a fin. En el caso de la arquitectura web de 3
niveles, la protección de la capa de transporte debe ser del cliente al servidor web y
del servidor web al servidor de base de datos. No tener protección de capa de
transporte de extremo a extremo como se muestra en la Figura 4.11 puede conducir
a MITM y ataques de divulgación en las áreas que carecen de él.

Además, cuando se utilizan certificados digitales para garantizar la confidencialidad,


integridad, autenticidad y no repudio, deben ser protegidos, debidamente
configurados y no caducados para que no se falsifiquen. Cuando los certificados son

los ataques de suplantación de identidad, MITM y phishing son habituales. Es digno


de mención discutir en este contexto, la configuración incorrecta de certificados o el
uso de certificados caducado hacer que el navegador advierta al usuario final, pero
con la familiaridad del usuario para aceptar mensajes de advertencia del navegador,
sin leer realmente lo que están aceptando, este El mecanismo de protección del
navegador se vuelve débil o inútil. Educación del usuario para no aceptar
certificados caducados o similares y pueden aparecer mensajes de advertencia del
navegador muy útiles para cambiar este comportamiento y aumentar la seguridad
del software.

Protección insuficiente de datos en reposo

No cifrar los datos que se transmiten (datos en movimiento) es un problema


importante, pero proteger los datos almacenados (datos en reposo) contra
vulnerabilidades criptográficas es un desafío igualmente abrumador. En muchos
casos, los esfuerzos para proteger los datos en movimiento se niegan cuando los
mecanismos de protección de datos en reposo son inadecuados o inseguros.

Las fuentes principales de protección insuficiente de datos en reposo incluyen:

■ Almacenamiento local
■ Configuración del navegador
■ caché
■ Copias de seguridad, registros y archivos de configuración
■ Comentarios en código
■ Secretos codificados en código
■ Excepciones no controladas y mensajes de error
■ Almacenes de datos de backend

Almacenamiento local: la protección insegura de datos en reposo puede ser


manifestación de amenazas de divulgación. No solo es importante almacenar datos
confidenciales en forma protegida, pero la ubicación de almacenamiento debe ser
tener en cuenta también, al almacenar datos confidenciales o privados o ajustes de
configuración. Los avances en tecnologías están haciendo el almacenamiento local
más factible. Tradicionalmente, en tecnologías HTML, el almacenamiento en el
cliente localmente se limitaba a cookies y objetos flash que estaban muy restringido
en el espacio de almacenamiento. Sin embargo, ahora con HTML5, uno puede
almacenar datos localmente en el cliente sin la restricción de espacio como fue el
caso de las cookies. Además, a diferencia del caso de las cookies, con cada
solicitud al servidor, los datos de almacenamiento local no se devuelven y adelante.
El almacenamiento local trae consigo los beneficios de tener más espacio de
almacenamiento para almacenar datos localmente y clasificación de datos
minimizada entre el cliente y el servidor.

Dado que se puede acceder fácilmente a los datos almacenados en el lado del
cliente y modificado usando scripts (por ejemplo, Javascript, VBScript, etc.), el
almacenamiento local también representa una amenaza para la seguridad. Además,
las aplicaciones móviles suelen almacenar datos (incluidos los datos sensibles) en
el dispositivo cliente y son susceptibles a ataques de inyección del lado del cliente.

Configuración del navegador:​ directivas y encabezados incorrectos del navegador


proporcionado por o enviado al navegador puede ser revelado usando sniffers y
alterado. El historial del navegador se puede robar usando la hoja de estilo en
cascada (CSS) hacks con o sin JavaScript o mediante técnicas llamadas
almacenamiento en caché del navegador. La información sobre los sitios que ha
visitado un usuario puede ser robada a un usuario.

Caché: aunque el caché se puede utilizar para mejorar significativamente el


rendimiento y experiencia del usuario, la información confidencial si se almacena en
caché puede ser divulgada, violando la confidencialidad.

Copias de seguridad, registros y archivos de configuración: los atacantes


suelen buscar archivos de respaldo y no referenciados, archivos de registro y
archivos de configuración que inadvertidamente se implementan o instalan en el
sistema. Estos archivos pueden potencialmente tener información sensible que es
muy útil para un atacante cuando intentan explotar el software.

Comentarios en el código: los desarrolladores generalmente consideran que


documentar sus código como una actividad no esencial, pero dado que en su
mayoría son necesarios para hacerlo, recurren a comentar su código en línea como
comentarios. Sin la educación y la formación adecuadas, estos comentarios en el
código pueden
revelar información más sensible de la necesaria. Algunos ejemplos de la
información confidencial en los comentarios incluye conexión a la base de datos
cadenas, rutinas de validación, producción y datos de prueba, producción y cuentas
de prueba y lógica empresarial. La figura 4.12 muestra un ejemplo de código que
tiene información sensible en sus comentarios.

Secretos codificados en código: uno de los problemas de seguridad más


comunes detectado en revisiones de código es la existencia de secretos
desprotegidos como contraseñas o claves, codificadas en el propio código. Cuando
estos secretos son no protegidos criptográficamente y / o usando el acceso
apropiado controles, pueden estar expuestos dando como resultado una divulgación
seria amenazas.

Excepciones no controladas y mensajes de error:​ cuando se no se maneja


adecuadamente, la información sensible, incluida la interna, la estructura del
software se puede filtrar a un atacante.

Almacenes de datos backend: datos que se conservan en un almacén de datos


backend como una base de datos o un directorio debe almacenarse en forma
protegida un concepto erróneo común que existe en muchas arquitecturas de
aplicaciones es que confían en la protección de datos en el cable (cuando los datos
están en tránsito) para asegurar la confidencialidad. Protección de datos en
movimiento, es decir cubierto con más detalle posteriormente, protege contra datos
sensibles exposición cuando los datos se transmiten pero no cuando se almacenan
a menos que los datos en sí estén protegidos. Datos confidenciales en almacenes
de datos de backend debe almacenarse en forma protegida.

Ingeniería Social Electrónica

No todas las amenazas de divulgación de datos están relacionadas con la


aplicación. La confianza humana puede ser explotado para revelar información
sensible y también mediante ingeniería social técnicas como:

■ Suplantación de identidad
■ Pharming
■ Vishing
■ SMSishing
Phishing,​ que es un método para engañar a los usuarios para que envíen sus
información personal utilizando medios electrónicos como correos electrónicos
engañosos y sitios web, va en aumento. Se cree que el término "phishing" tiene sus
raíces en el uso de señuelos electrónicos sofisticados para pescar información
personal de la víctima (financiera, de inicio de sesión y contraseñas, etc.). Esta
forma de ingeniería social electrónica está tan desenfrenada en la actualidad
informática empresarial de la que incluso las grandes organizaciones han caído.
Aunque estos señuelos electrónicos sofisticados generalmente se dirigen a usuarios
en masa, también pueden apuntar a un solo individuo y cuando este es el caso, se
conoce comúnmente como "spear phishing". Con la sofisticación de tales ataques
engañosos para revelar información, los atacantes han llegado con una variante de
phishing, llamada Pharming.

Pharming es una práctica de estafa en la que se instala código malicioso en un


sistema o servidor que redirecciona a los usuarios a sitios web fraudulentos sin el
conocimiento o consentimiento del usuario. También se le conoce como "Phishing
sin señuelos". A diferencia del phishing en el que los usuarios individuales que
reciben el señuelo de phishing (generalmente en forma de correo electrónico) son
objetivos, en el pharming un gran número de usuarios puede ser victimizado como
el ataque no requiere acciones individuales del usuario, sino sistemas que pueden
estar comprometido. El pharming a menudo funciona mediante la modificación de la
archivos de host del sistema que redirigen a los usuarios a un sitio web fraudulento
incluso si el usuario escribe la dirección web correcta. Otra forma popular en la que
las obras de pharming, que son aún más peligrosas, se conocen como dominio
envenenamiento del sistema de nombres (DNS). En el pharming de
envenenamiento del DNS ataque, la tabla DNS en el servidor se modifica para
señalar a fraudulentos sitios web incluso cuando se realiza la solicitud a los
legítimos. Con envenenamiento de DNS, no es necesario alterar el sistema local del
usuario individual archivos de host porque la modificación (explotada) se realiza en
el servidor lado y todos aquellos que soliciten recursos de ese servidor ahora serán
posibles víctimas sin su conocimiento o consentimiento. La divulgación de la
información personal es a menudo el resultado y, en algunos casos, esto aumenta al
robo de identidad.

Con la telefonía de voz sobre IP (VoIP) en aumento, los ataques de phishing tienen
una nueva variante llamada Vishing. Vishing se compone de dos palabras, "Voz" y
"phishing" y es la actividad criminal fraudulenta en la que un atacante roba
información confidencial utilizando ingeniería social engañosa técnicas en redes
VoIP.

SMSishing (también denominado a veces SMishing) proviene de acuñando las


palabras "Servicio de mensajes cortos (SMS)" y "phishing". Con el aumento de la
informática móvil, esta variante de redes sociales se observa que los ataques de
ingeniería están ganando prevalencia. En SMSishing ataques, los atacantes envían
un mensaje a la víctima, como si se originara de una fuente confiable (como el
banco de la víctima). El mensaje SMS por lo general, tiene un mensaje para la
víctima, que indica que debe devolver la llamada para verificar alguna información,
con sentido de urgencia. Cuando la víctima devuelve las llamadas, por lo general
escuchan un mensaje grabado solicitando información personal identificable y
sensible (como su información de la cuenta bancaria y contraseña o PIN asociado).
Cuando dicha información se proporciona el mensaje está configurado para
agradecer a la víctima y luego se desconecta automáticamente.

Como se mencionó anteriormente, la vulnerabilidad principal en electrónica los


ataques de ingeniería social no son una debilidad en la tecnología, pero es
confianza humana. Debilidades secundariamente explotables, como la falta de ACL
a sistemas host y servidores, falta de protección contra software espía que modificar
la configuración y las debilidades en el código del software también puede resultar
en divulgación de información significativa. Los phishers y pharmers intentan
explotar estas debilidades para enmascarar y ejecutar su phishing / estafas de
pharming.

Para mitigar y prevenir problemas de exposición de datos confidenciales, es


importante asegurarse de que los controles de seguridad adecuados, como los que
se enumeran a continuación, estén diseñados e implementados.

■ Para evitar la accesibilidad de los datos almacenados en cookies desde scripts,


puede establecer la marca HTTPOnly, que indica a los navegadores que no permitir
el acceso de Javascript a las cookies. Sin embargo, este HTTPOnly La opción de
marca no está disponible para proteger el contenido de almacenamiento local como
local el almacenamiento por diseño está destinado a ser accedido mediante scripts.
Así que con almacenamiento local, el mejor enfoque para garantizar la
confidencialidad evite almacenar información confidencial o privada en el
almacenamiento local.
■ Uso del modo "Navegación privada" en navegadores y otros complementos o
extensiones que no almacenan en caché las páginas visitadas. Configurar los
navegadores para no guardar el historial y borrar todas las visitas a la página al
cerrar el navegador.
■ Desactive las funciones de autocompletar en los formularios del navegador que
recopilan información delicada.
■ Desactive el almacenamiento en caché de datos confidenciales. Sin embargo, si
se necesitan datos sensibles almacenar en caché, luego cifrar el caché y / o
establecer el caché explícitamente tiempos de espera (a veces denominados
ventanas de caché).
■ No implemente archivos de respaldo en el sistema de producción. Por desastre
Con fines de recuperación, a veces el archivo de respaldo lo implementa cambiando
el nombre de la extensión del archivo a una extensión .bak o .old. Atacantes puede
adivinar y buscar con fuerza estos archivos y sin los controles de acceso en su
lugar, la información en estos archivos puede ser potencialmente divulgada.
■ Los servidores deben reforzarse para que sus archivos de registro estén
protegidos.
■ Las secuencias de comandos de instalación y los registros de cambios deben
eliminarse de sistemas de producción y almacenados en un entorno de no
producción si no es necesario para que el software funcione.
■ El comentario del código debe explicar qué hace el código, preferiblemente para
cada función, pero no debe revelar ninguna información sensible o específica
información la revisión del código no debe ignorar la revisión de comentarios en el
código.
■ Las herramientas de análisis de código estático se pueden aprovechar para
buscar API que son conocidos por filtrar información.
■ Si no necesita mantener datos confidenciales, no almacene los recopilados datos
después de su procesamiento. Si necesita almacenar los datos (datos en reposo),
luego protéjase cerrándola o cerrándola. Si los datos están encriptados, mantenga
la clave para descifrar los datos separados de los datos en sí se utiliza criptografía
asimétrica para el cifrado, la clave pública se puede utilizar en la interfaz para cifrar
los datos y los asociados La clave privada se puede configurar en el almacén de
datos de backend para descifrar los datos. Depender únicamente del cifrado
automático de la base de datos backend tanto para el cifrado como para el
descifrado no evita la inyección ataques si los datos son hash, use un valor de sal
para mitigar el arco iris agrietamiento de la mesa.
■ Las contraseñas almacenadas deben tener hash, pero si tiene que recurrir a
cifrarlos y luego aprovechar un algoritmo criptográfico que diseñado
específicamente para protección con contraseña. Ejemplos de contraseña los
algoritmos de protección incluyen bcrypt, PBKDF2 o scrypt.
■ Implementar la seguridad de canal de un extremo a otro para proteger el canal
mediante SSL / TLS o IPSec. Sin embargo, es importante señalar que aunque
puede parecer que las comunicaciones seguras (usando SSL / TLS o IPSec) es una
defensa eficaz contra la protección insuficiente de la capa de transporte ataques,
una simple mala configuración o implementación parcial puede hacer que todos los
demás mecanismos de protección sean ineficaces. La defensa contra este tipo de
ataques es la protección criptográfica de datos (cifrado o hash) de modo que,
independientemente de si el los datos se agrupan a través de canales de
comunicación seguros o no, todavía está protegido.
■ Evite el uso de SSL mixto cuando determinadas páginas estén protegidas
mediante SSL mientras que otros o no, porque esto puede dar lugar a la divulgación
de cookies de sesión de páginas que no lo son. Redirigir páginas no seguras (por
ejemplo, http) para protegerlas (por ejemplo, https).
■ Asegúrese de que el indicador de seguridad de la cookie de sesión esté
configurado. Esto hace que cookie del navegador que se enviará sólo a través de
canales cifrados (HTTPS y no HTTP) mitigando el ataque de Surf Jacking.
■ Proteja criptográficamente los datos en reposo y los datos en movimiento y su uso
algoritmos criptográficos comprobados y probados o funciones hash, cumple con
FIPS 140-2 para las necesidades de protección criptográfica.
■ Configurar correctamente certificados digitales que no hayan vencido y
no revocado.
■ Eduque a los usuarios para que no pasen por alto los mensajes de advertencia o
acepten certificados similares y avisos de phishing.
■ La concienciación y la educación del usuario es la mejor defensa contra los
estafas de ingeniería social. Además, control de SPAM, deshabilitando de enlaces
en correos electrónicos y clientes de mensajería instantánea (IM), visualización
correos electrónicos en formato no HTML, protección de la capa de transporte (SSL/
TLS), complementos de filtro de phishing y estrategias ofensivas como la dilución y
la eliminación son otras salvaguardas y contramedidas contra ataques de phishing y
pharming. Dilución, también conocida como "Spoofback", envía información falsa y
defectuosa al phisher con la intención de diluir la información real de que el atacante
está abordamiento. La eliminación, por otro lado, implica traer activamente el sitio
web de phishing / pharming como un medio para contener la exposición, pero esto
debe reducirse con la orientación legal adecuada. Para mitigar las estafas de
Vishing, no confíe en el identificador de llamadas, ya que puede ser fácilmente
falsificado y también verificar la persona que llama en el otro extremo de la línea.
Para mitigar las estafas de mensajes de texto, desactive los servicios de mensajes
de texto, si no es requerido. No devuelva la llamada al número que le piden llamar
en el mensaje en sí y notificar a las autoridades apropiadas cuando se sospecha un
ataque. "No confíe y verifique" siempre que tenga dudas.

■ Los datos sensibles y el acceso administrativo deben basarse en el principio de


separación de deberes / privilegios para reducir el fraude de información
privilegiada. No olvide incluir personal interno que tenga privilegios acceso a los
datos (por ejemplo, arquitectos de datos, administradores de bases de datos, etc.)
como parte de su perfil de amenaza.

Faltan comprobaciones de nivel de función

Una de las debilidades más fáciles de explotar en muchas aplicaciones es la falla


para restringir el acceso a funcionalidades o URL privilegiadas. Esto también se
conoce a veces como ataques de acceso forzado. En algunos casos, la protección
se proporciona y gestiona mediante ajustes de configuración y comprobaciones de
código. En la mayoría de los casos, la única protección que ofrece el software es no
presentar la función o la URL de la página a un usuario no autorizado (o anónimo).
Este tipo de seguridad por la oscuridad ofrece poca o ninguna protección contra un
atacante determinado y hábil quién puede adivinar y / o navegar a la fuerza a estas
ubicaciones de funciones y acceder funcionalidad no autorizada. Además, adivinar
las URL es más fácil si el patrón o esquema de nomenclatura de URL es predecible,
predeterminado y / o no se modifica Incluso si la funcionalidad o URL está oculta y
nunca se muestra a un usuario no autorizado usuario, sin verificación de control de
acceso y autenticación adecuada, funciones ocultas y las URL se pueden revelar e
invocar sus funciones de página. Adicionalmente, las herramientas automatizadas
no suelen estar configuradas para detectar comprobaciones de nivel de función
faltantes.

Las páginas web que brindan funcionalidad administrativa son los principales
objetivos para tales ataques de fuerza bruta, pero cualquier función o página puede
ser explotada si no está protegido adecuadamente. Por tanto, es imperativo verificar
la protección (controles de autenticación y autorización) de todas y cada una de las
funciones y URL pero esto puede ser una tarea desalentadora, cuando se realiza
manualmente, especialmente si la aplicación es compleja y compuesta de muchas
funciones y páginas. El diseño Los principios de mediación completa y los
mecanismos menos comunes deben ser diseñados en la aplicación.

Control de acceso basado en roles (RBAC) de funciones y URL que niega el acceso
por defecto, además de requerir concesiones explícitas a usuarios y roles,
proporciona cierto grado de mitigación contra comprobaciones de nivel de función
faltantes y falta de restringir los ataques de acceso a URL. Cuando las
comprobaciones de control de acceso se implementan utilizando ajustes de
configuración o en el código, es mejor no codificar estas verificaciones dentro del
código de la aplicación y utilizar un control de acceso basado en derechos
mecanismo para que estos controles pueden actualizarse y auditarse de una
manera relativamente fácil.

En situaciones en las que el software está diseñado para aceptar un parámetro de


"acción" para invocar una función o la propia "URL" como parámetro antes de
otorgar acceso (como en el caso de comprobar el Origen del Remitente), el punto en
el que el acceso la verificación de control también debe implementarse
cuidadosamente. Acceso a las comprobaciones de control en el flujo de trabajo
deben realizarse contra el estándar canónico formas de las funciones y / o URL, lo
que significa que la URL se decodifica y canonicalizado en el formulario estándar
antes de que se verifique la solicitud de ese recurso. La ofuscación de URL
proporciona cierta defensa contra los atacantes que intentan navegación forzada
adivinando la URL. Además en los casos en que la página web las pantallas se
basan en un flujo de trabajo, asegúrese de que antes de que se sirva la página se
muestran, verificaciones adecuadas no solo para la autorización sino también para
que las condiciones estatales se cumplan. Incluir en la lista blanca funciones y URL
válidas y validar archivos de biblioteca que se mencionan otros controles de
prevención y mitigación recomendados.

No confíe en las comprobaciones basadas en el cliente, pero siempre realice un


acceso basado en roles controles de control en el backend (lado del servidor).
Implementar verificaciones de control de acceso en la capa de lógica empresarial
(modelo) o capa de controlador para que la presentación (ver) control de acceso a la
capa, que se basa en no mostrar la funcionalidad o página al usuario, no puede ser
forzado.

No almacene en caché páginas web que contengan información confidencial y


cuando estos se solicitan páginas, asegúrese de comprobar que las credenciales de
autenticación y los derechos de acceso del usuario que solicita el acceso se
verifican y validan antes sirviendo la página web. Marcos de autorización como la
autorización JAAS marco y OWASP ESAPI se pueden aprovechar.
Falsificación de solicitudes entre sitios (CSRF)

Aunque el ataque Falsificación de solicitud entre sitios (CSRF) es único en el


sentido que requiere que un usuario ya esté autenticado en un sitio y posea el token
de autenticación, su impacto puede ser devastador y se clasifica legítimamente
dentro de los cinco principales ataques de seguridad de aplicaciones tanto en
OWASP Top 10 como así como el CWE / SANS Top 25. Los sitios web más
populares, como ING Direct, han demostrado que NYTimes.com y YouTube son
susceptibles a esto.

En CSRF, un atacante enmascara (falsifica) una solicitud HTTP maliciosa como uno
legítimo y engaña a la víctima para que presente esa solicitud. Porque la mayoría de
los navegadores incluyen automáticamente solicitudes HTTP, es decir, las
credenciales (cookies de sesión de usuario, información de autenticación básica,
direcciones IP de origen, credenciales de dominio de Windows) asociado con el
sitio, si el usuario ya autenticado, el ataque logrará realizar lo que el ataque diseñó
solicitud para hacer. Estas solicitudes falsificadas se pueden enviar mediante
enlaces de correo electrónico, etiquetas de imagen de cero bytes (imágenes cuya
altura y ancho son de 0 píxeles cada una de modo que la imagen es invisible para el
ojo humano), almacenada en un iFrames (CSRF almacenado),URL susceptibles a
Clickjacking (donde la URL es secuestrada y al hacer clic en una URL que parece
inocua y legítima en realidad da como resultado hacer clic en el URL maliciosa que
se oculta debajo) y redirecciones XSS. Formas que invocan la función de cambio de
estado son los principales objetivos de CSRF. CSRF también es conocido por varios
otros nombres, incluidos XSRF, Session riding attack, sea surf attack, enlace hostil,
ataque de automatización y falsificación de referencias entre sitios. El ataque el flujo
en un ataque CSRF es el siguiente:

1. El usuario se autentica en un sitio web legítimo y recibe el token de autenticación


asociado con ese sitio.
2. Se engaña al usuario para que haga clic en un enlace que tiene un código
malicioso falsificado. Solicitud HTTP que se realizará contra el sitio en el que se
encuentra el usuario ya autenticado.
3. Dado que el navegador envía la solicitud HTTP maliciosa, el credenciales de
autenticación, esta solicitud navega o se superpone a el token autenticado y realiza
la acción como si fuera un acción legítima solicitada por el usuario (ahora la víctima)
Aunque es necesario un token previamente autenticado para que este ataque tenga
éxito, las acciones hostiles y el daño que pueden causar los ataques CSRF pueden
ser extremadamente peligroso, limitado solo a lo que la víctima ya está autorizada a
hacer. Omisión de autenticación, compromiso de identidad y phishing son solo
algunos ejemplos de impacto de ataques CSRF exitosos. Si el usuario es un usuario
privilegiado, entonces el compromiso total del sistema es una posibilidad. Cuando
CSRF se combina con XSS, el impacto puede ser extenso. Los gusanos XSS que
se propagan y afectan a varios sitios web dentro de un corto período de tiempo
suelen tener un ataque CSRF que los alimenta. La potencia del CSRF aumenta aún
más por el hecho de que las acciones hostiles forzadas aparecen como acciones
legítimas (ya que viene con un token autenticado) y por lo tanto, puede pasar
totalmente desapercibido. Se puede utilizar la herramienta OWASP CSRFTester
para generar casos de prueba para demostrar los peligros de las fallas CSRF.

La mejor defensa contra CSRF es implementar el software para que no depende de


las credenciales autenticadas que se envían automáticamente por el navegador. Los
controles se pueden clasificar ampliamente en controles de usuario y
desarrolladores control

Las siguientes son algunas estrategias defensivas que los usuarios pueden emplear
para prevenir y mitigar los ataques CSRF:

■ No guarde el nombre de usuario / contraseña en el navegador.


■ No marque la opción "recordarme" en los sitios web.
■ No utilice el mismo navegador para navegar por Internet y acceder sitios web
sensibles al mismo tiempo, si accede a ambos desde la misma máquina.
■ Leer correos electrónicos estándar en texto sin formato. Ver correos electrónicos
en texto sin formato, el formato muestra al usuario el enlace real en el que se está
engañando al usuario para hacer clic renderizando los enlaces HTML maliciosos
incrustados en el enlace textual real. La figura 4.13 muestra cómo es un correo
electrónico de phishing se muestra a una víctima potencial cuando el cliente de
correo electrónico está configurado para leer correo electrónico en formato HTML y
en formato de texto sin formato.
■ Cierre la sesión explícitamente después de usar una aplicación web.
■ Utilice extensiones de navegador del lado del cliente que mitiguen los ataques
CSRF. Un ejemplo de esto es CSRF Protector, que es un complemento del lado del
cliente extensión para el navegador Mozilla Firefox.

Las siguientes son algunas estrategias defensivas que pueden ser empleadas por
desarrolladores para prevenir y mitigar los ataques CSRF:

■ El control defensivo del desarrollador más eficaz contra CSRF es para


implementar el software para usar un token específico de sesión único (llamado
nonce) que se genera de forma aleatoria, no predecible, de manera no adivinable y /
o secuencial. Tales tokens deben ser únicos por función, página o sesión en
general.
■ CAPTCHA (prueba de Turing pública completamente automatizada para
diferenciar a las computadoras y a los humanos) se puede utilizar para establecer
identificadores de token específicos por sesión. CAPTCHA no proporciona defensa
infalible pero aumenta el factor de trabajo de un atacante y evita la ejecución
automatizada de scripts que pueden explotar CSRF vulnerabilidades.

■ La exclusividad de los tokens de sesión debe validarse en el servidor y no


depender únicamente de la validación basada en el cliente.
■ Utilice métodos POST en lugar de solicitudes GET de datos confidenciales
transacciones y transacciones privilegiadas y de cambio de estado, junto con con
generación y uso de identificadores de sesión aleatorios.
■ Utilice una cookie de doble envío. Cuando un usuario visita un sitio, el sitio
primero genera un valor pseudoaleatorio criptográficamente fuerte y lo establece
como una cookie en la máquina del usuario. Cualquier solicitud posterior del sitio
debe incluir este valor pseudoaleatorio como un formulario valor y también como un
valor de cookie y cuando la solicitud POST es validada en el lado del servidor, debe
considerar la solicitud válida, si y solo si el valor del formulario y el valor de la cookie
son iguales. Ya que un atacante puede modificar los valores del formulario pero no
los valores de las cookies según la política del mismo origen, un atacante no podrá
enviar correctamente un formulario a menos que sea capaz de adivinar el valor
pseudoaleatorio.
■ Verifique el origen de la solicitud en la etiqueta de URL de referencia antes
procesando la solicitud. Sin embargo, cuando se implementa este método, es
importante asegurarse de que las acciones legítimas no se vean afectadas. Si los
usuarios o proxies han inhabilitado el envío de la información de referencia por
motivos de privacidad, se puede denegar la funcionalidad legítima también es
posible suplantar la información de referencia usando XSS y así a defensa debe
estar en conjunto con otros controles del desarrollador como parte de una estrategia
de defensa en profundidad.
■ Para transacciones confidenciales, vuelva a autenticarse cada vez (como según el
principio de mediación completa).
■ Utilice la firma de transacciones para asegurarse de que la solicitud sea genuina.
■ Incorporar la funcionalidad de cierre de sesión automatizado basada en un
período de inactividad y cerrar la sesión del usuario cuando transcurra ese período
de tiempo.
■ Aproveche las herramientas de la industria que ayudan con la defensa CSRF.
OWASP CSRF Guard y el control de gestión de sesiones OWASP ESAPI
proporciona paquetes anti-CSRF que se pueden utilizar para generar, pasando y
usando un token único por sesión. Code Igniter que es un complemento del lado del
servidor para el marco PHP MVC es otro pozo ejemplo conocido de una herramienta
que ofrece protección CSRF.
■ Mitigar las vulnerabilidades XSS ya que la mayoría de las defensas CSRF se
pueden eludir utilizando scripts controlados por atacantes.

Uso de componentes vulnerables conocidos

Cuando los componentes existentes, como bibliotecas, frameworks, módulos, etc.,


se aprovechan dentro de la aplicación, se corre el riesgo de utilizar componentes
con vulnerabilidades que el desarrollador puede o no conocer. Esto es
particularmente más frecuente en software adquirido a través de la cadena de
suministro de software y en el desarrollo de software de fuente abierta, donde todos
los componentes de la aplicación de software no es desarrollada por personal, bajo
el estricto control de la compañía. Este problema se agrava porque la mayoría de
los componentes de software desarrollado usando proyectos de código abierto no
desarrolle parches de vulnerabilidad para corregir versiones anteriores, pero en su
lugar lanzan nuevas versiones con las correcciones de errores en ellas. Eso sin
embargo, debe reconocerse que este problema no se limita solo al código abierto
software. El uso de API obsoletas, inseguras y prohibidas también se incluye en
este categoría de ataque.

Aunque se podría argumentar que aprovechar los componentes existentes no


introducir nuevas vulnerabilidades, vulnerabilidades conocidas en estos
componentes pueden ser explotados, lo que puede tener consecuencias
desastrosas. No solo es la aplicación que utiliza estos componentes vulnerables
conocidos explotables, pero cada aplicación conectada y dependiente que
aprovecha estos componentes es susceptible también. Funciones vulnerables en
bibliotecas y marcos que pueden ser invocados directamente por el usuario son
relativamente más susceptibles de ser directamente explotados que los que se
envuelven con código personalizado y se utilizan más en una aplicación.

Para mitigar y prevenir ataques que explotan vulnerabilidades conocidas en


componentes, es mejor no utilizar bibliotecas y marcos con conocidos
vulnerabilidades que el desarrollador no escribió, pero esto puede no ser factible
debido a los impulsores del negocio. Cuando componentes que no fueron
desarrollados bajo su control se van a utilizar, entonces es importante asegurarse
de que los componentes, y sus versiones, incluidas las dependencias, no solo se
identifican primero (se conocen), pero también se mantienen actualizados. También
es recomendable monitorear las bases de datos de seguimiento de errores y listas
de divulgación de vulnerabilidades para determinar si su aplicación está en riesgo,
cuando se detecta una falla de seguridad en los componentes que ha aprovechado
dentro de su solicitud y divulgada al público. Finalmente, establecer políticas que
rigen el uso y la reutilización de los componentes, determinando la validez de las
licencias, es necesario el soporte de mantenimiento continuo y el final de la vida útil
de estos componentes para minimizar los impactos comerciales y de seguridad.

Redirecciones y reenvíos no validados

Redireccionamiento y reenvío de usuarios de una ubicación (página) a otra


explícitamente en el cliente o internamente en el lado del servidor (también conocido
como transferencia) no es infrecuente en aplicaciones. El redireccionamiento
generalmente se dirige a enlaces externos mientras reenvío de páginas internas de
objetivos los scripts también se pueden utilizar para redirigir a los usuarios desde
una ubicación de documento a otra como se muestra en la Figura 4.14.
En situaciones en las que la URL de destino se proporciona como un parámetro no
validado, un atacante puede especificar una URL maliciosa alojada en un sitio
externo y redirigir usuarios a ese sitio. Cuando un atacante redirige a una víctima a
un sitio que no es de confianza, es también conocido como Open Redirects. Una
vez que la víctima llega a la página maliciosa el atacante puede realizar phishing
para obtener información confidencial y personal. También pueden instalar malware
automáticamente o engañando a los usuarios para que hagan clic en enlaces de
instalación. Estos redireccionamientos y reenvíos no validados también pueden ser
utilizados por un atacante para eludir los controles y comprobaciones de seguridad.

Detectar si la aplicación es susceptible a redireccionamientos no validados o los


reenvíos pueden hacerse posibles realizando una revisión de código y
asegurándose de que la URL de destino es válida y legítima. Un servidor responde
a un cliente solicitud enviando un mensaje de respuesta HTTP que incluye en su
línea de estado el versión del protocolo, un código de éxito o error, un motivo (frase
textual), seguido de campos de encabezado que contienen información del servidor,
información de metadatos (recurso, payload) y una línea vacía para indicar el final
de la sección del encabezado y el cuerpo de carga útil (si está presente). Mirando
los códigos de respuesta HTTP manualmente invocando al servidor para que
responda o spidering el sitio web, se puede determinar redirecciona y reenvía. Los
códigos de respuesta HTTP de la serie 3XX (300-307) son los que se ocupan de la
redirección. El Apéndice C presenta y enumera brevemente los códigos de estado
HTTP / 1.1 y frases de motivo.

■ Evitar redireccionamientos y reenvíos (transferencias) si es posible


■ Utilice una URL de destino de la lista blanca a la que se pueda redirigir a un
usuario.
■ No permita que el usuario especifique la URL de destino (destino) como
parámetro y si es necesario por razones comerciales, valide el parámetro de URL de
destino antes de procesarlo.
■ Utilice un valor de índice para asignar a la URL de destino y utilice ese valor como
parámetro. De esta forma, la URL real o partes del La URL no se revela al atacante.
■ Diseñe el software para informar al usuario mediante un intermediario página,
especialmente si el usuario está siendo redirigido a un sitio externo eso no está bajo
tu control. Esta página intermedia debe informar y advertir al usuario que está
abandonando su sitio es preferible avisar al usuario de forma modal antes de
redirigirlo a el sitio externo.
■ Mitigar las vulnerabilidades de los ataques de scripts que se pueden utilizar para
cambiar la ubicación del documento.
Ataques de archivos

Los ataques contra el software también son frecuentes cuando los datos se
intercambian en archivos. En esta sección, cubriremos algunos de los ataques más
comunes que involucran archivos estos ataques incluyen:

■ Ejecución de archivos maliciosos


■ Travesías de caminos
■ El archivo incorrecto incluye
■ Descarga de código sin verificación de integridad

Cuando el software está diseñado e implementado para aceptar archivos como


entrada, la carga de archivos no validada y sin restricciones podría conducir a
graves compromisos del estado de seguridad del software. Cualquier característica
del software que utilice un objeto externo referencias (como URL y referencias del
sistema de archivos) y que permiten la carga de imágenes (.gif, .jpg, .png, etc.),
documentos (.docx, .xlsx, .pdf, etc.) y otros archivos, son fuentes potenciales de
vectores de ataque. Validación insuficiente e incorrecta puede conducir a la carga,
invocación y ejecución de código hostil y remoto arbitrario, instalaciones de rootkit y
compromiso completo del sistema. Toda la aplicación web Los frameworks son
susceptibles a la ejecución de archivos maliciosos si aceptan nombres de archivo o
archivos de los usuarios.

Los ataques de ejecución de archivos maliciosos pueden ocurrir de cualquiera de


las siguientes formas:

■ Aceptar nombres de archivo y archivos proporcionados por el usuario sin


validarlos.
■ No restringir archivos a tipos no ejecutables.
■ Carga de datos hostiles al sistema de archivos mediante la carga de imágenes.
■ El uso de transmisiones de audio o compresión (p. Ej., Zlib: // u ogg: //) que
permitir el acceso a recursos remotos sin la inspección de banderas y
configuraciones internas.
■ Usar envoltorios de datos y de entrada (como php: // input) que aceptan entrada
de la solicitud de datos POST en lugar de un archivo.
■ El uso de definiciones de tipos de documentos (DTD) hostiles que obligan al
analizador XML para cargar un DTD remoto y analizar y procesar el resultados.
En situaciones donde el software está diseñado para aceptar nombres de ruta y
ubicaciones de directorio del usuario final, sin los controles de seguridad adecuados,
atacantes pueden explotar las debilidades que les permiten navegar para atravesar
el lugar previsto rutas de archivo a directorios y archivos no deseados en el sistema
software susceptible a los ataques que utilizan la canonicalización de rutas de
archivo, como el uso de ".." o similar se sabe que las secuencias suelen ser víctimas
de ataques transversales.

Aunque los ataques a archivos no se limitan a ningún tipo de programación


lenguaje, lenguajes de programación como PHP que permite incluir archivos
remotos (RFI) donde el nombre del archivo se puede construir concatenando la
entrada proporcionada por el usuario usando API basada en archivos o flujos, son
particularmente vulnerables. Rompiendo el software en partes más pequeñas de un
programa (documento) y luego combinarlas en una gran programa (documento) es
una forma común de crear un programa.

Cuando la ubicación de las partes más pequeñas del programa está definida por el
usuario y puede ser influenciado por un usuario final, un atacante puede apuntar a
ubicaciones con archivos remotos y peligrosos y explotar el software.
Cuando descarga código (o archivos) sin verificar si el código está alterado, puede
provocar violaciones de seguridad muy graves y repercusiones. Un atacante puede
modifique el código antes de descargarlo. Incluso ubicaciones (sitios) que contienen
archivos que usted confía y descarga puede ser atacado y suplantado mediante la
suplantación de DNS o envenenamiento de caché, redirigiendo a los usuarios a las
ubicaciones de los atacantes. Esto es particularmente importante cuando las
actualizaciones de software se publican utilizando archivos de ubicaciones de
confianza, la descarga de código y archivos sin verificaciones de integridad puede
provocar la descarga de archivos que han sido alterados maliciosamente por un
atacante.

El escaneo automatizado se puede usar para determinar secciones en el código que


aceptan nombres de archivo y rutas de archivo, pero no son muy eficientes para
identificar la legitimidad de los parámetros que se utilizan en el archivo las
herramientas de análisis estático pueden ser útiles en determinar las API
prohibidas, pero no pueden garantizar que la validación adecuada está en su lugar.
Se recomienda la revisión manual del código para buscar ataques de archivos
vulnerabilidades.
Los controles que previenen y mitigan los ataques a archivos son necesarios para
garantizar que la seguridad del software al tratar con archivos y sus propiedades
asociadas es seguro.

Los siguientes son controles recomendados contra la ejecución de archivos


maliciosos ataques:

■Utilice una lista blanca de extensiones de archivo permitidas. Asegúrese de que el


cheque para la lista válida de nombres de archivos tenga en cuenta la distinción
entre mayúsculas y minúsculas del nombre del archivo.
■ Permita sólo una extensión para un nombre de archivo. Por ejemplo, “myfile.exe.
png ”no debería permitirse.
■ Utilice un mapa de referencia de objeto indirecto y / o un índice para los nombres
de archivo proteger criptográficamente el nombre del archivo interno mediante
salazón y hash de los nombres de los archivos puede evitar el descubrimiento por
fuerza bruta del archivo nombres.
■ Comprobación de contaminación explícita. La comprobación de manchas es una
característica de algunos lenguajes de programación como Perl y Ruby que protege
contra ataques maliciosos de ejecución de archivos. Suponiendo que todos los
valores proporcionados por el usuario pueden ser potencialmente modificados y no
confiables, cada variable que contiene valores proporcionados por un usuario
externo es comprobado para ver si la variable ha sido contaminada por un atacante
para ejecutar comandos peligrosos.
■ Genere automáticamente un nombre de archivo en lugar de utilizar el usuario
proporcionado uno.
■ Cargue los archivos en un entorno de ensayo reforzado e inspeccione los binarios
antes de procesarlos. La inspección debería cubrir más que solo el tipo de archivo,
tamaño, tipo de contenido MIME o atributo de nombre de archivo sino también
inspeccionar el contenido del archivo, ya que los atacantes pueden ocultar el código
en algunos segmentos de archivo que se ejecutarán.
■ Evite el uso de funciones de archivo y API basadas en flujos para construir
nombres de archivo.
■ Configure la aplicación para exigir los permisos de archivo adecuados uso de Java
Security Manager y la confianza parcial ASP.Net las implementaciones se pueden
aprovechar para proporcionar permisos de archivo seguridad.
■ Los siguientes son controles recomendados contra el cruce de rutas
ataques:
■ Utilice una lista blanca para validar las rutas y ubicaciones de archivos aceptables.
■ Limite los juegos de caracteres antes de aceptar archivos para su procesamiento
los ejemplos deben incluir permitir un solo "." carácter en el nombre del archivo y no
permitir separadores de directorio como "/" mitiga el cruce de rutas ataques.
■ Refuerce los servidores configurándose para que no permitan el directorio
navegación o contenidos.
■ Decodificar una vez y rutas de archivo canónicas a la representación interna para
que no se introduzcan entradas peligrosas después de las comprobaciones se
realizan. Utilice funciones de canonicalización integradas que canonicaliza el
nombre de la ruta eliminando las secuencias ".." y enlaces. Los ejemplos incluyen
realpath () (C, Perl, PHP), getCanonicalPath (Java), GetFullPath () (ASP.Net) y
abs_path () (Perl).
■ Utilice un mapeo de valores genéricos para representar valores reales internos
conocidos nombres de archivo y rechazar cualquier valor no configurado
explícitamente.

Los siguientes son controles recomendados contra archivos incorrectos que


incluyen ataques:

■ Almacenar archivos de biblioteca, inclusión y utilidad fuera de la raíz o del sistema


directorios. Usar una constante en un programa de llamada y verificar su existencia
en la biblioteca o archivo de inclusión es una práctica común para identificar
archivos aprobados o no.
■ Restrinja el acceso a archivos dentro de un directorio específico.
■ Limite la capacidad de incluir archivos de ubicaciones remotas.
■ Los siguientes son controles recomendados contra la descarga de código sin
ataques de verificación de integridad.
■ Utilice la verificación de integridad en el código descargado de ubicaciones
remotas. Los ejemplos incluyen hash, firma de código y auténtico de tecnologías.
Estos se pueden utilizar para validar criptográficamente la autenticidad del editor del
código y la integridad del código sí mismo. Hash del código antes de que se
descargue y validando el valor hash antes de procesar el código se puede utilizar
para determinar si el código ha sido alterado o no.
■ Para detectar ataques de suplantación de identidad de DNS, realice tanto en
avance como en retroceso búsquedas de DNS. Cuando se utiliza, tenga en cuenta
que esto es sólo una solución parcial, ya que no evitará la manipulación del código
en el sitio de alojamiento o cuando está en tránsito.
■ Cuando el código fuente no es desarrollado por usted o no está disponible, el uso
de herramientas de seguimiento para examinar la interacción del software con el
sistema operativo y la red se pueden utilizar para detectar problemas de integridad
del código. Algunos ejemplos de herramientas comunes incluyen depuradores de
procesos, sistemas servicios de seguimiento de llamadas y monitores de actividad
del sistema y proceso (archivo monitores, monitores de registro, internos del
sistema), rastreadores y protocolo analizadores.

Condición de carrera

Para que ocurran las condiciones de carrera, las siguientes tres propiedades deben
ser cumplidas.

1. Propiedad de concurrencia
2. Propiedad de objeto compartido y
3. Cambiar propiedad estatal

La propiedad de concurrencia significa que debe haber al menos dos subprocesos o


control flujos que se ejecutan al mismo tiempo la propiedad de objeto compartido
significa que los subprocesos ejecutando al mismo tiempo están accediendo al
mismo objeto, es decir, el objeto es compartido entre los dos flujos concurrentes.
Cambiar propiedad estatal significa que en al menos uno de los flujos de control
debe alterar el estado del objeto compartido. Solamente cuando se cumplen todas
estas condiciones, se produce una condición de carrera.

Los atacantes buscan deliberadamente las condiciones de la carrera porque a


menudo son omitido en las pruebas generales y explotarlos, lo que a veces resulta
en casos muy graves consecuencias que van desde la denegación de servicio
(puntos muertos) hasta la integridad de los datos problemas y en algunos casos
compromiso y control total. Fácil de introducir pero difíciles de depurar y solucionar,
las condiciones de carrera pueden ocurrir en cualquier lugar el código (variables de
estado local o global, lógica de seguridad, etc.) y en cualquier nivel de código
(código fuente, código ensamblador o código objeto). Puede ocurrir en múltiples
subprocesos, procesos o sistemas.

Los controles de diseño e implementación contra las condiciones de carrera


incluyen

■ identificar y eliminar ventanas de carrera


■ realizar operaciones atómicas en recursos compartidos.
■ usar operaciones mutex.
■ uso selectivo de primitivas de sincronización en torno al código crítico
secciones para evitar problemas de rendimiento.
■ usar capacidades y funciones de subprocesos múltiples y seguros para
subprocesos y abstracciones sobre variables compartidas.
■ minimizar el uso de recursos compartidos y secciones críticas que se puede
activar repetidamente.
■ deshabilitar interrupciones o señales sobre secciones de código críticas.
■ evitar construcciones de bucle infinito.
■ implementar el principio de economía de mecanismos, manteniendo el diseño y la
implementación son simples, de modo que no hay circulares dependencias entre
componentes o secciones de código.
■ implementar el manejo de errores y excepciones para evitar la divulgación de
secciones de código críticas y sus operaciones.
■ realizar pruebas de rendimiento (pruebas de carga y estrés) para asegurar que el
software pueda funcionar de manera confiable bajo cargas pesadas y condiciones
de solicitudes de recursos simultáneas.

Ataques de canal lateral

Aunque no figura entre los 10 o 25 problemas principales que afectan al software,


los ataques de canal son una clase importante de ataques que pueden hacer que la
seguridad eficacia de protección de un criptosistema inútil. Son importantes para
nosotros porque los atacantes pueden utilizar medios no convencionales para
descubrir información sensible y información secreta sobre nuestro software e
incluso una implementación completa de los controles determinados a partir del
modelo de amenazas pueden no ser suficientes para proporcionar seguro de
software.

Aunque los ataques de canal lateral se observan predominantemente en criptografía


sistemas, no se limitan solo a la criptografía en el contexto de criptografía, los
ataques de canal lateral son aquellos que utilizan información ni texto plano ni texto
cifrado de un dispositivo criptográfico para descubrir secretos. La información que
no es ni texto plano ni cifrado se denomina lateral información del canal. Un
dispositivo criptográfico funciona convirtiendo texto sin formato a texto cifrado
(cifrado) y del texto cifrado al texto plano (descifrado). Atacantes de los
criptosistemas eran necesarios para conocer el texto cifrado (solo texto cifrado
ataques), o tanto el texto plano como el texto cifrado (ataques de texto plano
conocidos), o ser capaz de definir qué texto sin formato se cifrará y utilizar la salida
de texto cifrado.
hacia la explotación del sistema criptográfico (ataque de texto plano elegido). Hoy
en día, la mayoría de los dispositivos criptográficos tienen o emiten información
adicional de aquellos que no son ni texto plano ni texto cifrado. Ejemplos de algún
lado común la información del canal incluye el tiempo necesario para completar una
operación (tiempo información), consumos de energía, radiaciones / emanaciones,
acústica y de avería información. Esto hace posible que un atacante descubra
secretos como el contenido de la clave y la memoria utilizando toda o parte de la
información del canal lateral junto con otras técnicas de criptoanálisis conocidas.
Los más comunes las clases de ataques de canal lateral son las siguientes:

Ataques de tiempo

En los ataques de tiempo, el atacante mide cuánto tiempo dura cada operación
computacional y utiliza esa información del canal lateral para descubrir otra
información sobre la composición interna del sistema. Un subconjunto de este
ataque de sincronización busca retrasos mensajes de error que es una técnica
empleada en ataques de inyección SQL ciega.

Ataques de análisis de poder

En los ataques de análisis de poder, el atacante mide los distintos grados de poder
consumo del hardware durante el cómputo de operaciones por
Por ejemplo, la clave RSA se puede decodificar utilizando el análisis de los picos de
potencia,
que representan momentos en que los algoritmos usan multiplicaciones o no.

Ataques TEMPEST

También conocido como van Eck o ataque de monitoreo de radiación, un atacante


que intenta aos ataques TEMPEST utilizan radiaciones electromagnéticas filtradas
que se pueden utilizar para descubrir textos en claro y otra información pertinente
que se basa en emanaciones.

Ataques de criptoanálisis acústico

Al igual que los ataques de análisis de potencia, en los ataques de criptoanálisis


acústico, el atacante utiliza el sonido producido durante el cálculo de las
operaciones.
Ataques de análisis diferencial de fallas

Los ataques de análisis diferencial de fallas tienen como objetivo descubrir secretos
del sistema mediante inyectar intencionalmente fallas en la operación computacional
y determinar cómo responde el sistema a las fallas. Esta es una forma de prueba
fuzz (cubierta en el capítulo de pruebas de software seguro) y también se puede
utilizar para indicar la fuerza de los controles de validación de entrada establecidos.

Ataques de observación distante

Como su nombre indica, los ataques de observación distante son un ataque de surf
de hombro, donde el atacante observa y descubre información de un sistema
directamente desde una distancia. Observando a través de un telescopio o usando
una imagen reflejada fuera del ojo, los anteojos, el monitor u otros dispositivos
reflectantes de alguien son algunos ejemplos bien conocidos de ataques de
observación a distancia.

Ataques de arranque en frío

En una bota fría de ataque, un atacante puede extraer información secreta


congelando el contenido de datos de los chips de memoria y el arranque para
recuperar el contenido en memoria. Se creía que la remanencia de datos en la RAM
se destruía cuando el sistema se apagaba pero el ataque de arranque en frío
demostró conocimiento tradicional ser incorrecto. Esto es importante porque no solo
es un ataque contra confidencialidad, también demuestra la importancia de una
puesta en marcha segura.

Las siguientes son estrategias defensivas recomendadas contra el canal lateral


ataques:

■ Aproveche y use criptografía aprobada, probada y estandarizada algoritmos que


se sabe que son menos propensos al canal lateral
fuga de información.
■ Utilice un sistema en el que el tiempo para calcular una operación sea
independiente de los datos de entrada o el tamaño de la clave.
■ Evite el uso de lógica operativa condicional y de ramificación (IF-THEN-ELSE) en
secciones de código críticas para calcular operaciones
ya que tendrán un impacto en el momento de cada operación. Está se recomienda
utilizar cálculos computacionales más simples y directos operaciones (Y, O, XOR)
para limitar la cantidad de tiempo variaciones que pueden resultar y ser
potencialmente utilizadas para el lado espigado información sobre el tiempo de
canal y el consumo de energía.

■ La protección más eficaz contra los ataques de tiempo es estandarizar en el


tiempo que tomará cada cálculo. Esto significa que cada y cada operación toma la
misma cantidad de tiempo para completar su operación, sin embargo, esto podría
tener un impacto en el rendimiento. La implementación de tiempo fijo no es muy
eficiente desde una actuación punto de vista, pero dificulta que el atacante lleve a
cabo el cronometraje ataques también se sabe que agregar un retraso aleatorio
aumenta el factor de trabajo de un atacante. También estandarizando el tiempo
necesario calcular una multiplicación o una exponenciación puede dejar el atacante
adivinando qué operación se llevó a cabo.
■ Equilibrio del consumo de energía independientemente del tipo de operación junto
con la reducción del tamaño de la señal son controles útiles para defenderse contra
ataques de análisis de poder.
■ La adición de ruido es un control conocido y probado contra análisis.
■ El blindaje físico proporciona una de las mejores defensas contra seguridad de
emanación o radiación como los ataques TEMPEST.
■ Doble cifrado, que se caracteriza por ejecutar el algoritmo de cifrado dos veces y
generar los resultados solo si ambas operaciones coinciden, es un control
recomendado contra diferencial análisis de fallas. Esto funciona con la premisa de
que la probabilidad de La falla que ocurre dos veces es estadísticamente pequeña e
insignificante.
■ Protección física de los chips de memoria, evitando que la memoria deshacerse
del software de la ejecución, no almacenar información confidencial en la memoria,
borrando y sobrescribiendo el contenido de la memoria que ya no es necesario
periódicamente o en el momento del arranque (usando un destructivo autoprueba de
encendido) y uso del módulo de plataforma segura (TPM) son controles efectivos
contra ataques de arranque en frío. Es importante saber que el chip TPM puede
evitar que una clave se cargue en la memoria, pero no puede evitar que la clave sea
descubierta una vez que ya está cargado en la memoria.

Prácticas de codificación defensiva -


Conceptos y técnicas
Comenzamos este capítulo con la premisa de que el software seguro es más que
solo escribir código seguro, sin embargo, implementar controles en el código puede
tener un gran impacto en la resistencia del software frente a amenazas de piratas
informáticos. Al momento en que se escribe una sola línea de código, la superficie
de ataque ha aumentado potencialmente y, por lo tanto, es importante reconocer
que la superficie de ataque del código del software no es solo evaluado pero
también reducido. Algunos ejemplos de reducción de la superficie de ataque
relacionados codificar son:

■ reducir la cantidad de código y servicios que se ejecutan de forma


predeterminada.
■ reducir el volumen de código al que pueden acceder los usuarios que no son de
confianza.
■ limitar el daño cuando se explota el código.

Determinar el RASQ antes y después de la implementación del código puede


utilizarse para medir la eficacia de las actividades de reducción de la superficie de
ataque. Se utilizan prácticas y técnicas de codificación defensiva para reducir el
ataque superficie y asegurando la confiabilidad, resiliencia y recuperabilidad del
software. En la siguiente sección, aprenderemos sobre la codificación defensiva
más común prácticas y técnicas.

Validación de entrada

Si bien es importante confiar, es aún más importante verificar. Este es el premisa


subyacente detrás de la validación de entrada. Cuando se trata de software, de
hecho, debe considerar todas las entradas como malas y validar todas las entradas
del usuario.

La validación de entrada es el proceso de verificación que asegura los datos que se


suministrado:

■ para el procesamiento es del tipo y formato de datos correctos


■ está dentro del rango de valores esperado y permitido
■ no se interpreta como código como es el caso de los ataques por inyección
(cubierto más adelante en este capítulo)
■ no se disfraza de formas alternativas que eluden los controles de seguridad
¿Cómo validar?

Las expresiones regulares (RegEx) se pueden utilizar para validar la entrada. Una
lista de los patrones RegEx comunes se proporcionan en el capítulo Pruebas de
software seguras. Este proceso de verificación se puede lograr mediante técnicas
de filtración.

El filtrado de la entrada del usuario se puede lograr utilizando una lista blanca o una
lista negra. Una lista blanca es una lista de caracteres, comandos buenos y no
maliciosos permitidos o patrones de datos permitidos. Por ejemplo, la aplicación
solo permitirá "@" Y ".com" en el campo de correo electrónico. Los elementos de
una lista blanca se conocen y suelen ser considerados de naturaleza no maliciosa.
Por otro lado, una lista negra es una lista de caracteres, comandos o patrones de
datos no permitidos que se consideran maliciosos. Los ejemplos incluyen comillas
simples (‘), comentario SQL (- -) o un patrón como (1 = 1).

¿Dónde validar?

El punto en el que se valida la entrada también es de vital importancia. La entrada


puede validarse en el cliente o en el servidor o en ambos. Es mejor recomendado
que la entrada esté validada tanto en el cliente (frontend) como en el servidor
(backend) si el software es una solución de arquitectura Cliente / Servidor. Como
mínimo, el servidor debe realizarse una validación lateral. También es insuficiente
para validar la entrada únicamente en el lado del cliente, ya que esto se puede
evitar fácilmente y ofrecer una protección mínima o nula.

¿Qué Validar?

Se puede validar prácticamente cualquier cosa, desde la lista blanca genérica y la


lista negra artículos a patrones específicos definidos por el negocio. Al validar la
entrada, el la entrada debe ser validada como mínimo para:
■ tipo de datos
■ rango
■ longitud
■ formato
■ valores
■ representaciones alternativas de una forma estándar (canónica).
Canonicalización

La canonicalización es el proceso de conversión de datos que tiene más de una


representación para ajustarse a una forma canónica estándar. Desde la
canonicalización es una palabra difícil de pronunciar para algunas personas, se ha
abreviado como C14N (hay 14 caracteres entre la primera letra C y la última letra
NORTE). Aunque la canonicalización es predominantemente evidente en Internet
software, la canonicalización se puede utilizar para convertir cualquier dato en su
estándar formularios y formatos aprobados. En XML, la canonicalización se utiliza
para garantizar que el documento XML se adhiere al formato especificado. La forma
canónica es la forma más estándar o más simple.

La codificación de URL a las traducciones de direcciones IP son aplicaciones bien


conocidas de canonicalización. La canonicalización también tiene implicaciones
internacionales en lo que respecta a juegos de caracteres o páginas de códigos
como ASCII, unicode, etc. (cubierto en la sección de requisitos internacionales del
software seguro capítulo de requisitos). Por tanto, es imperativo que el carácter
apropiado del conjunto y la configuración regional de salida se establezcan en el
software para evitar problemas de canonización. Desde el punto de vista de la
seguridad, la canonicalización tiene un impacto en la filtración de entrada cuando se
utilizan filtros (RegEx) para validar que la forma canónica o estándar de la entrada
son parte de una lista negra, se pueden omitir potencialmente cuando un se pasa
una representación alternativa de la forma canónica, si la verificación de validación
ocurre antes de que se complete el proceso de canonicalización. Se recomienda
decodificar una vez y canonicalizar las entradas en la representación interna antes
realizar la validación para garantizar que no se eluda. Un ejemplo de
canonicalización se muestra en la Figura 4.15.

La desinfección

La desinfección es el proceso de convertir algo que se considera peligroso en su


forma inocua. Tanto las entradas como las salidas se pueden desinfectar. La
desinfección de entrada es el proceso de transformar los datos que proporciona el
usuario antes de que se procesen. La desinfección de entrada se puede lograr
utilizando cualquiera de los siguientes métodos:

■ Eliminación: eliminación de caracteres dañinos de la entrada proporcionada por el


usuario
■ Sustitución: Reemplazo de la entrada proporcionada por el usuario con
alternativas más seguras
■ Literalización: uso de propiedades que representan la entrada proporcionada por
el usuario para ser tratado como una forma literal.

El desmontaje, el reemplazo y la literalización se tratan aquí. Un ejemplo es el


siguiente:
Digamos, por ejemplo, que el atacante proporciona el siguiente texto en un
formulario de entrada campo.

Eliminando los caracteres potencialmente dañinos como "<", ">", "(", ")", "" ","; "
y "/", la entrada del atacante se convierte en script de prueba de la sonda
scriptalertXSS que no se ejecuta.

Un ejemplo de sustitución es el siguiente:


Digamos, por ejemplo, que el atacante proporciona el siguiente texto en un
formulario de entrada campo.

"O 1 = 1 -
Al reemplazar la comilla simple (‘) por una comilla doble (‘ ’), el la entrada del
atacante termina convirtiéndose
"O 1 = 1 -
lo que provocará un error de sintaxis SQL. Un ejemplo de literalización es el
siguiente:

Para la desinfección de entrada en aplicaciones web, una técnica común que es


utilizado incluye la conversión de la entrada en su forma de texto interno, en lugar
de su
formulario innerHTML. Esto hace que la entrada sea no ejecutable y trata la
entrada proporcionada por el usuario como literal cuando se procesa y se refleja en
el cliente.
La desinfección de salida generalmente se realiza mediante codificación (a veces se
denomina como codificación) los datos antes de que se presenten al cliente. Al igual
que el reemplazo técnica de desinfección de entrada, la salida codificada implica la
conversión de la entrada proporcionada por el usuario mediante la codificación de
los valores que se proporcionan con su entidad formulario, de modo que el script
malicioso se escape. Los dos métodos predominantes de la codificación en
aplicaciones web incluyen

■ codificación de entidad HTML


■ codificación de URL

En la codificación de entidades HTML, los metacaracteres y las etiquetas HTML son


codificado a (sustituido con) sus referencias de entidad de carácter
correspondientes.

Por ejemplo, en la codificación de entidades HTML, el carácter "<" se codifica en su


equivalente HTML correspondiente, que es "& lt;" y ">" está codificado en "& gt;".

En Url codificación, la codificación se aplica a parámetros y valores que se


transmiten como parte de la consulta HTTP (URL). Personajes que no son
permitidos en las URL se pueden codificar en su código de juego de caracteres
Unicode. Por ejemplo, en la codificación de URL, el carácter "<" se codifica en su
correspondiente El equivalente de URL que es "% 3C" y ">" está codificado como
"% 3E".

A veces, la desinfección de insumos puede no ser factible debido a algunos motivos,


en ese momento, es mejor desinfectar la salida antes de que se envíe al cliente.

Cuando se realiza la desinfección, es de vital importancia asegurarse de que se


mantiene la integridad de los datos. Por ejemplo, si O’’Shea es el valor
proporcionado como el apellido de un usuario, reemplazando la comilla simple con
doble cotizaciones, el valor cambiará a O’’Shea, que no es exacto. Adicionalmente,
la cantidad de veces que se codifican los datos puede tener un impacto en la
respuesta que se envía al cliente. Por ejemplo, codificación doble (codificación de la
entrada una vez y codificar la entrada codificada de nuevo antes de que salga)
puede tener algunos comportamiento indeseable. Por ejemplo, si el proveedor del
usuario el valor "AT&T", codificarlo una vez resultaría en "AT & amp; T" como &
amp; es la forma codificada del símbolo ampersand. Ahora, cuando ese texto
codificado se vuelva a codificar, el resultado es "AT & amp; amp; T" y el navegador
mostrará "AT & amp; T" en su lugar de "AT&T", que es inexacto.
********* (Aquí termina sesión 11) ******

Manejo de errores

La validación de entrada y el manejo de errores de salida pueden considerarse dos


de los más mecanismos de protección básicos y efectivos que se pueden utilizar
para mitigar mucho de los ataques de software. Los mensajes de error son una de
las primeras fuentes que un atacante mire para determinar la información sobre el
software. Sin un manejo adecuado de entrada y la respuesta generada a partir de
esa entrada en forma de mensaje error, se puede filtrar información confidencial.
Valide todas las entradas para evitar una atacante de forzar un error mediante el
uso de una entrada (tipo, valor, rango, longitud, etc.) que el software no espera.

Los mensajes de error no deben ser detallados y deben especificarse explícitamente


en el software. Un ejemplo de un mensaje de error detallado sería mostrar "Usuario
El ID no coincide "o" la contraseña es incorrecta ", en lugar de utilizar el no detallado
o equivalente lacónico como "Inicio de sesión no válido". Además de los errores, el
el software es fallar a un estado más seguro. Las organizaciones son tolerantes con
los errores de los usuarios que son inevitables, permitiendo un número
predeterminado de errores de usuario antes registrarlo como una violación de
seguridad. Este número predeterminado está establecido como línea de base y en
las operaciones se denomina nivel de recorte. Un ejemplo de esto es decir, después
de tres entradas incorrectas de PIN fallidas, su cuenta se bloquea hasta que el
proceso fuera de banda lo desbloquea o ha transcurrido un cierto período de tiempo.
El software nunca debe fallar inseguro que se caracterizaría por el software que
permite acceso después de tres entradas incorrectas de PIN fallidas.

■ Utilice mensajes de error no detallados con solo la información necesaria errores


generados por el sistema con información de pila y rutas de código debe resumirse
en mensajes de error genéricos fáciles de usar que son lacónicos, con solo la
información necesaria.
■ Utilice un índice del valor o mapa de referencia. Un ejemplo de uso de índices
sería utilizar un identificador único global (GUID) que mapear los errores internos
pero es el GUID solo el que se muestra al usuario, informando que se ponga en
contacto con la línea de soporte para obtener más asistencia. De esta forma, los
detalles del error interno no son directamente revelado al usuario final o al atacante
que podría estar utilizándolos en sus esfuerzos de reconocimiento mientras planean
lanzar otros ataques.
■ Se recomienda como práctica recomendada redirigir errores y excepciones a una
ubicación de manejo de errores personalizada y predeterminada y dependiendo en
el contexto donde el usuario ha iniciado sesión (remoto o local), se pueden mostrar
los detalles del mensaje apropiado.

API seguras

Una de las 10 principales amenazas para el software y los sistemas de computación


en la nube, según el informe publicado de Cloud Security Alliance, fue el uso nefasto
de API. El software actual se desarrolla principalmente usando y aprovechando
aplicaciones interfaces de programación (API). Las API hacen que la funcionalidad
interna de un software funcione accesible para llamantes externos (otras entidades y
funciones de código). Ellos abstraen los detalles de la función interna y siempre que
la persona que llama se encuentre con la interfaz requisitos, pueden invocar y
beneficiarse del procesamiento de la función. Las interfaces son útiles para
implementar el principio de diseño para aprovechar los componentes. El modelado
de amenazas debe identificar las API como posibles puntos de entrada, API
prohibidas y obsoletas que son susceptibles a las brechas de seguridad debe ser
evitado y reemplazado con contrapartes seguras.

Cuando se utilizan interfaces para acceder a funciones administrativas, servicios


web, u otros componentes de terceros, es esencial asegurarse de que la
autenticación está en su lugar. También es importante auditar el acceso y el usuario
/ sistema acciones que se realizan tras la invocación de funciones privilegiadas
expuestas por las interfaces. Cuando la confidencialidad de la información sensible
(nombres de usuario, contraseñas, cadena de conexión, claves), CryptoAPI Next
Generation (GNC) se puede utilizar. Cuando las API internas de una aplicación se
abren a desarrolladores externos, los mecanismos de protección necesarios deben
estar en su lugar.

Gestión de la memoria

Cubrimos la importancia de la gestión de la memoria en la sección sobre


arquitectura de computadora y ataques de desbordamiento de búfer. Los siguientes
son otros conceptos importantes de gestión de memoria con los que un CSSLP
debe estar familiarizado, para ayudar en la implementación de los controles de
seguridad de manera apropiada.
Localidad de referencia

La localidad de referencia, también conocida como principio de localidad, es el


principio que las ubicaciones de datos posteriores a las que se hace referencia
cuando se ejecuta un programa son a menudo predecible y próximo a ubicaciones
anteriores en función del tiempo o el espacio.Esto es principalmente para promover
la reutilización de datos e instrucciones usados ​recientemente.Los principales tipos
de localidad de referencia que prevalecen son temporales, espaciales, sucursal y
localidad equidistante.

Es importante comprender el principio de localidad ya que es apropiado la


protección de la memoria se puede implementar para evitar el desbordamiento del
búfer de memoria ataques.

Punteros colgantes

Los punteros colgantes son aquellos punteros que no apuntan a un objeto válido del
tipo apropiado en la memoria. Estos ocurren cuando el objeto que el puntero la
referencia original se eliminó o se desasigna sin el valor del puntero siendo
modificado. Esto también se conoce comúnmente como una pérdida de memoria y
el objeto de memoria anterior se vuelve inalcanzable mientras todavía ocupa
memoria superior espacio. Los punteros colgantes hacen referencia a la ubicación
de la memoria de los memoria y cuando esa ubicación de memoria desasignada se
carga con alguna otros datos, resultados impredecibles que incluyen inestabilidades
del sistema, segmentación y potencialmente pueden ocurrir fallas de protección
general. Además, si un atacante puede aprovechar el puntero que cuelga, pueden
producirse ataques de desbordamiento graves. Los punteros colgantes difieren de
los punteros salvajes en el sentido de que los punteros salvajes se utilizan antes de
ser inicializados, pero se sabe que producen resultados similares resultados
erráticos, impredecibles y peligrosos como punteros colgantes.

Recolección de basura

Se produce una pérdida de memoria cuando el objeto de búfer de memoria


asignado para contener alguna variable se vuelve inalcanzable. Esto puede ocurrir
si los subprocesos de procesamiento son no optimizados o debido a una mala
programación. Es por eso que la memoria debe ser gestionada. Una vez que se
terminan los subprocesos de procesamiento, se asignan recursos de memoria
deben liberarse y recuperarse para su reutilización.
La recuperación de la memoria se hace posible automáticamente por lo que se
refiere como recolección de basura, en programación informática. El principal
objetivo de la basura la recopilación es para reducir las pérdidas de memoria, es
decir, recuperar la memoria inalcanzable objetos. Exigir a los programadores que
administren manualmente la memoria no sólo dan lugar a problemas de
optimización del software, pero también hacen que el software sea explotable. Por
eso es importante la recolección de basura.

Aunque la recolección de basura se aplica automáticamente, se puede invocar en


código por el programador. Sin embargo, debe reconocerse que la recolección de
basura es de naturaleza no determinista. En otras palabras, una llamada a la
recolección de basura funcionalidad (por ejemplo, System.gc ()) no significa que la
recolección de basura ocurrirá cuando se ejecute esa línea de código. En cambio,
es simplemente el procesador que se debe realizar la recolección de basura.

La recolección de basura puede tener y generalmente tiene un impacto en el


rendimiento porque un tiempo de retraso (latencia) es una experiencia entre el
tiempo, referencias de objetos se designan y cuando se reclama el objeto. Para
abordar el problema de la latencia, en algunos sistemas operativos más nuevos,
como Apple iOS, la recolección de basura está siendo obsoleto por lo que se
conoce como conteo automático de referencias (ARC). El recuento de referencias
se puede considerar como una forma de recolección de basura en la que cada
objeto en la memoria mantiene un recuento del número de referencias de puntero al
mismo. Cada vez que se hace una referencia al objeto, se incrementa el recuento
de referencias. Siempre que se destruya una referencia al objeto, el recuento de
referencias será decrementado. Cuando ese recuento llega a cero, ese objeto se
considera para ser basura que luego se puede desasignar y recuperar. La ventaja
de ARC sobre la recolección de basura tradicional, es que el conteo de referencias
garantiza que los objetos se destruyen y recuperan tan pronto como se vuelven
inalcanzables es decir, sus recuentos de referencia llegan a cero.

La gestión inadecuada de la memoria puede provocar asignaciones de memoria


anormales que eventualmente puede conducir a un ataque DoS. Esto sucede
cuando el espacio de la memoria está lleno de objetos que luego son destruidos por
el código de explotación del atacante, luego, el recolector de basura se activa,
deteniendo otros subprocesos de procesamiento, mientras intenta recuperar el
espacio de memoria, lo que lleva a un ataque DoS. Frecuentemente someter al
recolector de basura a sobremarcha en su función puede resultar en el sistema se
detiene y esta técnica de ataque se conoce como muerte rápida. En una muerte
rápida, los recursos de la memoria del sistema se agotan. Al contrario de un ayuno
la muerte es la muerte lenta en la que el atacante solicita memoria adicional que el
recolector de basura tiene que invocar, pero lo hacen a una velocidad que no es tan
grave para lanzar una excepción de memoria insuficiente. En muerte lenta, los ciclos
de la CPU son robados, cuando la memoria está ocupada.

Tipo de seguridad

El código de seguridad de tipo no puede acceder a la memoria en ubicaciones


arbitrarias fuera del rango del espacio de direcciones de memoria que pertenece a
los campos expuestos públicamente del objeto. No puede acceder a ubicaciones de
memoria a las que no está autorizado a acceder. Cuando el el código es de tipo
seguro, el tiempo de ejecución tiene la capacidad de aislar ensamblados de unos y
otros. El código de seguridad de tipos accede a tipos solo en los definidos
explícitamente convertido) y formatos permitidos. Se descubre que las
vulnerabilidades de desbordamiento de búfer prevalecen en lenguajes seguros no
de tipo no administrados, como C y C ++. El tipo de seguridad es una consideración
importante al elegir entre una gestión de lenguaje de programación no administrada.
Polimorfismo paramétrico o genéricos que permite que una función o tipo de datos
se escriba genéricamente para que pueda manejar valores idénticos sin depender
de su tipo es un medio para hacer un lenguaje más expresivo manteniendo la
seguridad de tipo completo.

Acceso al código Seguridad

A diferencia del caso de un entorno de código no administrado, en un código


administrado entorno, cuando se ejecuta un programa de software, se evalúa
automáticamente para determinar el conjunto de permisos que se deben otorgar al
código durante tiempo de ejecución y en función de los permisos concedidos, el
programa se ejecutará como esperado o lanzar una excepción de seguridad. La
configuración de seguridad de la computadora host El sistema en el que se ejecuta
el programa decide los conjuntos de permisos que el código es concedido. La
seguridad de acceso al código (CAS) evita que el código provenga de fuentes no
confiables o orígenes desconocidos por tener permisos en tiempo de ejecución para
realizar operaciones. CAS también protege el código de fuentes confiables de
inadvertidamente o comprometer intencionalmente la seguridad. Para implementar
CAS, el código debe ser generado por un lenguaje de programación que puede
producir código de seguridad de tipo verificable.
Además de la seguridad de tipos, los conceptos CAS incluyen lo siguiente:

■ Seguridad de sintaxis (declarativa e imperativa)


■ Acciones de seguridad
■ Bibliotecas de clases seguras

Seguridad de sintaxis (declarativa e imperativa)

CAS se puede implementar en el propio código. Las dos formas en que se


implementa en sintaxis de código incluye seguridad declarativa e imperativa. En el
contexto de CAS, la sintaxis de seguridad declarativa significa que los permisos
están definidos como atributos de seguridad en los metadatos del código como se
muestra en la Figura 4.16. los alcance de los atributos de seguridad que definen las
acciones de seguridad permitidas (solicitudes, demandas y anulaciones) puede ser
a nivel de todo el conjunto, una clase o en el nivel de miembro. La seguridad
imperativa, por otro lado, se implementa utilizando nueva instancia del objeto de
permiso en línea en el código como se muestra en la Figura 4.17. La acción de
seguridad de demandas y anulaciones es posible en seguridad imperativa, pero la
seguridad imperativa no se puede utilizar para las solicitudes. La seguridad
imperativa es útil cuando no se conocen los permisos de tiempo de ejecución que se
otorgarán al código antes de que se ejecute, en cuyo caso los permisos no se
pueden definir declarativamente como atributos de seguridad del código.

Además de la seguridad de sintaxis declarativa para implementar CAS, la seguridad


también es un enfoque de seguridad gestionado por contenedores. En este
contexto, el objetivo principal es hacer que el software sea portátil, flexible y menos
costoso para implementar y las reglas de seguridad se configuran fuera del código
de software como parte del descriptor de despliegue. A menudo, esto se basa en un
servidor (contenedor) y los ajustes de configuración del servidor para autenticación y
autorización se utilizan para proteger el recurso del acceso no autorizado. Suele ser
un todo o nada tipo de seguridad. Dado que generalmente lo configura y mantiene la
implementación

personal y no al desarrollador, la seguridad declarativa permite a los programadores


ignorar el entorno en el que escriben su software y las actualizaciones del software
no requiere refactorizar el modelo de seguridad. Seguridad programática por otro
lado, es un enfoque de seguridad gestionado por componentes y muy parecido a la
imperativa implementación de CAS, la seguridad programática funciona definiendo
las reglas de seguridad en el componente o código en sí. Esto permite una granular
enfoque para implementar la seguridad y se puede utilizar para aplicar reglas
comerciales cuando la seguridad basada en contenedor declarativo de todo o nada
no puede soportar el reglas necesarias. La seguridad programática la define el
desarrollador. Si el código se reutiliza es un requisito necesario, luego la seguridad
basada en componentes programáticos que no se recomienda personalizar el
código con reglas comerciales y de seguridad. En ciertos casos, se prefiere la
seguridad declarativa basada en contenedores, que también aprovecha a los no
programadores y al personal de implementación para hacer cumplir las políticas de
seguridad.

Acciones de seguridad

Los permisos que se otorgan son evaluados por el tiempo de ejecución cuando se
carga el código en la memoria. Las tres categorías de acciones de seguridad que se
pueden realizar son solicitud, demandas y anulaciones. Las solicitudes se utilizan
para informar al tiempo de ejecución sobre los permisos que necesita el código para
que se ejecute. No se puede utilizar para influir en el tiempo de ejecución para
otorgar al código más permisos de los que debería ser concedido. Las demandas se
utilizan en el código para hacer valer los permisos y ayudar a proteger los recursos
de las personas que llaman. Las anulaciones se utilizan en el código para anular el
comportamiento de seguridad predeterminado.

Bibliotecas de clases seguras

Una característica distintiva de una biblioteca de clases segura es que utiliza


demandas de seguridad para determinar que las personas que llaman a las
bibliotecas tienen los permisos para acceder a la funcionalidad y recursos que
expone. Código que no tiene el tiempo de ejecución necesario los permisos para
acceder a las bibliotecas de clases seguras no podrán acceder a los recursos de
bibliotecas. Además, incluso si el código tiene los permisos de tiempo de ejecución
para llamar bibliotecas de clases seguras, si ese código a su vez es llamado por
código malicioso, entonces el código malintencionado (que ahora es la persona que
llama) no podrá acceder a la seguridad bibliotecas de clases o sus recursos.

Gestión de excepciones

Las excepciones son inevitables cuando se trata de software. Si bien los errores
pueden ser un resultado de la ignorancia del usuario o avería del software, las
excepciones son problemas de software que no se manejan explícitamente cuando
el software se comporta de forma no intencionada o manera poco confiable. Un
ejemplo de error de usuario es que el usuario escribe incorrectamente a su usuario
ID al intentar iniciar sesión. Ahora, si el software esperaba que el ID de usuario fuera
suministrado en un formato numérico y el usuario escribió en caracteres alfabéticos
en ese campo, las operaciones del software darán como resultado una excepción de
conversión de tipo de datos. Si esta excepción no se maneja explícitamente,
resultaría en informar al usuario de esta excepción y, en muchos casos, divulga toda
la pila de excepciones. Esto puede resultar en la divulgación de información que
potencialmente revele los detalles arquitectónicos y, en algunos casos, incluso el
valor de los datos. La figura 4.18 revela cómo una excepción no manejada revela
mucha información confidencial, incluida la composición interna del software.
Maneje todas las excepciones preferiblemente con un enfoque común.

Todas las excepciones deben manejarse explícitamente. Si el lenguaje de


programación permite construcciones try-catch-finalmente, entonces debe haber
una excepción de atrapar todo o bloquear.

Además, una función importante de gestión de excepciones que puede apalancarse


durante el proceso de compilación y vinculación es utilizar seguridad Indicador del
controlador de excepciones (/ SAFESEH) en los sistemas que lo admiten.

Cuando se establece el indicador / SAFESEH, el vinculador producirá la seguridad


del ejecutable la tabla de controladores de excepciones y escribe esa información
en el programa ejecutable (EDUCACIÓN FÍSICA). Esta tabla en el PE se utiliza para
verificar las excepciones seguras (o válidas) por parte del SO. Cuando se lanza una
excepción, el sistema operativo comprobará el controlador de excepciones con la
lista de manejadores de excepciones seguras que está escrita en el PE y si no
coinciden, el sistema operativo terminará el proceso.

Gestión de sesiones

Solo porque alguien está autenticado y autorizado para acceder a los recursos del
sistema no significa que los controles de seguridad puedan ser laxos después de
una sesión autenticada está establecida, porque una sesión puede ser secuestrada.
Ataques de secuestro de sesiones suceden cuando un atacante se hace pasar por
la identidad de un usuario válido e interviene ellos mismos en el medio de una
sesión existente, enrutando información desde el usuario al sistema y del sistema al
usuario a través de ellos. Esto puede llevar a la divulgación de información
(amenaza de confidencialidad), alteración (amenaza de integridad) o una
denegación de servicio (amenaza de disponibilidad). También se conoce como
ataque man-in-themiddle (MITM). La gestión de sesiones es un concepto de
seguridad que tiene como objetivo para mitigar el secuestro de sesiones o los
ataques MITM. Requiere que la sesión sea única por la emisión de tokens de sesión
únicos y también requiere que el usuario la actividad se rastrea para que alguien
que esté intentando secuestrar una sesión válida se le impide hacerlo. Controles a
implementar en código para administrar sesiones se tratan en la sección
autenticación rota y administración de sesiones en este capítulo.

Gestión de parámetros de configuración

El software se compone de código y parámetros que deben establecerse. Estos


parámetros pueden incluir variables que deben inicializarse en memoria para que se
inicie el software, cadenas de conexión a bases de datos en el backend o claves
criptográficas para mantener el secreto, por nombrar solo algunas. Estas
configuraciones y parámetros son parte de la estructura del software. Deben
considerarse un activo al igual que el propio software operativo y deben configurarse
correctamente y protegido también. ¿De qué sirve cerrar las puertas y ventanas de
tu casa? cuando dejas la llave debajo de la alfombra en el porche delantero? En el
contexto de seguridad software, la gestión de parámetros de configuración significa
que los parámetros que componen el software se gestionan y protegen de modo
que sean menos propensos a explotación. Dos parámetros configurables principales
incluyen variables de inicio y claves criptográficas y cada una se cubre en esta
sección a continuación bajo los temas, inicio seguro y agilidad criptográfica.

Inicio seguro

Es importante reconocer que el software escrito puede ser seguro de forma


predeterminada en diseño e implementación, pero sin niveles adecuados de
protección para proteger la integridad del software cuando comienza a ejecutarse,
puede frustrar la garantía del software. Por tanto, es imperativo asegurarse de que
el software el proceso de inicio en sí es seguro. Por lo general, durante el proceso
de arranque se inicializan la fase de inicio, las variables de entorno y los parámetros
de configuración. Estas variables y parámetros deben protegerse contra la
divulgación, alteración o amenazas de destrucción. La seguridad de bootstrapping
se trata con más detalle en el capítulo de implementación, operaciones y
mantenimiento y eliminación de software. Seguro el inicio previene y mitiga los
ataques de canal lateral como el ataque de arranque en frío.

Criptografía

El impacto de las vulnerabilidades criptográficas puede ser extremadamente grave y


desastroso para el negocio, que van desde la divulgación de datos que trae consigo
multas y supervisión (reglamentaria y de cumplimiento) para el robo de identidad de
los clientes, daño a la reputación y, en algunos casos, la quiebra total.

Cuando se trata de proteger criptográficamente la información, el predominante la


falla en el software es la falta de cifrado de datos sensibles. Los atacantes
normalmente persiguen las debilidades que son las más fáciles de romper. Cuando
los datos que deben ser criptográficamente seguros se almacenan como texto
plano, el factor de trabajo para que un atacante obtenga acceso a información
confidencial y verla es prácticamente inexistente, ya que no tiene la necesidad de
romper el algoritmo de criptografía o determinar la clave necesitaba descifrar. Sin
embargo, si los datos están encriptados, entonces el factor de trabajo para un
atacante es relativamente más alto. Pero hay que reconocer que cifrar el datos sin
asegurar adecuadamente el almacenamiento de claves hace que el criptográfico
protección inútil ya que los atacantes no necesariamente tienen que romper la
criptografía algoritmo en sí, pero puede encontrar las claves y utilizar la clave para
descifrar el texto cifrado texto claro que conduce a la divulgación.

Otras vulnerabilidades criptográficas inseguras se componen principalmente de


siguiendo:

■ el uso de un criptográfico no validado desarrollado a medida o débil algoritmo para


las necesidades de cifrado y descifrado.
■ el uso de interfaces de programación de aplicaciones criptográficas más antiguas
(API)
■ administración de claves insegura e inadecuada que se compone de generación
de claves inseguras, intercambio de claves sin protección, clave incorrecta rotación,
archivo de claves desprotegidas y custodia de claves, clave incorrecta destrucción y
medidas de protección adecuadas e inadecuadas que garantizan el secreto de la
clave criptográfica cuando se almacena. Un ejemplo común es almacenar la clave
criptográfica junto con los datos en una cinta de respaldo.
■ almacenamiento adecuado e inadecuado de los datos (datos en reposo) que debe
ser criptográficamente seguro. Almacenar los datos sensibles en texto simple o
como texto cifrado sin sal (que puede ser forzado) son ejemplos de esto.
■ control de acceso insuficiente que da a los usuarios acceso directo a archivos no
cifrados datos o funciones criptográficas que pueden descifrar texto cifrado y / o a la
base de datos donde se almacena información confidencial y privada.
■ violación del privilegio mínimo que otorga a los usuarios privilegios elevados que
permiten que realicen operaciones que no se les debe permitir y carecen de
auditoría de operaciones criptográficas.

Técnicas de prevención y mitigación para abordar la criptografía insegura Los


problemas se pueden clasificar en términos generales en los siguientes:

■ Controles de protección de datos en reposo


■ Uso apropiado de algoritmos
■ Agilidad criptográfica
■ Gestión segura de claves
■ Auditoría y control de acceso adecuados

Las fuentes de las amenazas de divulgación de datos en reposo y algunas de los


controles se cubrió en el tema Exposición de datos sensibles, en este capítulo se
trata de nuevo aquí para reforzar su importancia. Otra protección de datos en
reposo los controles incluyen:

■ cifrar y almacenar los datos confidenciales como texto cifrado, al inicio.


■ almacenar versiones de texto cifrado con sal de los datos para mitigar la fuerza
bruta ataques de criptoanálisis.
■ no permitir que los datos que se consideran sensibles crucen los límites de la
confianza de zonas seguras a zonas inseguras (según lo determine la amenaza
modelo)
■ separar los datos sensibles de los no sensibles (si es posible) utilizando
convenciones de nomenclatura y tipos fuertes. Esto hace que sea más fácil detectar
segmentos de código donde los datos utilizados no se cifran cuando es necesario.

El uso apropiado del algoritmo significa que:

■ El algoritmo utilizado para fines de cifrado y descifrado no es desarrollado a


medida.
■ El algoritmo utilizado con fines de cifrado y descifrado es un estándar (como el
AES) y no un débil históricamente probado uno (como DES). AES se compone de
tres cifrados de bloque, cada uno con un tamaño de bloque de 128 bits y tamaños
de clave de 128, 192, 256 bits (AES-128, AES-192 y AES-256), que se adopta de
una colección más grande publicada originalmente como Rijndael. Una común es la
implementación de AES en el código es usar la clase RijndaelManaged pero debe
entenderse que el uso del RijndaelManaged la clase no necesariamente hace que
uno sea compatible con FIPS-197 especificación para AES a menos que el tamaño
del bloque y el tamaño de la retroalimentación (cuando utilizando el modo Cipher
Feedback (CFB)) son de 128 bits cada uno.
■ Las API de criptografía más antiguas (CryptoAPI) no se utilizan y reemplazan con
la API de criptografía: próxima generación (CNG). GNC está destinado a ser
utilizado por desarrolladores para proporcionar una creación de datos segura e
intercambiar en entornos no seguros como Internet y es extremadamente extensible
debido a su criptografía agnóstica naturaleza. Se recomienda que CSSLP esté
familiarizado con GNC.
características y su implementación.
■ el diseño del software tiene en cuenta la capacidad de intercambiar rápidamente
algoritmos criptográficos según sea necesario. Los criptográficos algoritmos
criptográficos que se consideraban fuertes en el pasado han demostrado ser
ineficaz en el mundo de la informática actual y sin la capacidad de intercambiar
rápidamente estos algoritmos en código, la aplicación puede experimentar un
tiempo de inactividad que afecta el principio de disponibilidad de seguridad.

La agilidad criptográfica significa que la aplicación está diseñada para hacer


referencia al algoritmo criptográfico o la función hash fuera del código de la
aplicación en sí mismo, de modo que se pueda cambiar fácilmente cuando sea
necesario.

Uno de los defectos predominantes de la implementación de la protección


criptográfica en el código es el uso de criptográficos débiles o no validados y
desarrollados a medida algoritmos para cifrado y descifrado o hash sin colisiones
funciones para propósitos de hash. La recomendación para abordar esta
preocupación
era utilizar algoritmos estandarizados examinados, probados y comprobados. Sin
embargo, en el juego de criptoanálisis del gato y el ratón, los criptoanalistas trabajan
igualmente duro para romper algoritmos seguros que los criptógrafos han estado
ideando. No es sorpresa que los algoritmos criptográficos que antes se
consideraban seguros ahora han demostrado estar rotos y algunos incluso se han
incluido en listas prohibidas. La tabla 4.5 es una tabulación de algunos algoritmos
criptográficos y funciones hash que son prohibidos por SDL (Security Development
Lifecycle) en Microsoft y su alternativas recomendadas.

Código que contiene algoritmos criptográficos que alguna vez se consideraron


seguro pero ahora determinado a ser inseguro y encontrado en una lista prohibida
necesita ser revisado y actualizado. Esta no es una tarea fácil a menos que el
código tenga ha sido diseñado e implementado para ser criptográficamente ágil o
agnóstico del algoritmo criptográfico. La agilidad criptográfica es la capacidad del
código para ser capaz de cambiar de algoritmos inseguros a algoritmos aprobados
con facilidad, porque la forma en que se construye el código es independiente del
algoritmo para proporcionar operaciones criptográficas (cifrado, descifrado y / o
hash). Esto significa que un algoritmo específico o la forma en que se puede usar no
es un código en línea codificado y así reemplazar algoritmos no requiere cambios de
código, reconstrucción, regresión pruebas, actualizaciones (parches y paquetes de
servicios) y redespliegue. Código que es criptográficamente ágil se caracteriza por
mantener la especificación del algoritmo o función hash fuera del código de la
aplicación. Configuración de los archivos a nivel de la aplicación o de la máquina se
utilizan generalmente para implementar esto. Además, incluso cuando el algoritmo
se especifica en un archivo de configuración, la implementación del algoritmo debe
ser abstracta dentro del código. Codificar solo el tipo abstracto del algoritmo (por
ejemplo, SymmetricAlgorithm o AsymmetricAlgorithm) en lugar de un algoritmo
específico (por ejemplo, RijndaelManaged o RSACryptoServiceProvider)
proporciona una mayor agilidad. Además del beneficio de reemplazo rápido y fácil
de algoritmos, se puede utilizar la agilidad criptográfica para mejorar el rendimiento
cuando la API de criptografía es más nueva y eficiente Se aprovechan las
implementaciones de próxima generación (CNG).

CNG es el reemplazo de CryptoAPI y es muy extensible y criptográficamente


agnóstico por naturaleza. Fue desarrollado para brindar a los desarrolladores la
capacidad de permitir a los usuarios crear e intercambiar documentos y datos de
forma segura manera en entornos no seguros como Internet. Las principales
características de GNC incluyen:

■ Un nuevo sistema de configuración criptográfica que admite mejores


agilidad criptográfica.
■ Abstracción para el almacenamiento de claves y separación del almacenamiento
de las operaciones de algoritmo.
■ Aislamiento de procesos para operaciones con claves a largo plazo.
■ Generadores de números aleatorios reemplazables.
■ Mejor soporte de firmas de exportación.
■ Seguridad del hilo en toda la pila
■ API criptográfica en modo kernel.

Sin embargo, el código criptográficamente ágil plantea algunos desafíos. El


criptográfico observa que la agilidad funciona mejor con datos transitorios no
persistentes que con datos persistentes datos. Datos persistentes (almacenados)
que están encriptados con un algoritmo que se reemplazado puede no ser
recuperable una vez que se reemplaza el algoritmo. Esto también puede conducir a
una denegación de servicio a usuarios legítimos, cuando la autenticación se basa en
coincidencia comparativa de hashes calculados, y las credenciales de la cuenta son
almacenado después de ser calculado usando una función hash que ha sido
reemplazada. Se recomienda que, en tales situaciones, la función hash original sea
almacenado como metadatos junto con el valor hash real. Además, es importante
planificar el tamaño de almacenamiento de las salidas como el algoritmo utilizado
para reemplazar el uno inseguro puede producir una salida con un tamaño diferente.
Por ejemplo, el MD5 hash es siempre de 128 bits de longitud, bit las funciones
SHA-2 pueden producir 256 bits (SHA-256), 384 bits (SHA-384) o 512 bits
(SHA-512) salida de longitud de bits y si El almacenamiento no está planeado para
asignarse por adelantado, la actualización puede ni siquiera ser un posibilidad

La gestión segura de claves significa que


■ La generación de la clave utiliza un número aleatorio o aleatorio generador (RNG
o PRNG) es aleatorio en naturaleza.

■ El intercambio de claves se realiza de forma segura mediante mecanismos fuera


de banda o infraestructura clave aprobada que también sea segura.
■ El almacenamiento de claves está protegido, preferiblemente en un sistema que
no es el mismo que el de los datos, ya sea el sistema transaccional o el sistema de
respaldo.
■ La rotación de la llave donde una llave es reemplazada por otra sigue el proceso
apropiado de descifrar primero los datos con la clave anterior que serán
reemplazados y luego cifrar los datos con la nueva clave que es reemplazo de la
llave vieja. No seguir este proceso secuencialmente ha demostrado que causa DoS,
especialmente en datos archivados, porque los datos cifrados con una clave anterior
no pueden ser descifrados por la nueva llave.
■ El archivo y custodia de la clave está protegido con los mecanismos de control de
acceso y preferiblemente no archivados en el mismo sistema como el que contiene
los archivos de datos cifrados. Cuando las llaves están en custodia, es importante
mantener las diferentes versiones de llaves.
■ La destrucción de claves asegura que una vez que se destruye la clave, nunca
más se utilizará. Es de vital importancia garantizar que todos los datos cifrados con
la clave que se va a destruir sean descifrados antes de que la clave se destruya
permanentemente.

Un adecuado control de acceso y auditoría significa que tanto para internos como
para usuarios, el acceso a las claves y datos criptográficos
■ concedido explícitamente
■ controlados y monitoreados mediante auditorías y revisiones periódicas.
■ no frustrado inadvertidamente por debilidades como inseguridad
configuraciones de permisos.
■ contextualmente apropiado y protegido, independientemente de si el cifrado es
unidireccional o bidireccional. Contexto de cifrado unidireccional implica que solo el
usuario o destinatario necesita tener acceso al clave, como en el caso de PKI. El
contexto de cifrado bidireccional implica que el cifrado se puede realizar
automáticamente en nombre del usuario, pero la clave debe estar disponible para
que el texto sin formato pueda ser recuperado automáticamente por ese usuario.

Concurrencia
Anteriormente aprendimos que para que ocurran las condiciones de carrera, debería
haber varios subprocesos que operan simultáneamente contra un objeto
compartido, y cada subproceso intenta cambiar el estado de ese objeto compartido.
Simultaneidad (simultánea operaciones) es una propiedad principal en los ataques
TOC / TOU.

Algunas de las medidas de protección predominantes contra condiciones de carrera


o TOC / los ataques TOU son:

■ Evite las ventanas de carrera


■ Operaciones atómicas
■ Exclusión mutua (Mutex)

Una ventana de carrera se define como la ventana de oportunidad cuando dos hilos
compiten entre sí tratando de alterar el mismo objeto. El primer paso para evitar
condiciones de carrera es identificar ventanas de carrera. Codifica incorrectamente
segmentos de código que acceden a objetos sin un flujo de control adecuado
pueden resultar en ventanas de carrera. Tras la identificación de las ventanas de
carrera, es importante arreglarlas en código o diseño lógico para mitigar las
condiciones de carrera. Además de abordar ventanas de carrera, las operaciones
atómicas también pueden ayudar a prevenir ataques de condición de carrera.

Las operaciones atómicas significan que todo el proceso se completa con un solo
flujo de control y que subprocesos concurrentes o flujo de control contra el mismo el
objeto no está permitido. Las operaciones de un solo hilo son un medio para
garantizar que las operaciones se realizan de forma secuencial y no simultánea. Sin
embargo, tal diseño tiene un costo de rendimiento y debe ser considerado
cuidadosamente sopesando los beneficios de la seguridad sobre el rendimiento.

Las condiciones de carrera también se pueden eliminar haciendo dos procesos en


conflicto o ventanas de carrera, mutuamente excluyentes entre sí. Se hace
referencia a las ventanas de carrera como secciones críticas porque es fundamental
que dos ventanas de carrera no se superpongan a una u otra. Las exclusiones
mutuas o Mutex se pueden lograr mediante el bloqueo de recursos, donde el objeto
al que se accede está bloqueado y no permite ninguna alteración hasta que el
primer proceso o amenaza lo libere. El bloqueo de recursos proporciona integridad
garantía. Digamos, por ejemplo, en el caso de una subasta en línea, Jack puja por
una artículo en particular y Jill, que también está interesada en ese mismo artículo,
hace una oferta como bien. Tanto las ofertas de Jack como las de Jill deben
excluirse mutuamente y hasta que la oferta de Jack se procese por completo y se
asigne a la base de datos de backend, no se debe permitir la operación de Jill Bid.
El registro de backend que contiene el la información del artículo debe estar
bloqueada para cualquier operación hasta la transacción de Jack se confirma
correctamente o se revierte en caso de error.

Tokenización

Muchos estándares y regulaciones de la industria impiden el almacenamiento de


información después de que se haya utilizado en una transacción. Por ejemplo, PCI
DSS impide el almacenamiento del número de cuenta principal (PAN) del titular de
la tarjeta en los sistemas de punto de venta (POS) del minorista en un almacén de
datos después de que se haya utilizado en una transacción. Muchas empresas han
recurrido a la protección criptográfica (encriptar) la información del titular de la
tarjeta e implementar de un extremo a otro soluciones de encriptación que son
caras. Otra alternativa es la tokenización.

La tokenización es el proceso de reemplazar datos confidenciales con símbolos de


identificación que aún conservan la información necesaria sobre los datos, sin
comprometer su seguridad. Tiene como objetivo minimizar la cantidad de datos la
empresa necesita almacenar mientras facilita el cumplimiento de los estándares de
la industria y regulaciones.

En el caso del ejemplo de PCI DSS, el PAN se convertiría en aleatorio o valores


pseudoaleatorios (o tokens). El token normalmente sólo contendría los últimos
cuatro dígitos del número real de la tarjeta y los demás números se reemplazan con
caracteres alfanuméricos que representan información y datos del titular de la tarjeta
específico de la transacción en curso. La tokenización generalmente se implementa
como un servicio y el proveedor de servicios es responsable de emitir el valor del
token y al mismo tiempo, asume la responsabilidad de conservar los datos
confidenciales del titular de la tarjeta protegido. Dado que el token no es el PAN, no
se puede usar fuera del contexto de la transacción única específica.

Aunque la tokenización suele ser evidente para proteger al titular de la tarjeta


información, su aplicación puede extenderse para proteger la confidencialidad de
cualquier dato sensible, incluidas transacciones bancarias, registros médicos,
registros, negociación de acciones y registros de votantes. La tokenización lo hace
más difícil para piratas informáticos para robar información confidencial, ya que el
robo de los datos del token en sí no revela directamente la información confidencial
subyacente que fue tokenizada.

Sandboxing

En el contexto de la seguridad informática, el sandboxing se refiere al mecanismo


de seguridad que evita que el software que se ejecuta en un sistema acceda al host
sistema operativo. La caja de arena crea una separación del sistema operativo host
para que código y programas no probados, no confiables y no verificados,
especialmente aquellos que son publicados por terceros. Controla estrictamente los
recursos en el host el sistema se ve comprometido. A menos que los permisos se
otorguen explícitamente, el programa de software que está siendo sandbox tendrá
un acceso mínimo o nulo al sistema operativo subyacente.

El sandboxing es un ejemplo del principio de privilegio mínimo. Ejecutando código


en una caja de arena (o cárcel) restringe el acceso que tiene el código a otros
recursos del sistema. La cárcel chroot de Unix, AppArmor y SELinux son algunos
ejemplos conocidos de sandboxing a nivel de SO. La interacción de la aplicación
con el sistema se puede configurar mediante derechos que anulan la zona de
pruebas de la aplicación. Firma de código (cubierto bajo técnicas Anti-Manipulación)
asegura la integridad y autenticidad del código de software, además de darle al
código los permisos de tiempo de ejecución necesarios para acceder el sistema
operativo de espacio aislado del host.

Anti-manipulación

Las técnicas anti-manipulación aseguran la integridad y la protección contra


alteraciones no autorizadas y maliciosas del código de software y / o los datos.
Algunas de las técnicas anti-manipulación más conocidas incluyen la ofuscación,
protección contra la ingeniería inversa y la firma de códigos.

Ofuscación

El código (fuente u objeto) debe protegerse contra usuarios no autorizados


modificaciones para asegurar operaciones confiables e integridad del software. La
garantía contra la manipulación del código se puede lograr mediante la ofuscación.
Ofuscación del código fuente es el proceso de hacer que el código sea oscuro y
confuso usando un programa especial llamado ofuscator para que incluso si el
código fuente es filtrado o robado por un atacante, el código fuente no sea fácil de
leer y descifrable. Este proceso generalmente implica complicar el código con
genéricos nombres de variables, bucles complicados, construcciones condicionales
y cambio de nombre textual y símbolos dentro del código a secuencias de
caracteres sin sentido. Ofuscado el código también se conoce como código
envuelto. La ofuscación no se limita solo a la fuente código, también se puede
utilizar para código objeto. Cuando se ofusca el código objeto, actúa como elemento
disuasorio de la ingeniería inversa.

Técnicas anti inversión

La ingeniería inversa o reversión es el proceso de recopilar información sobre los


detalles de diseño e implementación del software a partir del código objeto. Está
análogo a retroceder (revertir) en el ciclo de vida del desarrollo de software. Eso se
puede utilizar para fines legítimos, como comprender el plano del software,
especialmente en los casos en que la documentación no está disponible, pero hay
ramificaciones legales si el software no pertenece al inversor. Desde una seguridad
y punto de vista, la ingeniería inversa se puede utilizar para la investigación de
seguridad y para determinar vulnerabilidades en software publicado. Sin embargo,
también se conocen atacantes hábiles para realizar ingeniería inversa y descifrar
software, eludiendo las protecciones de seguridad como restricciones de licencia
implementadas en el código. También pueden manipular y reempacar software con
intenciones maliciosas. Esta es la razón por la que la protección contra la
manipulación de objetos el código es necesario. Además de utilizar la ofuscación
como control disuasorio contra el retroceso ingeniería, código objeto o ejecutables
también se pueden proteger de ser ingeniería inversa utilizando otros mecanismos
de protección anti-manipulación tales como eliminar información simbólica del
programa ejecutable (PE) e incrustar código anti-depurador. La eliminación de
información simbólica implica el proceso de eliminar cualquier información simbólica
como nombres de clases, miembros de clase nombres, nombres de objetos
instanciados globales, etc., y otra información textual del programa ejecutable
eliminandolos antes de la compilación o el uso de la ofuscación para cambiar el
nombre de los símbolos en secuencias de caracteres sin sentido. Incrustar código
anti-depurador significa que un detector de depurador de nivel de usuario o de
kernel se incluye como parte del código y detecta la presencia de un depurador y
termina el proceso cuando se encuentra uno. La API está presente el depurados y la
API Información del depurador del kernel del sistema son ejemplos de API comunes
que pueden aprovechar para implementar código anti-depurador.
Firma de código
La firma de código es el proceso de firmar digitalmente el código (ejecutables,
scripts, etc.) con la firma digital del autor del código. En la mayoría de los casos, la
firma de código es implementado utilizando sistemas de claves públicas y privadas y
firmas digitales. Cada cuando se crea el código, se puede firmar o se puede firmar
el código justo antes de la implementación. Los desarrolladores pueden generar su
propia clave o utilizar una clave emitida por un CA por firmar su código. Cuando los
desarrolladores no tienen acceso a la clave para firmando su código, pueden
firmarlo en una fase posterior del ciclo de vida del desarrollo, justo antes de la
implementación, y esto se conoce como firma retrasada. Firma retrasada permite
que el desarrollo continúe. Cuando el código se firma con el autor del código firma
digital, se genera un hash criptográfico de ese código. Este hash es publicado junto
con el software cuando se distribuye. Cualquier alteración del código dará como
resultado un valor hash que ya no coincidirá con el valor hash que se ha publicado.
Así es como la firma de código garantiza la integridad y la lucha contra la
manipulación.

La firma de código es particularmente importante cuando se trata de código móvil.


El código es un código que se descarga desde una ubicación remota. Ejemplos de
móvil el código incluye subprogramas de Java, componentes ActiveX, scripts de
navegador, Adobe Flash, y otros controles web. Es posible que la fuente del código
móvil no sea obvia. En tales situaciones, la firma de código se puede utilizar para
asegurar la prueba de origen o su autenticidad. La firma del código móvil también
proporciona el tiempo de ejecución (no el código en sí) permiso para acceder a los
recursos del sistema y garantiza la seguridad del código mediante sandboxing.
Además, la firma de código se puede utilizar para garantizar que no haya conflictos
de espacio de nombres y para proporcionar información de versiones cuando el
software está desplegado.

La firma de código asegura la autenticidad del código publicado (especialmente


código) además de proporcionar integridad y protección contra la manipulación.

Procesos de software seguros

La garantía de software es una confluencia de procesos y tecnologías seguros


implementado por personas capacitadas y capacitadas que entienden cómo diseñar,
desarrollar e implementar software seguro. Además de escribir código seguro,
existen ciertos procesos que deben llevarse a cabo durante la fase de
implementación que puede garantizar la seguridad del software. Éstos incluyen:
■ Control de versiones (gestión de la configuración)
■ Análisis de código
■ Código / revisión por pares

Versión (gestión de la configuración)

La gestión de la configuración tiene un impacto directo en el estado de la garantía


del software y es aplicable como parte del desarrollo y la implementación. La
configuración de la administración, ya que se aplica a la implementación, se cubre
con más detalle en el software. Capítulo de despliegue, operaciones, mantenimiento
y eliminación. En este capítulo, cubrirá la importancia de la gestión de la
configuración en lo que respecta al código desarrollo e implementación, más
particularmente el control de versiones del código fuente o control de versiones.

El control de versiones o versiones del software no solo garantiza que el equipo de


desarrollo está trabajando con la versión correcta del código, pero también ofrece la
capacidad de retroceder a una versión anterior en caso de que sea necesario.
Adicionalmente, el control de versiones del software brinda la capacidad de rastrear
la propiedad y los cambios de código. Si se realiza un seguimiento y se mantiene
cada versión del software, determinar y el análisis de la superficie de ataque de
cada versión puede proporcionar información sobre el RASQ y la tendencia general
de la seguridad del software. El control de versiones puede reducir las incidencias
de una condición conocida como errores regenerativos, donde reaparecen errores
previamente corregidos (se regeneran). Se sabe que esto ocurre cuando se corrigen
errores sin darse cuenta se sobrescribe cuando no se utiliza la versión correcta del
código.

Desde el punto de vista de la seguridad, es importante asegurarse de que el control


de versiones utilice lo que se llama bloqueos de archivos o pagos reservados. Esto
significa que cuando el código es revisado por alguien para cambios, nadie más
puede hacer cambios en el código hasta que se haya registrado. El desarrollo de
software más actual integrado los entornos de desarrollo (IDE) incluyen en ellos la
capacidad de hacer versionado.
Ejemplos bien conocidos de software de control de versiones incluyen: Visual fuente
segura (VSS), sistema de versiones concurrentes (CVS), equipo estrella y equipo
fundación del servidor (TFS).

Análisis de código
El análisis de código es el proceso de inspeccionar el código en busca de calidad y
debilidades que se pueden explotar. Se logra principalmente por dos medios;
estático y dinámico.

El análisis de código estático implica la inspección del código sin ejecutar el código
(o programa de software). Este análisis se puede realizar manualmente mediante lo
llamada revisión de código o de forma automatizada utilizando herramientas.
Cualquier código, independientemente de si se trata de código fuente, código byte o
código objeto, se puede analizar. Herramientas que se utilizan para realizar análisis
de código fuente estático se denominan comúnmente analizadores de código fuente
y herramientas que se utilizan para analizar el código de bytes intermedio se
conocen como escáneres de códigos de bytes. Las herramientas utilizadas para
analizar el código objeto de forma estática son denominadas analizadores binarios o
escáneres de códigos binarios. Analizadores de código fuente utilizar
predominantemente la coincidencia de patrones con una lista conocida de sintaxis
de vulnerabilidad y análisis de modelo / flujo de datos contra conjuntos de datos
conocidos para detectar vulnerabilidades. Los escáneres de código binario
funcionan bien como analizadores de código fuente estáticos, pero utilizan
desensamblaje, antes de la matriz de patrones y el análisis de datos contra códigos
ejecutables. La principal ventaja que tiene un analizador de código binario sobre el
código estático analizadores es que puede detectar vulnerabilidades e ineficiencias
de código que han introducido por el compilador, ya que está inspeccionando el
código objeto compilado, después del proceso de compilación. También tiene la
capacidad de buscar bibliotecas que están vinculadas durante el proceso de
compilación.

Los beneficios de realizar análisis de código estático son que los errores y las
vulnerabilidades se pueden detectar temprano y abordar antes de la implementación
del software. Hoy en día, la funcionalidad de análisis de código estático se
proporciona como parte del propio entorno de desarrollo integrado (IDE). Esto ayuda
en la detección de errores de seguridad en las primeras etapas del ciclo de vida,
durante la fase de desarrollo en sí mismo, además de proporcionar
retroalimentación inmediata al personal de desarrollo que aprende a partir de los
comentarios y las horas extraordinarias, desarrolle un código más seguro. Además
estático el análisis de código no requiere la necesidad de un entorno de producción
simulado y se puede realizar en el entorno de desarrollo o prueba. Esperando un
alto grado de seguridad del software simplemente utilizando herramientas de
análisis de código estático debe abordarse con precaución ya que existe la
posibilidad de un alto grado de falsas positivos y falsos negativos observados en la
mayoría de las herramientas. Estas herramientas deben usarse como ayuda para el
analista de seguridad, para que puedan centrarse en secciones de código inseguras
y abordar los errores de seguridad de forma más eficaz.

El análisis de código dinámico es la inspección del código cuando se está


ejecutando (ejecutar como un programa). Solo porque el código se compila sin
errores que puedan ser analizado mediante análisis de código estático, no significa
que se ejecutará sin cualquier error. Se puede realizar un análisis de código
dinámico para determinar que el código funciona de forma fiable como se esperaba
y no es propenso a errores o explotación. Para realizar un análisis dinámico con
precisión, un entorno simulado que refleja el entorno de producción donde se
implementará el código es necesario. Las herramientas utilizadas para el análisis de
código dinámico se conocen como código dinámico. analizadores y se pueden
utilizar para determinar cómo se ejecutará el programa interactúa con otros
procesos y con el propio sistema operativo.

Código / revisión por pares

Una forma de inspeccionar estáticamente el código es realizar una revisión del


código. Una revisión de código también se conoce como revisión por pares cuando
los pares del equipo de desarrollo son parte del proceso de revisión del código. Una
revisión de código se puede realizar manualmente o usando herramientas. Es una
evaluación sistemática del código fuente con el objetivo de averiguar problemas de
sintaxis y debilidades en el código que pueden afectar el rendimiento y seguridad
del software. Problemas semánticos como la lógica empresarial y fallas de diseño.
Generalmente no se detectan en una revisión de código, pero se puede usar una
revisión de código para validar el modelo de amenazas generado en la fase de
diseño del desarrollo del proyecto software. Se pueden utilizar herramientas para
automatizar e identificar vulnerabilidades rápidamente, pero no deben realizarse en
lugar de una revisión humana manual.

Cuando se lleva a cabo una revisión de código por razones de seguridad, el código
debe ser inspeccionado como mínimo para lo siguiente:

■ Código inseguro
■ Código ineficiente
El código inseguro es un código que tiene debilidades explotables. Inseguro común
las implementaciones de código incluyen:

Defectos de inyección

Compruebe el código que hace posibles los ataques por inyección. Los ejemplos
incluyen la falta de validación de entrada o la construcción dinámica de consultas
que aceptan datos proporcionados por el usuario sin la validación o desinfección
adecuadas. La revisión del código debe verificarse para asegurarse de que se haya
implementado la validación de entrada adecuada.

Mecanismos de no repudio

La revisión del código debe garantizar que la auditoría se implemente correctamente


y que la autenticidad del código y las acciones del usuario o del sistema no son
discutibles. Si la firma retrasada no es el caso, verifica para asegurarse de que el
código correctamente firmado debe llevarse a cabo como parte de la revisión.

Ataques de suplantación

Compruebe el código que posibilita los ataques de suplantación de identidad. Esta


comprobación debe garantizar que los identificadores de sesión no son predecibles,
las contraseñas no están codificadas, las credenciales no se almacenan en caché y
el código que permite cambios en la suplantación el contexto no está implementado.

Errores y excepciones

Manejo la revisión del código debe verificar para asegurarse de que los errores
cuando se informan no revelen más información de la necesaria y que el software
falla de forma segura cuando ocurren errores. Se debe implementar código para
manejar excepciones. El cheque para la presencia de bloques try-catch-finalmente
también debe verificar para asegurarse de que los objetos creados en código se
destruyen en los bloques finalmente.

Fuerza criptográfica

Se considera el código que utiliza algoritmos criptográficos personalizados o no


estándar débil y debe evitarse. Los algoritmos no deben codificarse de forma rígida,
ya que perjudican la agilidad criptográfica del software. El uso del número aleatorio
los generadores (RNG) y los generadores de números pseudoaleatorios (PRNG)
deben validado. Las claves tampoco deben estar codificadas y la revisión del código
debe garantizar que las protecciones criptográficas son sólidas para evitar cualquier
ataque criptoanalítico.

Funciones y rutinas inseguras y no utilizadas en el código

El código debe revisarse para asegurarse de que las API obsoletas y prohibidas no
sean usado. También se deben eliminar las funciones no utilizadas en el código.
Comprobaciones explícitas de cómo se deben realizar huevos de Pascua y
campanas y silbidos en código. Una buena manera de determinar si se requiere el
código es utilizar la matriz de trazabilidad de requisitos.

Código reversible

El código reversible es un código que se puede utilizar para determinar la


arquitectura interna y detalles de diseño e implementación de la funcionalidad del
software. El código debe ser revisado para comprobar si hay detectores de
depuradores y cualquier simbólico y textual se debe eliminar la información que
pueda ayudar a una ingeniería inversa.

Código privilegiado

El código privilegiado es un código que viola el principio de privilegio mínimo. Como


parte de la revisión del código, se deben realizar comprobaciones para garantizar
que el código que requiere los derechos administrativos de ejecución se controlan y
supervisan explícitamente.

Además, el código también debe revisarse para:

Ganchos de mantenimiento

Los ganchos de mantenimiento se introducen intencionalmente, un código


aparentemente inocuo que se implementa para satisfacer principalmente las
necesidades de mantenimiento. Son implantados para facilitar la resolución de
problemas y un mejor soporte. Los ganchos de mantenimiento pueden utilizarse
para hacerse pasar por un usuario que está experimentando problemas con el
software para volver a crear el problema como una forma de solucionarlo. También
pueden funcionar como puerta trasera y permitir a los desarrolladores acceder a
sistemas privilegiados (generalmente en entorno de producción) incluso si no se les
conceden derechos de autorización para esos sistemas. Deben considerarse
códigos críticos o de privilegios porque generalmente brindan acceso administrativo
con derechos ilimitados. Sin embargo, estos los ganchos de mantenimiento no
deben implementarse en el entorno de producción porque un atacante podría
aprovechar fácilmente el gancho de mantenimiento y obtener acceso por la puerta
trasera al sistema, a menudo eludiendo toda la protección de seguridad
mecanismos.

Bombas lógicas

Las bombas lógicas son problemas graves de seguridad del código, ya que se
pueden colocar en el código y pasar desapercibido si no se realiza una revisión del
código. Basado en la lógica (tal como condición o tiempo), se puede activar una
bomba lógica para que se active alguna operación malintencionada y no
intencionada cuando se cumple esa lógica. Bombas lógicas son implantados por
una persona con información privilegiada que tiene acceso al código fuente.
Descontento se sabe que los empleados que se sienten ofendidos por sus
empleadores implantan bombas lógicas en su código como medio de venganza
contra sus empleadores. Una bomba lógica no sólo causa la destrucción de datos,
sino que también puede interrumpir o provocar que el negocio se detenga por
completo. También se han utilizado para estafas de extorsión, donde el editor del
código amenaza al suscriptor con que activarán la bomba lógica en código a menos
que el suscriptor esté de acuerdo con los términos del editor. Cuando el código de
software no es desarrollado y controlado directamente por usted, como en el caso
de un subcontratista o tercero, revisión de código para determinar bombas lógicas
se vuelve extremadamente crítico. También es importante tener en cuenta que para
desactivar una prueba software después de un cierto período de tiempo (la
condición), que se comunicó por adelantado, no se considera una bomba lógica
porque no es maliciosa y funciona según lo previsto.

La revisión del código también debe identificar el código que es ineficiente ya que
puede tener un impacto directo en la seguridad del software. Haciendo un impropio
la llamada al sistema y las construcciones de bucle infinito son algunos ejemplos de
código ineficiente que puede conducir al compromiso del sistema, pérdidas de
memoria, agotamiento de recursos y denegación de servicio, lo que afecta la
confidencialidad, integridad y disponibilidad básicas principios de seguridad del
software. Específicamente, el código debe revisarse para eliminar
las siguientes ineficiencias:

Implementaciones de sincronización y temporización

Condiciones de carrera en el código que pueden resultar en canales encubiertos y


puntos muertos de recursos se puede identificar mediante una revisión de código.
Es importante asegurarse de que el código está construido para ser ejecutado de
una manera mutuamente excluyente (Mutex) por el tiempo y se pueden evitar los
problemas de sincronización. Esto es particularmente importante si el el código se
escribe para alterar el estado de un objeto compartido simultáneamente.

Complejidad ciclomática

La complejidad ciclomática es una medida del número de linealmente


independientes rutas en un programa. Es una métrica de software que se utiliza
para averiguar el alcance de la lógica de decisión dentro de cada módulo del código.
Altamente cohesivo y suelto el código acoplado tendrá pocas o ninguna
dependencia circular y, por lo tanto, será menos complejo. Los resultados de la
determinación de la complejidad ciclomática pueden utilizarse como indicador del
diseño de software en lo que respecta al principio de diseño de economía de
mecanismos y mecanismos menos comunes.

También es importante reconocer que el proceso de revisión del código es una


estructura y la actividad planificada y debe llevarse a cabo de manera constructiva.
primero y sobre todo, es el código y no el codificador lo que se está revisando, por lo
que el respeto mutuo de todos los miembros del equipo que forman parte de la
revisión del código es fundamental importante. Se recomienda que se asignen roles
y responsabilidades explícitos a los participantes de la revisión del código.
Moderadores que facilitan la revisión del código debe ser identificado, se espera que
un CSSLP funcione de esta manera. También es importante identificar quiénes
serán los revisores del código y nombrar un escribiente quién será responsable de
registrar las actas de la reunión de revisión del código para que los elementos de
acción que surgen de ella no se dejan sin abordar. Informar al revisor sobre el
código que se va a revisar en la reunión de revisión del código por adelantado y se
aconseja darles acceso seguro al código, para que los revisores vengan preparado
para la reunión. Como medio para demostrar la separación de funciones, el
programador que escribió el código no debería ser también el moderador o el
escribiente. Deben participar en la revisión del código con la mentalidad de aceptar
elementos de acción que deben abordarse. Los hallazgos de la revisión del código
deben comunicarse como comentarios constructivos en lugar de críticas al estilo de
codificación del programador o habilidad. Aprovechando los estándares de
codificación y las políticas internas y externas requisitos reglamentarios y de
cumplimiento para priorizar y manejar la revisión del código se recomiendan los
hallazgos.

Protección de entornos de construcción

El código fuente escrito por el programador debe convertirse en una forma que la
máquina pueda entender. Este proceso de conversión es genéricamente
denominado proceso de construcción. La integridad del entorno de construcción
donde el código fuente se convierte en código objeto es importante. La integridad
del el entorno de construcción se puede asegurar mediante:

■ Asegurar físicamente el acceso a los sistemas que crean código.


■ Usar listas de control de acceso (ACL) que evitan el acceso a personas no
autorizadas.
■ Usar software de control de versiones para asegurar que el código construido sea
de la versión correcta.
■ La automatización de la construcción es el proceso de creación de scripts o
automatización de las tareas que están involucrados en el proceso de construcción.
Se necesitan las actividades manuales realizadas por los miembros del equipo de
construcción a diario y automatizarlas. Algunas de estas actividades de compilación
incluyen: compilar fuente código en código de máquina, dependencias de
empaquetado, implementación e instalación. Cuando se utilizan scripts de
compilación para la automatización de compilación proceso, es importante
asegurarse de que los controles de seguridad y las comprobaciones no se eluden
cuando se utilizan estos scripts de compilación.

Además, es importante asegurarse de que se pueda construir el código fuente


heredado sin errores. Esto exige la necesidad de mantener el código fuente
heredado, el archivos de dependencia asociados que deben vincularse y el entorno
de compilación sí mismo. Dado que la mayoría del código heredado no se ha
diseñado ni desarrollado con seguridad en mente, es fundamental asegurarse de
que el estado seguro del ecosistema informático no se reduce cuando el código
fuente heredado se reconstruye y se vuelve a implementar.
Durante el proceso de construcción, la seguridad del software se puede aumentar,
utilizando funciones en las herramientas de compilación y scripts de compilación
automatizados. Los principales tipos de Las herramientas de compilación para
preparar el código para la implementación son los empaquetadores y los
empaquetadores.

Los empaquetadores se utilizan para crear software de modo que el software pueda
instalado sin errores. Se aseguran de que todas las dependencias y recursos que
son necesarios para que el software se ejecute son parte de la compilación del
software. El rojo Hat Package Manager (RPM) y Microsoft Installer (MSI) son
ejemplos de envasadores. Cuando se empaqueta el software, es importante
asegurarse de que no se introducen vulnerabilidades.

Los empaquetadores se utilizan para comprimir ejecutables principalmente con el


propósito de distribución y para reducir los requisitos de almacenamiento
secundario. Ejecutables empaquetados reducen el tiempo y el ancho de banda que
requieren los usuarios que descargan código y actualizaciones. Los ejecutables de
software empaquetados deben descomprimirse con el desempaquetador apropiado
y cuando se utilizan empacadores patentados y no publicados para empaquetar el
software ejecutable, proporcionan cierto grado de protección contra la ingeniería
inversa. Los ejecutables empaquetados plantean más desafíos a la inversa
ingeniero y es de naturaleza disuasoria, pero no impiden revertir los esfuerzos.
El software de empaque también se puede utilizar para ofuscar el contenido del
ejecutable, también es importante reconocer que los atacantes, especialmente los
escritores de malware, utilizan empaquetadores para empaquetar sus programas de
malware porque los empacadores transforman el apariencia de ejecutables para
evadir las herramientas de detección de malware basadas en firmas, pero no
afectan su semántica de ejecución de ninguna manera.

También podría gustarte