Gestión de Vulnerabilidades Base de conocimiento que contiene guías, procedimientos, manuales y técnicas para la solución/mitigación de vulnerabilidades. Servidores DNS Capítulo destinado a contramedidas para solucionar vulnerabilidades en servidores de nombres de dominio. Resolución abierta de DNS La vulnerabilidad Open Resolver DNS es una vulnerabilidad de seguridad que se refiere a los servidores de nombres de dominio (DNS) que han sido configurados de manera que permiten que cualquier persona en Internet realice consultas a través de ellos sin restricciones. Esto significa que un atacante puede enviar solicitudes de consulta DNS a estos servidores en grandes cantidades y utilizarlos como amplificadores en ataques de denegación de servicio distribuido (DDoS) contra otros sistemas en Internet. En un ataque de DDoS que utiliza la vulnerabilidad Open Resolver DNS, el atacante envía una gran cantidad de solicitudes de consulta DNS falsas a los servidores Open Resolver, y éstos responden a estas solicitudes enviando grandes cantidades de datos a las direcciones de origen de las solicitudes. Al enviar muchas solicitudes falsas desde diferentes direcciones, el atacante puede hacer que los servidores de destino se vean abrumados por el tráfico de red y se vuelvan inaccesibles. Para evitar la vulnerabilidad Open Resolver DNS, es importante que los administradores de sistemas configuren sus servidores DNS correctamente. Esto incluye restringir el acceso a los servidores de DNS, implementar listas de control de acceso (ACL), limitar el tamaño de los registros de consulta DNS, y actualizar el software de DNS regularmente para corregir vulnerabilidades conocidas. Configuración DNS en Bind9 Agregue lo siguiente a las opciones globales: Las opciones globales de BIND9 se definen en el archivo de configuración principal de BIND9, que normalmente se llama named.conf o named.conf.options . Este archivo de configuración principal generalmente se encuentra en el directorio /etc/bind/ o /etc/named/ en la mayoría de las distribuciones de Linux. options { allow-query-cache { none; }; recursion no; }; Configuración DNS de Microsoft En la herramienta de consola DNS de Microsoft: a. Primero, haga clic derecho en el servidor DNS y haga clic en Propiedades. b. Después de eso, haga clic en la pestaña Avanzado. c. Finalmente, en las opciones del servidor, seleccione la casilla de verificación "Deshabilitar recursividad" y luego haga clic en Aceptar. Configuración en postfix 3.x En el archivo de configuración /etc/postfix/main.cf En la variable “mydestination” NO deben estar los dominios locales: localhost.localdomain, localhost Aumentar los parametros (si no existiesen): mynetworks_style = host relay_domains = Tambien es valido: mynetworks_style = subnet Sugerencias a considerar Utilizar cortafuegos compatibles con el DNS y utilizar protección DDoS de terceros. Deshabilitar transferencia de zona La vulnerabilidad de transferencia de zona en los servidores DNS es una vulnerabilidad de seguridad que permite a un atacante obtener copias completas de la zona de nombres de un servidor DNS. La zona de nombres de un servidor DNS es un archivo que contiene información sobre los nombres de dominio y sus correspondientes direcciones IP. La transferencia de zona es un proceso legítimo utilizado por los servidores DNS para compartir información sobre los nombres de dominio entre ellos. Sin embargo, si la configuración del servidor DNS está mal configurada, un atacante puede aprovechar esta función legítima para obtener una copia completa de la zona de nombres, lo que le permitiría realizar ataques de denegación de servicio o identificar otros vectores de ataque. Los servidores DNS mal configurados pueden permitir a cualquier persona solicitar una transferencia de zona sin autenticación o permitir la transferencia de zona a cualquier dirección IP. Si un atacante identifica que un servidor DNS es vulnerable a la transferencia de zona, puede utilizar herramientas disponibles públicamente para realizar la transferencia de zona y obtener información sobre los nombres de dominio y direcciones IP. Es importante que los administradores de sistemas configuren correctamente los servidores DNS para evitar la vulnerabilidad de transferencia de zona y proteger la información confidencial. Las medidas de seguridad recomendadas incluyen restringir el acceso a la transferencia de zona solo a direcciones IP específicas y autenticar las solicitudes de transferencia de zona. Además, es importante mantener el software del servidor DNS actualizado con las últimas actualizaciones de seguridad para evitar vulnerabilidades conocidas. Deshabilitar transferencia de zona (Bind) En el archivo /etc/bind/named.conf adicionar: options { allow-transfer {"none";}; }; Servidores de correo Capítulo destinado a configuraciones específicas para mitigar/solucionar vulnerabilidades, errores de configuración en servidores de correo. Deshabilitar Open Relay interno y externo en Postfix Guía para evitar que personas no autorizadas envíen correos electrónicos a nombre del dominio de una entidad. Esta solución es para postfix con autenticación mediante dovecot. En caso de no tener instalado dovecot procedemos a su instalación: apt install dovecot-core dovecot-imapd Instalamos el plugin pcre de postfix: apt install postfix-pcre Configuramos el archivo /etc/postfix/main.cf de la siguiente manera: # See /usr/share/postfix/main.cf.dist for a commented, more complete version # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h readme_directory = no # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_tls_auth_only = yes ## SASL implementation smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for # information on enabling SSL in the smtp client. myhostname = dominio.gob.bo alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = $myhostname, localhost.dominio.gob.bo, localhost, dominio.gob.bo relayhost = recipient_delimiter = + inet_interfaces = all inet_protocols = all mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [IP servidor de correo] disable_vrfy_command = yes # Restricciones smtpd_helo_required = yes smtpd_sender_login_maps = pcre:/etc/postfix/controlled_envelope_senders.pcre smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname, reject_unknown_reverse_client_hostname, permit smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated ,reject_unauth_destination,reject_unknown_sender_domain, reject_sender_login_mismatch, permit Los parámetros a considerar son los siguientes: smtpd_sasl_auth_enable = yes : Habilitar la autenticación SASL en postfix. smtpd_sasl_type = dovecot : utilizar dovecot para la autenticación SASL. myhostname = dominio.gob.bo : Declaran los dominios a los que se autorizará mandar mensajes a través del servidor de correo. mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [IP servidor de correo] : Configurar la lista de direcciones IPs que pueden mandar correos. (Típicamente solo la IP interna del servidor de correo). smtpd_helo_required = yes : Exige que un cliente SMTP remoto se presente con el comando HELO o EHLO antes de enviar el comando MAIL u otros comandos que requieran negociación EHLO. smtpd_sender_login_maps = pcre:/etc/postfix/controlled_envelope_senders.pcre : Filtro de búsqueda opcional con el dominio de inicio de sesión SASL que poseen las direcciones del remitente (MAIL FROM). smtpd_client_restrictions : Restricciones de cliente permit_mynetworks .- Permite el envío de correo a clientes que coincidan con las direcciones descritas en mynetworks. reject_unknown_client_hostname .- Hace una comparación con la IP y nombre del cliente para verificar que coincidan, en caso de no coincidir rechaza la solicitud. reject_unknown_reverse_client_hostname .- Rechaza la solicitud cuando la dirección IP del cliente no tiene asignación de dirección-> nombre. permit : Permitir en caso de no ser rechazado en sentencias anteriores. smtpd_recipient_restrictions: Restricciones del recipiente (RCPT) permit_mynetworks .- Permite la solicitud a clientes que coincidan con las direcciones descritas en mynetworks. permit_sasl_authenticated .- Permite la solicitud cuando el cliente se haya autenticado correctamente a través del protocolo RFC 4954 (AUTH). reject_unauth_destination .- Rechaza la solicitud si el que envía no es un retransmisor permitido, ó si el receptor del mensaje no es un destino válido. reject_unknown_sender_domain .- Rechaza la solicitud cuando Postfix no es el destino final para la dirección del remitente y el dominio MAIL FROM tiene 1) ningún registro DNS MX ni DNS A, o 2) un registro MX con formato incorrecto, como un registro con un nombre de host MX de longitud cero. reject_sender_login_mismatch .- Rechaza la solicitud cuando $ smtpd_sender_login_maps especifica un propietario para la dirección MAIL FROM, pero el cliente no está (SASL) conectado como propietario de la dirección MAIL FROM. permit .- Permitir en caso de no ser rechazado en sentencias anteriores. Adicionalmente es necesario añadir el archivo controlled_envelope_senders.pcre en la dirección establecida, en este caso /etc/postfix/: #envelop sender owners (SASL login names) /^(.*)@dominio\.gob\.bo$/ ${1} Por último es necesario hacer una configuración en dovecot: Para versiones de dovecot que corresponden a postfix 2.7 se edita el archivo /etc/dovecot/dovecot.conf: client { # The client socket is generally safe to export to everyone. Typical use # is to export it to your SMTP server so it can do SMTP AUTH lookups # using it. #path = /var/run/dovecot/auth-client path = /var/spool/postfix/private/auth mode = 0660 user = postfix group = postfix } Para versiones posteriores se edita el archivo /etc/dovecot/conf.d/10-master.conf: service auth { # auth_socket_path points to this userdb socket by default. It's typically # used by dovecot-lda, doveadm, possibly imap process, etc. Its default # permissions make it readable only by root, but you may need to relax these # permissions. Users that have access to this socket are able to get a list # of all usernames and get results of everyone's userdb lookups. unix_listener auth-userdb { #mode = 0600 #user = #group = } # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } Misceláneo Capítulo destinado a la solución, mitigación de software en general. Mitigar enumeración de usuarios OpenSSH Utilizar versiones antiguas de openssh puede permitir la enumeración de usuarios en SSH, por lo cual es recomendable utilizar versiones posteriores a la 7.7 de OPENSSH, a continuación se detallará de cómo realizar la actualización mediante uso de repositorios. La presente guía fue probada en un servidor Debian 9.7 con versión 7.4 de OpenSSH. Visualizar la versión de OpenSSH utilizada: $ sshd -V Agregar el repositorio para la última version de openssh: $ nano /etc/apt/source.list Agregar al final: deb http://ftp.de.debian.org/debian sid main Actualizar la lista de paquetes: $ apt update Instalar OpenSSH: $ apt install openssh-server elegir opcion 1 (install the package maintainer’s version) Verificar la versión instalada: $ telnet localhost 22 SSH-2.0-OpenSSH_8.4p1 Debian-4 Si desea puede comentar le repositorio agregado en source.list $ nano /etc/apt/source.list Colocar # al comienzo de la línea añadida: # deb http://ftp.de.debian.org/debian sid main Actualizar la lista de paquetes: $ apt update Mitigar HearthBleed en OpenSSL La vulnerabilidad de OpenSSL desactualizado puede permitir a un atacante realizar una variedad de ataques, incluyendo la interceptación de datos cifrados y la inyección de código malicioso. Esta vulnerabilidad puede ser explotada por los atacantes mediante la explotación de una variedad de vulnerabilidades de seguridad conocidas en versiones antiguas de OpenSSL. Para evitar esta vulnerabilidad, es importante que los sistemas se mantengan actualizados con las últimas versiones de OpenSSL y otros software críticos. También es recomendable realizar auditorías periódicas de seguridad en los sistemas para identificar cualquier vulnerabilidad que pueda estar presente. Además, se deben aplicar medidas de seguridad adicionales, como la utilización de certificados SSL/TLS seguros y la implementación de políticas de autenticación adecuadas, para minimizar el riesgo de ataques. Actualización OpenSSL en Ubuntu Esta guía fue probada en un servidor Ubuntu con una versión inicial de OpenSSL de 0.9.8. Ejecutar el siguiente comando para ver la versión actual de openssl: $ openssl version Y como respuesta nos da la versión y el año de creación del OpenSSL: OpenSSL 0.9.8k 25 mar 2009 Descargar desde el repositorio de openssl el archivo al que se actualizará en este caso OpenSSL 1.1.1j: $ https://www.openssl.org/source/openssl-1.1.1j.tar.gz Desempaquetar: $ tar -zxf openssl-1.1.1j.tar.gz Emitir los siguientes comandos para la instalación: $ ./config $ make // (si el comando make no está instalado ejecutar $ sudo apt install make gcc) $ make install Creando un enlace desde el binario recién instalado a la ubicación predeterminada: $ sudo ln -s /usr/local/bin/openssl /usr/bin/openssl $ sudo ldconfig $ openssl version La respuesta debe ser parecida a la siguiente: OpenSSL 1.1.1j 16 Feb 2021 Aplicaciones web Capítulo destinado a la solución de vulnerabilidades en aplicaciones web. Inyección SQL Sin la eliminación o citación suficiente de la sintaxis SQL en las entradas controlables por el usuario, la consulta SQL generada puede hacer que esas entradas se interpreten como SQL en lugar de datos de usuario ordinarios. Esto se puede usar para alterar la lógica de consulta para eludir las comprobaciones de seguridad o para insertar declaraciones adicionales que modifican la base de datos de back-end, posiblemente incluyendo la ejecución de comandos del sistema. La inyección SQL se ha convertido en un problema común con los sitios web basados en bases de datos. La falla se detecta y explota fácilmente y, como tal, es probable que cualquier sitio o paquete de software con una base mínima de usuarios esté sujeto a un intento de ataque de este tipo. Esta falla depende del hecho de que SQL no hace una distinción real entre los planos de control y de datos. Inyección SQL PHP - Solución La solución aplica para aplicaciones que no usan ningún framework como base de desarrollo. Opción a) Usar esta opción en versiones de PHP 4 > = 4.3.0 hasta versiones anteriores a PHP 5.5.0. $id=mysqlrealescapestring($GET["id"]); // sanitizando el parámetro id (ejemplo) Opción b) Ejemplo, valida el parámetro id $id=$GET["id"]; $id=str_replace("'","",$id); $id=str_replace('"','',$id); $id=str_replace(')','',$id); $id=str_replace('-','',$id); $id=str_replace('%','',$id); Opción c) Usar consultas parametrizadas https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php También es importante realizar la verificación y validación en el resto de campos de entrada que existan en formularios o parámetros en URL de su sitio web. Inyección SQL ASP.net - solución Comience restringiendo la entrada en el código del lado del servidor para sus páginas web ASP.NET. No confíe en la validación del lado del cliente porque se puede omitir fácilmente. Use la validación del lado del cliente solo para reducir los viajes de ida y vuelta y mejorar la experiencia del usuario. Si usa controles de servidor, use los controles de validación de ASP.NET, como los controles RegularExpressionValidator y RangeValidator para restringir la entrada. Si usa controles de entrada HTML regulares, use la clase Regex en su código del lado del servidor para restringir la entrada. Opción a) Puede restringir su entrada usando un control RegularExpressionValidator como se muestra a continuación: <%@ language="C#" %>
Si la entrada de SSN proviene de otra fuente, como un control HTML, un parámetro de cadena de consulta o una cookie, puede restringirla usando la clase Regex del espacio de nombres System.Text.RegularExpressions . El siguiente ejemplo asume que la entrada se obtiene de una cookie. Opción b) Usando System.Text.RegularExpressions; if (Regex.IsMatch(Request.Cookies["SSN"], "^\d{3}-\d{2}-\d{4}$")) { // access the database } else { // handle the bad input } Opción c) Usar parámetros con procedimientos almacenados: El uso de procedimientos almacenados no impide necesariamente la inyección de SQL. Lo importante es usar parámetros con procedimientos almacenados. Si no usa parámetros, sus procedimientos almacenados pueden ser susceptibles a la inyección SQL si usan entrada sin filtrar como se describe en la sección "Descripción general" de este documento. El siguiente código muestra cómo usar SqlParameterCollection al llamar a un procedimiento almacenado. using System.Data; using System.Data.SqlClient; using (SqlConnection connection = new SqlConnection(connectionString)) { DataSet userDataset = new DataSet(); SqlDataAdapter myCommand = new SqlDataAdapter( "LoginStoredProcedure", connection); myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; myCommand.Fill(userDataset); } En este caso, el parámetro @au_id se trata como un valor literal y no como un código ejecutable. Además, se comprueba el tipo y la longitud del parámetro. En el ejemplo de código anterior, el valor de entrada no puede tener más de 11 caracteres. Si los datos no se ajustan al tipo o la longitud definidos por el parámetro, la clase SqlParameter genera una excepción. Opción d) Usar parámetros con SQL dinámico: Si no puede usar procedimientos almacenados, aún debe usar parámetros cuando construya sentencias SQL dinámicas. El siguiente código muestra cómo usar SqlParametersCollection con SQL dinámico. using System.Data; using System.Data.SqlClient; using (SqlConnection connection = new SqlConnection(connectionString)) { DataSet userDataset = new DataSet(); SqlDataAdapter myDataAdapter = new SqlDataAdapter( "SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", connection); myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; myDataAdapter.Fill(userDataset); } Opción e) Uso de procesamiento por lotes de parámetros: Un concepto erróneo común es que si concatena varias sentencias SQL para enviar un lote de sentencias al servidor en un solo viaje de ida y vuelta, no puede usar parámetros. Sin embargo, puede usar esta técnica si se asegura de que los nombres de los parámetros no se repitan. Puede hacer esto fácilmente asegurándose de usar nombres de parámetros únicos durante la concatenación de texto SQL, como se muestra aquí. using System.Data; using System.Data.SqlClient; . . . using (SqlConnection connection = new SqlConnection(connectionString)) { SqlDataAdapter dataAdapter = new SqlDataAdapter( "SELECT CustomerID INTO #Temp1 FROM Customers " + "WHERE CustomerID > @custIDParm; SELECT CompanyName FROM Customers " + "WHERE Country = @countryParm and CustomerID IN " + "(SELECT CustomerID FROM #Temp1);", connection); SqlParameter custIDParm = dataAdapter.SelectCommand.Parameters.Add( "@custIDParm", SqlDbType.NChar, 5); custIDParm.Value = customerID.Text; SqlParameter countryParm = dataAdapter.SelectCommand.Parameters.Add( "@countryParm", SqlDbType.NVarChar, 15); countryParm.Value = country.Text; connection.Open(); DataSet dataSet = new DataSet(); dataAdapter.Fill(dataSet); } . . . Inyección SQL JAVA - solución La solución más simple es usar PreparedStatement en lugar de Statement para ejecutar la consulta. En lugar de concatenar el nombre de usuario y la contraseña en la consulta, los proporcionamos para consultar a través de los métodos de establecimiento de PreparedStatement. Ahora, el valor del nombre de usuario y la contraseña recibidos de la solicitud se tratan solo como datos, por lo que no se producirá una inyección SQL. Veamos el código del servlet modificado. String query = "select * from tbluser where username=? and password = ?"; Connection conn = null; PreparedStatement stmt = null; //Las credenciales utilizadas son de ejemplo, se recomienda utilizar contraseñas robustas try { conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user", "root", "root"); stmt = conn.prepareStatement(query); stmt.setString(1, username); stmt.setString(2, password); ResultSet rs = stmt.executeQuery(); if (rs.next()) { // Login Successful if match is found success = true; } rs.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { stmt.close(); conn.close(); } catch (Exception e) { } } Entendamos lo que está pasando en este caso. Consulta : seleccione * de tbluser donde nombre de usuario =? y contraseña = ? El signo de interrogación (?) en la consulta anterior se denomina parámetro posicional. Hay 2 parámetros posicionales en la consulta anterior. No concatenamos nombre de usuario y contraseña para consultar. Usamos métodos disponibles en PreparedStatement para proporcionar información de usuario. Hemos configurado el primer parámetro usando stmt.setString(1, username) y el segundo parámetro usando stmt.setString(2, password). La API de JDBC subyacente se encarga de desinfectar los valores para evitar la inyección de SQL. Deshabilitar phpinfo La función phpinfo() en PHP muestra información detallada sobre la configuración de PHP instalada en el servidor, incluyendo la versión de PHP, módulos cargados, variables de entorno y configuración del servidor. Si esta función se deja activa en un servidor web público, puede ser una vulnerabilidad de seguridad. Esto se debe a que los atacantes pueden utilizar la información expuesta en la función phpinfo() para encontrar vulnerabilidades conocidas en la versión de PHP, los módulos instalados o la configuración del servidor. Los atacantes pueden utilizar esta información para desarrollar ataques específicos que exploten las vulnerabilidades conocidas. Por lo tanto, es una buena práctica deshabilitar la función phpinfo() en servidores web públicos o restringir el acceso a esta función solo a usuarios de confianza. Se recomienda también mantener actualizada la versión de PHP y sus módulos instalados para reducir el riesgo de vulnerabilidades conocidas. Deshabilitar phpinfo en Linux Abrir el archivo de configuración de PHP (php.ini). Rutas por defecto en servidores En servidores apache el archivo php.ini se encuentra en la siguiente ruta: /etc/php/[VERSION]/apache2/ En servidores Nginx el archivo php.ini se encuentra en la siguiente ruta: /etc/php/[VERSION]/fpm Una vez encontrado el archivo php.ini se debe realizar lo siguiente: Buscar la línea que contiene la directiva "disable_functions" y agregue "phpinfo" a la lista separada por comas de funciones deshabilitadas. disable_functions = phpinfo Guarde el archivo php.ini y reinicie su servidor web para que los cambios surtan efecto. Reiniciar Apache: Abre una línea de comandos en el servidor. Ejecuta el siguiente comando para reiniciar el servicio de Apache: //para versiones modernas de Linux que usan systemd sudo systemctl restart apache2 //para versiones antiguas de Linux sudo service apache2 restart Reiniciar Nginx: Abre una línea de comandos en el servidor. Ejecuta el siguiente comando para reiniciar el servicio de Nginx: //para versiones modernas de Linux que usan systemd sudo systemctl restart nginx //para versiones antiguas de Linux sudo service nginx restart Deshabilitar phpinfo en Windows Ubicación del archivo php.ini en Windows utilizando XAMPP Abre el cmd. Luego dirigirse a la carpeta donde esta instalada PHP en su unidad c. Por ejemplo: cd c:xamppphp Una vez encontrado el archivo php.ini se debe realizar lo siguiente: Buscar la línea que contiene la directiva "disable_functions" y agregue "phpinfo" a la lista separada por comas de funciones deshabilitadas. disable_functions = phpinfo Guarde el archivo php.ini y reinicie su servidor web para que los cambios surtan efecto. Reiniciar WIndows con XAMPP instlado: Abre la consola de XAMPP desde el menú de inicio o buscando la aplicación en la carpeta de instalación. En la consola de XAMPP, detén los servicios de Apache y MySQL haciendo clic en el botón "Stop" para cada uno de ellos. Asegúrate de que ambos servicios estén detenidos antes de continuar. Una vez que se hayan detenido los servicios, cierra la consola de XAMPP. Abre el menú Inicio de Windows y haz clic en el botón de "Apagar" para mostrar las opciones de apagado. Selecciona "Reiniciar" para reiniciar el servidor. Espera a que el servidor se reinicie completamente y vuelve a abrir la consola de XAMPP. En la consola de XAMPP, inicia los servicios de Apache y MySQL haciendo clic en el botón "Start" para cada uno de ellos. Asegúrate de que ambos servicios estén iniciados antes de continuar. Verifica que tus sitios web o aplicaciones estén funcionando correctamente. Cross-Site Scripting XSS XSS Cross-Site Scripting (o "Inyección de scripts entre sitios", en español). Es un tipo de vulnerabilidad de seguridad en aplicaciones web, donde un atacante puede insertar código malicioso (como JavaScript) en una página web, que luego se ejecutará en el navegador de un usuario que visite esa página. Los ataques XSS ocurren cuando una aplicación web no valida correctamente las entradas de los usuarios, permitiendo que un atacante inserte código malicioso en una página web que se servirá a otros usuarios. El código malicioso puede ser diseñado para robar información personal, redirigir a los usuarios a sitios web maliciosos, mostrar anuncios no deseados, o incluso para tomar control del navegador del usuario. Existen dos tipos principales de ataques XSS: Reflejado: El ataque XSS reflejado ocurre cuando el código malicioso se ejecuta en la página web después de que un usuario hace una solicitud a la aplicación web. El código malicioso se "refleja" de vuelta al usuario a través de la respuesta de la aplicación web. Almacenado: El ataque XSS almacenado ocurre cuando el código malicioso se almacena en la base de datos de la aplicación web y se ejecuta cada vez que se solicita la página web afectada. Los desarrolladores pueden prevenir ataques XSS mediante la validación y filtrado de las entradas de los usuarios, utilizando bibliotecas de seguridad como Content Security Policy (CSP) y asegurándose de que todas las entradas de los usuarios se escapen de forma adecuada antes de ser utilizadas en una página web. Sanitización de XSS en PHP Aquí hay un ejemplo de cómo mitigar el riesgo de XSS en PHP utilizando la función "htmlspecialchars()" para escapar las salidas de usuario: Test"; $valid = htmlspecialchars($param, ENT_QUOTES, 'UTF-8'); echo $valid // Test ?> En este ejemplo, estamos utilizando la función "htmlspecialchars()" para escapar los caracteres especiales HTML en la entrada del usuario. La función toma tres argumentos: la cadena de entrada a escapar, la opción ENT_QUOTES para escapar tanto comillas dobles como comillas simples, y la codificación de caracteres 'UTF-8'. Sanitización XSS en Laravel Este método fue probado para Laravel 7, y consiste en crear un middleware para sanitizar las entradas. El middleware proporciona un mecanismo conveniente para inspeccionar y filtrar las solicitudes HTTP que ingresan a su aplicación. Para crear un middleware se debe aplicar el siguiente comando en la raíz del proyecto de Laravel: php artisan make:middleware XssSanitizer Editar el archivo app/Http/Middleware/XssSanitizer.php para que quede de la siguiente manera: all(); array_walk_recursive($input, function(&$input) { $input = strip_tags($input); }); $request->merge($input); return $next($request); } } Ahora es necesario agregar la ruta de XssSanitizer.php al vector $routeMiddleware ubicado en app/Http/Kernel.php: protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, .... 'XssSanitizer' => \App\Http\Middleware\XssSanitizer::class, ]; Una vez realizado esto, ya se puede utilizar XssSanitizer middleware en las rutas para realizar la sanitización: Route::group(['middleware' => ['XssSanitizer']], function () { Route::get('/', function () { return view('welcome'); }); Route::get('/formulario',function () { return view('formulario'); }); Route::get('form-get', function (Illuminate\Http\Request $request) { return $request->input('buscar'); })->name('form-get'); }); Despliegue de mensajes de error El software genera un mensaje de error que incluye información confidencial sobre su entorno, usuarios o datos asociados. La información confidencial puede ser información valiosa por sí misma (como una contraseña, nombres de usuario), o puede ser útil para lanzar ataques dirigidos. Un atacante puede usar el contenido de los mensajes de error para ayudar a lanzar otro ataque más enfocado. Deshabilitar el despliegue de errores en PHP El manual de PHP recomienda deshabilitar "display_errors" en servidores expuestos a Internet. Para PHP 5.2.4 y superior, la configuración "display_errors" en el archivo de configuración "php.ini" debe establecerse en "stderr" (flujo de salida de error), en lugar de " stdout " (flujo de salida enviado a los clientes). display_errors = stderr Para versiones anteriores, "display_errors" es un tipo booleano y se puede establecer en "False" para desactivarlo. La configuración también se puede deshabilitar en tiempo de ejecución usando ini_set() desde dentro de un script PHP. display_error = False Deshabilitar el despliegue de errores en Framework Yii 2.0 Yii incluye embebido un Error Exception Handler que hace del manejo de errores una experiencia mucho más llevadera. El manejo de excepciones está habilitado por defecto. Se puede deshabilitar definiendo la constante global "YII_ENABLE_ERROR_HANDLER" a “ "false" en el script de entrada (Entry Scripts) de la aplicación. YII_ENABLE_ERROR_HANDLER = false Variables de entorno en PHP Una variable de entorno es un valor dinámico que se almacena en el sistema operativo y que puede ser utilizado por diferentes aplicaciones y procesos en un sistema informático. Estas variables contienen información que puede ser utilizada por programas y scripts para personalizar su comportamiento y configuración. Las variables de entorno se establecen y se gestionan a nivel del sistema operativo, y están disponibles para cualquier programa que se ejecute en el sistema. Estas variables pueden contener información como la ubicación de ciertos archivos o directorios, el nombre del usuario actual, la configuración regional o cualquier otra información que se considere útil para el funcionamiento de las aplicaciones. Las variables de entorno son útiles para personalizar y automatizar el comportamiento de los programas y scripts, y también pueden ser utilizadas para compartir información entre diferentes aplicaciones y procesos en el sistema. Variables de entorno en Apache Opción a) Puede agregar la siguiente instrucción desde el archivo de configuración que se encuentra en /etc/apache2/sites-available