Saltar a contenido

Index

Denegación de servicio por expresión regular

Descripción

La Denegación de Servicio por Expresión Regular (ReDoS) es una vulnerabilidad de seguridad que se produce cuando se utiliza la entrada del usuario para construir una expresión regular. En presencia de un patrón de expresión regular cuidadosamente diseñado, la aplicación puede consumir una cantidad sustancial de recursos, lo que podría resultar en una denegación de servicio.

Algunos ejemplos de patrones maliciosos incluyen:

  • (a+)+
  • ([a-zA-Z]+)*
  • (a|aa)+
  • (a|a?)+
  • (.*a){x} for x > 10

Y los siguientes ejemplos de código son ilustraciones de implementaciones incorrectas:

```java import java.util.regex.*;

public class RegexVulnerabilityExample { public static void main(String[] args) { // Function to read user input, potentially malicious String userInput = getUserInput();

   // Constructing a regular expression using user input
   Pattern pattern = Pattern.compile(userInput);

   // Using the regular expression
   Matcher matcher = pattern.matcher("input_string");
   boolean matchFound = matcher.find();

   if (matchFound) {
       System.out.println("Match found!");
   } else {
       System.out.println("No match found!");
   }

} ```

```swift import Foundation

func checkRegex(input: String, regex: String) {

 // Constructing a regular expression using user input
 do {
     let regex = try NSRegularExpression(pattern: userInput)
     let range = NSRange(location: 0, length: input.utf16.count)
     let matchRange = regex.rangeOfFirstMatch(in: input, options: [], range: range)

     if matchRange.location != NSNotFound {
         print("Match found!")
     } else {
         print("No match found!")
     }
 } catch {
     print("Error: Invalid regular expression")
 }

}

// Call the function with user input checkRegex(input: "input_string",regex: "redos") ```

```dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart';

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Regex Vulnerability Example'), ), body: Center( child: ElevatedButton( onPressed: () { // Function to read user input, potentially malicious String userInput = getUserInput();

           // Constructing a regular expression using user input
           RegExp regex = RegExp(userInput);

           // Using the regular expression
           String inputString = "input_string";
           bool matchFound = regex.hasMatch(inputString);

           if (matchFound) {
             print("Match found!");
           } else {
             print("No match found!");
           }
         },
         child: Text('Test Regex'),
       ),
     ),
   ),
 );

} ```

Recomendación

Para mitigar las vulnerabilidades de Denegación de Servicio por Expresión Regular (ReDoS), considere las siguientes recomendaciones:

  • Minimizar la dependencia de la entrada del usuario: Siempre que sea posible, minimice la dependencia de la entrada proporcionada por el usuario para construir expresiones regulares (regex). Considere enfoques alternativos o patrones de diseño que reduzcan la necesidad de una generación dinámica de regex basada en la entrada del usuario. Al limitar la exposición a patrones potencialmente maliciosos, puede reducir significativamente el riesgo de vulnerabilidades ReDoS.

  • Validar la entrada del usuario: Implemente mecanismos de validación robustos para asegurar que la entrada proporcionada por el usuario para la construcción de regex se adhiera a criterios predefinidos. Valide la longitud, la complejidad y la estructura de los patrones de entrada para mitigar el riesgo de expresiones creadas maliciosamente. Al validar la entrada desde el principio, puede identificar y rechazar de forma preventiva patrones potencialmente dañinos.

  • Implementar mecanismos de limitación de tasa y tiempo de espera: Aplique mecanismos de limitación de tasa y tiempo de espera (timeout) para restringir el tiempo de ejecución y el consumo de recursos asociados con la evaluación de regex. Establezca límites adecuados en la complejidad y la duración de las operaciones de coincidencia de regex para evitar una sobrecarga computacional excesiva. Al imponer restricciones razonables en el procesamiento de regex, puede mitigar el riesgo de ataques ReDoS y asegurar la estabilidad de su aplicación bajo condiciones de entrada variables.

```java import java.util.Scanner; import java.util.concurrent.*;

public class TimeoutDatabaseCheckExample { public static void main(String[] args) { // Create a Scanner object to read user input Scanner scanner = new Scanner(System.in);

     // Prompt the user to enter a regex pattern
     System.out.print("Enter a regex pattern: ");
     String regexPattern = scanner.nextLine();

     // Set the timeout duration in milliseconds
     long timeoutDuration = 1000; // 1 second

     // Create an ExecutorService with a single thread
     ExecutorService executor = Executors.newSingleThreadExecutor();

     // Submit the database check task to the executor
     Future<Boolean> future = executor.submit(() -> {
         // Perform the database check operation
         return checkDatabase(regexPattern);
     });

     try {
         // Wait for the result with timeout
         boolean recordExists = future.get(timeoutDuration, TimeUnit.MILLISECONDS);

         // Check if the record exists in the database
         if (recordExists) {
             System.out.println("Record exists in the database!");
         } else {
             System.out.println("Record not found in the database.");
         }
     } catch (TimeoutException e) {
         // Handle timeout
         System.out.println("Database operation timed out.");
     } catch (InterruptedException | ExecutionException e) {
         // Handle other exceptions
         e.printStackTrace();
     } finally {
         // Shutdown the executor
         executor.shutdown();
     }

     // Close the scanner
     scanner.close();
 }

 // Hypothetical database check function
 public static boolean checkDatabase(String regexPattern) {
     // Perform the database check operation here
     // For demonstration purposes, assume the record exists if the regex pattern matches
     return Pattern.compile(regexPattern).matcher("record_from_database").find();
 }

}

```

```swift import Foundation

// Function to perform database check func checkDatabase(forRegexPattern regexPattern: String) -> Bool { // Perform the database check operation here // For demonstration purposes, assume the record exists if the regex pattern matches let inputString = "record_from_database" return inputString.range(of: regexPattern, options: .regularExpression) != nil }

// Function to perform database check with timeout func checkDatabaseWithTimeout(forRegexPattern regexPattern: String, timeout: TimeInterval) -> Bool? { var result: Bool?

 // Create a dispatch group
 let group = DispatchGroup()

 // Create a dispatch queue
 let queue = DispatchQueue.global()

 // Enter the dispatch group
 group.enter()

 // Asynchronously perform the database check operation
 queue.async {
     result = checkDatabase(forRegexPattern: regexPattern)
     // Leave the dispatch group when the operation is complete
     group.leave()
 }

 // Wait for the operation to complete with timeout
 let dispatchResult = group.wait(timeout: .now() + timeout)

 // Check if the operation timed out
 if dispatchResult == .timedOut {
     // Return nil indicating timeout
     return nil
 }

 // Return the result of the database check operation
 return result

}

// Function to get regex pattern from user input func getRegexPatternFromUser() -> String { print("Enter the regex pattern:") guard let input = readLine() else { return "" } return input }

// Example usage let regexPattern = getRegexPatternFromUser() let timeoutDuration = 1.0 // Timeout duration in seconds

if !regexPattern.isEmpty { if let recordExists = checkDatabaseWithTimeout(forRegexPattern: regexPattern, timeout: timeoutDuration) { if recordExists { print("Record exists in the database!") } else { print("Record not found in the database.") } } else { print("Database operation timed out.") } } else { print("Invalid regex pattern.") }

```

Enlaces

Estándares

  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
  • OWASP_MASVS_L1:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_v2_1:
    • MASVS_CODE_4
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
    • CC_9_1
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213
    • SECURITY255