Skip to content

Insecure hostname validation check

Insecure hostname validation check

Description

The application performs insecure hostname validation using easy to bypass methods like startsWith or endsWith. An attacker can easily bypass this check by registering a domain that matches the check pattern.

Composite checks with both startsWith and endsWith are equally insecure as the attack can still create domain with random middle input that matches the checked pattern.

Recommendation

To ensure a safe validation of the hostname, consider the implementations below.

  1. Implement Regular Expression (Regex) Validation: Instead of using simple methods like startsWith or endsWith, opt for regular expressions to perform thorough hostname validation. Regex patterns can allow for precise matching criteria.

  2. Consider Standardized Validation Libraries: Utilize established libraries or frameworks that offer robust hostname validation functionalities. These libraries are often well-maintained and regularly updated to address potential security flaws.

  3. Implement Whitelisting: If you have a limited number of whitelisted hosts, consider implementing a whitelist approach where only known and trusted hostnames are accepted by the application.

import java.util.regex.*;

public class SubdomainValidator {
    public static void main(String[] args) {
        String userInput = "sub.example.com"; // replace this with user input

        // Regular expression pattern to match subdomains of example.com
        String pattern = "^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+example\\.com$";

        // Create a Pattern object
        Pattern r = Pattern.compile(pattern);

        // Create Matcher object
        Matcher m = r.matcher(userInput);

        // Check if input matches the pattern
        if (m.find()) {
            System.out.println("Valid subdomain of example.com");
        } else {
            System.out.println("Invalid subdomain of example.com");
        }
    }
}
import Foundation

func isValidSubdomain(_ userInput: String) -> Bool {
    let pattern = #"^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+example\.com$"# // Regular expression pattern
    let regex = try! NSRegularExpression(pattern: pattern)
    let range = NSRange(location: 0, length: userInput.utf16.count)
    return regex.firstMatch(in: userInput, options: [], range: range) != nil
}

let userInput = "sub.example.com" // replace this with user input
if isValidSubdomain(userInput) {
    print("Valid subdomain of example.com")
} else {
    print("Invalid subdomain of example.com")
}
import 'package:flutter/material.dart';

bool isValidSubdomain(String userInput) {
  RegExp regex = RegExp(r'^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+example\.com$');
  return regex.hasMatch(userInput);
}

void main() {
  String userInput = "sub.example.com"; // replace this with user input
  if (isValidSubdomain(userInput)) {
    print("Valid subdomain of example.com");
  } else {
    print("Invalid subdomain of example.com");
  }
}

Standards

  • OWASP_MASVS_L1:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • CWE_TOP_25:
    • CWE_20
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_3
    • REQ_11_3
  • 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