跳转至

Index

正则表达式拒绝服务

描述

正则表达式拒绝服务 (ReDoS) 是一种安全漏洞,当利用用户输入来构造正则表达式时就会发生。在存在精心设计的正则表达式模式的情况下,应用程序可能会消耗大量资源,从而可能导致拒绝服务。

一些恶意模式的例子包括:

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

以下代码示例是不正确实现的说明:

```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'),
       ),
     ),
   ),
 );

} ```

建议

为了缓解正则表达式拒绝服务 (ReDoS) 漏洞,请考虑以下建议:

  • 最大限度地减少对用户输入的依赖: 只要可行,就尽量减少对用户提供的输入来构建正则表达式 (regex) 的依赖。考虑采用可减少基于用户输入动态生成正则表达式需求的替代方法或设计模式。通过限制暴露于潜在的恶意模式,您可以显着降低 ReDoS 漏洞的风险。

  • 验证用户输入: 实施强大的验证机制,以确保用户提供用于构建正则表达式的输入符合预定义标准。验证输入模式的长度、复杂性和结构,以降低恶意制作表达式的风险。通过在开始时验证输入,您可以先发制人地识别并拒绝潜在的有害模式。

  • 实施速率限制和超时机制: 应用速率限制和超时机制来限制与正则表达式评估相关的执行时间和资源消耗。对正则表达式匹配操作的复杂性和持续时间设置适当的限制,以防止计算开销过大。通过对正则表达式处理施加合理的约束,您可以缓解 ReDoS 攻击的风险,并确保您的应用程序在不断变化的输入条件下的稳定性。

```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.") }

```

链接

标准

  • 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