Saltar al contenido

Cómo reparar Veracode CWE 117 (neutralización de salida incorrecta para registros)

Solución:

¿Hay alguna forma de solucionar esta vulnerabilidad sin cambiar el registrador a ESAPI?

En resumen, sí.

TLDR:

Primero, comprenda la gravedad del error. La principal preocupación es la falsificación de las declaraciones de registros. Digamos que tenía un código como este:

log.error( transactionId + " for user " + username + " was unsuccessful."

Si cualquiera de las variables está bajo el control del usuario, pueden inyectar declaraciones de registro falsas utilizando entradas como rn for user foobar was successfulrn lo que les permite falsificar el registro y cubrir sus huellas. (Bueno, en este caso artificial, solo haz que sea un poco más difícil ver lo que sucedió).

El segundo método de ataque es más un movimiento de ajedrez. Muchos registros están formateados HTML para ser vistos en otro programa, para este ejemplo, pretendemos que los registros son archivos HTML para ser vistos en un navegador. Ahora inyectamos <script src=”https://evilsite.com/hook.js” type=”text/javascript”></script> y habrá enganchado un navegador con un marco de explotación que probablemente se esté ejecutando como administrador del servidor … porque es dudoso que el CEO vaya a leer el registro. Ahora puede comenzar el verdadero truco.

Defensas:

Una defensa simple es asegurarse de que todas las declaraciones de registro con entrada de usuario escapen de los caracteres ‘ n’ y ‘ r’ con algo obvio, como ‘֎’ o puede hacer lo que hace ESAPI y escapar con el guión bajo. Realmente no importa siempre que sea consistente, solo tenga en cuenta que no debe usar conjuntos de caracteres que lo confundirían en el registro. Algo como userInput.replaceAll("r", "֎").replaceAll("n", "֎");

También me resulta útil asegurarme de que los formatos de registro se especifiquen de manera exquisita … lo que significa que debe asegurarse de tener un estándar estricto sobre el aspecto que deben tener las declaraciones de registro y construir su formato para que la captura de un usuario malintencionado sea más fácil. ¡Todos los programadores deben presentarse a la fiesta y seguir el formato!

Para defenderme del escenario HTML, usaría el [OWASP encoder project][1]

En cuanto a por qué se sugiere la implementación de ESAPI, es una biblioteca muy probada en batalla, pero en pocas palabras, esto es esencialmente lo que hacemos. Ver el código:

/**
 * Log the message after optionally encoding any special characters that might be dangerous when viewed
 * by an HTML based log viewer. Also encode any carriage returns and line feeds to prevent log
 * injection attacks. This logs all the supplied parameters plus the user ID, user's source IP, a logging
 * specific session ID, and the current date/time.
 *
 * It will only log the message if the current logging level is enabled, otherwise it will
 * discard the message.
 *
 * @param level defines the set of recognized logging levels (TRACE, INFO, DEBUG, WARNING, ERROR, FATAL)
 * @param type the type of the event (SECURITY SUCCESS, SECURITY FAILURE, EVENT SUCCESS, EVENT FAILURE)
 * @param message the message to be logged
 * @param throwable the {@code Throwable} from which to generate an exception stack trace.
 */
private void log(Level level, EventType type, String message, Throwable throwable) {

    // Check to see if we need to log.
    if (!isEnabledFor(level)) {
        return;
    }

    // ensure there's something to log
    if (message == null) {
        message = "";
    }

    // ensure no CRLF injection into logs for forging records
    String clean = message.replace('n', '_').replace('r', '_');
    if (ESAPI.securityConfiguration().getLogEncodingRequired()) {
        clean = ESAPI.encoder().encodeForHTML(message);
        if (!message.equals(clean)) {
            clean += " (Encoded)";
        }
    }

    // log server, port, app name, module name -- server:80/app/module
    StringBuilder appInfo = new StringBuilder();
    if (ESAPI.currentRequest() != null && logServerIP) {
        appInfo.append(ESAPI.currentRequest().getLocalAddr()).append(":").append(ESAPI.currentRequest().getLocalPort());
    }
    if (logAppName) {
        appInfo.append("https://foroayuda.es/").append(applicationName);
    }
    appInfo.append("https://foroayuda.es/").append(getName());

    //get the type text if it exists
    String typeInfo = "";
    if (type != null) {
        typeInfo += type + " ";
    }

    // log the message
    // Fix for https://code.google.com/p/owasp-esapi-java/issues/detail?id=268
    // need to pass callerFQCN so the log is not generated as if it were always generated from this wrapper class
    log(Log4JLogger.class.getName(), level, "[" + typeInfo + getUserInfo() + " -> " + appInfo + "] " + clean, throwable);
}

Vea las líneas 398-453. Eso es todo el escape que proporciona ESAPI. Sugeriría copiar también las pruebas unitarias.

[DISCLAIMER]: Soy codirector del proyecto en ESAPI.

[1]: https://www.owasp.org/index.php/OWASP_Java_Encoder_Project y asegúrese de que sus entradas estén codificadas correctamente cuando ingrese en las declaraciones de registro, tanto como cuando envíe las entradas al usuario.

Soy nuevo en Veracode y me enfrentaba a CWE-117. Entiendo que Veracode genera este error cuando su declaración del registrador tiene el potencial de ser atacada a través de los valores de los parámetros de la solicitud maliciosa pasados. Por lo tanto, debemos eliminar / r y / n (CRLF) de las variables que se utilizan en la declaración del registrador.

La mayoría de los novatos se preguntarán qué método se debe usar para eliminar CRLF de la variable pasada en la declaración del registrador. También en algún momento replaceAll () no funcionará ya que no es un método aprobado por Veracode. Por lo tanto, aquí está el enlace a los métodos aprobados por Veracode para manejar los problemas de CWE. https://help.veracode.com/reader/4EKhlLSMHm5jC8P8j3XccQ/IiF_rOE79ANbwnZwreSPGA

En mi caso, he usado org.springframework.web.util.HtmlUtils.htmlEscape mencionado en el enlace anterior y resolvió el problema.

private static final Logger LOG = LoggerFactory.getLogger(MemberController.class);
//problematic logger statement 
LOG.info("brand {}, country {}",brand,country);
//Correct logger statement
LOG.info("brand {}, country {}",org.springframework.web.util.HtmlUtils.htmlEscape(brand),org.springframework.web.util.HtmlUtils.htmlEscape(country));

Para evitar la vulnerabilidad Veracode CWE 117, he usado una clase de registrador personalizada que usa la función HtmlUtils.htmlEscape () para mitigar la vulnerabilidad. La solución recomendada a este problema por Veracode es usar registradores ESAPI, pero si no desea agregar una dependencia adicional a su proyecto, esto debería funcionar bien. https://github.com/divyashree11/VeracodeFixesJava/blob/master/spring-annotation-logs-demo/src/main/java/com/spring/demo/util/CustomLogger.java

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *