Incomplete regular expression for hostnames¶
ID: rb/incomplete-hostname-regexp Kind: problem Severity: warning Precision: high Tags: - correctness - security - external/cwe/cwe-020 Query suites: - ruby-code-scanning.qls - ruby-security-extended.qls - ruby-security-and-quality.qls
Sanitizing untrusted URLs is an important technique for preventing attacks such as request forgeries and malicious redirections. Often, this is done by checking that the host of a URL is in a set of allowed hosts.
If a regular expression implements such a check, it is easy to accidentally make the check too permissive by not escaping the
. meta-characters appropriately. Even if the check is not used in a security-critical context, the incomplete check may still cause undesirable behaviors when it accidentally succeeds.
Escape all meta-characters appropriately when constructing regular expressions for security checks, and pay special attention to the
The following example code checks that a URL redirection will reach the
example.com domain, or one of its subdomains.
class AppController < ApplicationController def index url = params[:url] host = URI(url).host # BAD: the host of `url` may be controlled by an attacker regex = /^((www|beta).)?example.com/ if host.match(regex) redirect_to url end end end
The check is however easy to bypass because the unescaped
. allows for any character before
example.com, effectively allowing the redirect to go to an attacker-controlled domain such as
Address this vulnerability by escaping
regex = /^((www|beta)\.)?example\.com/.
Common Weakness Enumeration: CWE-20.