Get a Pentest and security assessment of your IT network.

Cyber Security

PHP strtoupper() SQL Injection Bypass

TL;DR

The strtoupper() function in PHP doesn’t prevent SQL injection attacks when used to sanitize user input before including it in a MySQL query. Attackers can bypass this by using character encoding tricks or database-specific functions that ignore case sensitivity, allowing them to inject malicious SQL code.

Solution Guide

  1. Understand the Problem: The strtoupper() function converts strings to uppercase. While it might seem like a security measure (e.g., comparing against known uppercase keywords), it’s easily bypassed because MySQL queries are often case-insensitive by default, and attackers can manipulate input to achieve their goals.
    • Case Insensitivity: MySQL doesn’t usually care if you use SELECT or select.
    • Character Encoding: Attackers can exploit different character encodings (e.g., UTF-8) to bypass case conversion.
  2. Identify Vulnerable Code: Look for code where user input is converted to uppercase using strtoupper() and then directly included in a MySQL query. For example:
  3. Bypass Techniques: Attackers can use several techniques to bypass strtoupper():
    • Mixed Case Encoding: Use a combination of uppercase and lowercase characters that, when interpreted by MySQL, result in the desired case-insensitive match. For example, `SeLeCt`.
    • Hexadecimal Representation: Use hexadecimal encoding to represent characters. MySQL can interpret hexadecimal representations correctly.
      SELECT * FROM users WHERE username = '0x53656c656374' -- Equivalent to SELECT
    • Database-Specific Functions: Some databases have functions that ignore case sensitivity. For example, in MySQL:
      SELECT * FROM users WHERE LOWER(username) = LOWER('$userInput')
  4. Prevent SQL Injection (Best Practices): The correct way to prevent SQL injection is not relying on functions like strtoupper(). Use these methods:
    1. Prepared Statements: Prepared statements with parameterized queries are the most effective defense.
      prepare("SELECT * FROM users WHERE username = ?");
      $stmt->execute([$userInput]);
      ?>
    2. Escaping User Input: If prepared statements aren’t possible, use database-specific escaping functions (e.g., mysqli_real_escape_string() for MySQL).
    3. Input Validation: Validate user input to ensure it conforms to expected formats. This reduces the attack surface.
  5. Example Attack Scenario: Consider the vulnerable code from step 2. An attacker could use a URL like this:
    http://example.com/?username=SeLeCt+*+FROM+users

    This would likely bypass the strtoupper() function and execute a malicious SQL query, potentially revealing all user data.

Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation