php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #75661 FILTER_VALIDATE_DOMAIN allows characters that can lead to script injection
Submitted: 2017-12-10 08:56 UTC Modified: 2017-12-14 15:19 UTC
From: hanno at hboeck dot de Assigned:
Status: Not a bug Package: filter (PECL)
PHP Version: 7.2.0 OS:
Private report: No CVE-ID: None
 [2017-12-10 08:56 UTC] hanno at hboeck dot de
Description:
------------
The FILTER_VALIDATE_DOMAIN filter allows characters like spaces, semicolons and angle brackets.

These can't be part of a valid domain. But more importantly they make code that relies on FILTER_VALIDATE_DOMAIN prone to script injections.

I'll put an example script below that shows this. It takes a GET variable and first checks it with FILTER_VALIDATE_DOMAIN, afterwards passes the output to the ping command and will give the output to a user. Without knowing these limitations of FILTER_VALIDATE_DOMAIN this script appears safe, as one doesn't expect a domain name to have any characters that can pose trouble here. But it leads to a trivial script injection, e.g. by passing something "test; echo foo > bar" (creating a file "bar" on the targeted system) in the "domain" parameter.

FILTER_VALIDATE_DOMAIN is currently undocumented, so I think it's probably not widely used. Still this looks like a serious security problem to me.

This affects PHP 7.0, 7.1 and 7.2. PHP 5.6 didn't contain FILTER_VALIDATE_DOMAIN yet.

Test script:
---------------
<?php

$r = filter_var($_GET['domain'], FILTER_VALIDATE_DOMAIN);

if ($r === false) die("invalid domain");

system("ping -c 1 ".$_GET['domain']);


Expected result:
----------------
FILTER_VALIDATE_DOMAIN should reject input with characters that can't be part of a legitimate domain name.

Actual result:
--------------
It accepts various problematic characters (space, ;, >, <) that can easily lead to security problems if one relies on the filter.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-12-10 19:37 UTC] cmb@php.net
There are very few restrictions on a *domain* name (see RFC 2181,
section 11).  You are probably referring to *host* names, which
are indeed constrained as described.  To validate host names, you
have to pass FILTER_FLAG_HOSTNAME as flag, see
<https://3v4l.org/4LeI5>.
 [2017-12-12 08:02 UTC] stas@php.net
-Status: Open +Status: Not a bug
 [2017-12-12 08:02 UTC] stas@php.net
Since the RFC says "Those restrictions aside, any binary string whatever can be used as the label of any resource record." I don't think we should do more than RFC requires here. FILTER_VALIDATE_DOMAIN does not guarantee shell-safety or HTML safety - one should use appropriate quoting functions or whitelists or different filters for that. That said, since FILTER_VALIDATE_DOMAIN is not documented, maybe its intent was different than validating DNS domain strings? In that case, it should be documented properly.
 [2017-12-14 15:19 UTC] hanno at hboeck dot de
I figured out later that actually this is really RFC conform.
However I think this is quite problematic and given that due to lack of documentation it should be considered to change this. This sounds like an API that is a security trap and that's not good.

When people think "domain" they think "google.com" and not "; cat /etc/shadow".

I could think of two ways of moving forward:

1. Rename FILTER_VALIDATE_DOMAIN to FILTER_VALIDATE_RFC2128 or something that is less likely to be confused. Add FILTER_VALIDATE_HOSTNAME to do what right now FILTER_VALIDATE_DOMAIN does in combination with FILTER_FLAG_HOSTNAME.

2. Make FILTER_FLAG_HOSTNAME the default for FILTER_VALIDATE_DOMAIN and add another FILTER_FLAG_RFC2128.

In any case: The fact that this is undocumented makes it even more concerning, as people may find some info about it. At the very least there should be a documentation that is clear and makes sure it mentions all potential security concerns.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 13:01:30 2024 UTC