|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #78011 pathinfo behavior regarding extensions can lead to XSS risk
Submitted: 2019-05-14 14:12 UTC Modified: 2019-05-16 07:55 UTC
From: hanno at hboeck dot de Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 7.3.5 OS:
Private report: No CVE-ID: None
 [2019-05-14 14:12 UTC] hanno at hboeck dot de
With the pathinfo function a script can check a file extension. However the interpretation of "file extension" differs from common webserver behavior (tested on apache) on a file that only consists of a dot and an extension (e.g. .jpg).

This can lead to a Cross Site Scripting vulnerability. Imagine the following situation:
A web page allows users to upload files, but it only allows them to upload jpg files. To validate that the script will call pathinfo (e.g. "pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION)") and compare it to jpg and will reject the upload otherwise.
These should be safe, as a web server will serve all *.jpg files with an image/jpeg mime type. However a .jpg file will bypass that check and the webserver will deliver it (depending on its configuration) either without a mime type or with an autodetected mimetype. Both lead to XSS.

I put a small example script below that exposes this behavior.

I haven't yet found a real world example of this, but this looks like a problematic behavior that can easily lead to XSS unless a developer is very familiar with the subtleties of web servers and pathinfo. I recommend that PHP pathinfo() interprets a .jpg file as a file named ".jpg" without an extension.

Test script:
if (array_key_exists("upload", $_FILES)) {
    if (pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION) != 'jpg') {
        die("Only jpg allowed");
    move_uploaded_file($_FILES['upload']['tmp_name'], $_FILES['upload']['name']);
    echo "Upload succeeded!<br>";
<form action="." enctype="multipart/form-data" method="POST">
<input type="file" name="upload" accept=".jpg"><br>
<input type="submit" value="Upload jpg">


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-05-16 07:33 UTC]
This behavior is explicitely noted in the manual[1]:

| If the basename of the path starts with a dot, the following
| characters are interpreted as extension, and the filename is empty
| (see third example below).

So the behavior is certainly not an oversight, but rather a
deliberate design decision, and changing it would cause a BC
break.  Maybe we should just document that more prominently?

[1] <>
 [2019-05-16 07:55 UTC]
-Status: Open +Status: Not a bug
 [2019-05-16 07:55 UTC]
Works as intended. 

I would suggest to reject files with empty names or configure the webserver so it'd serve them as jpeg.
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Thu Jun 30 05:03:35 2022 UTC