php / php/php-src

Trailing multi dots in filenames are ignored in Windows

Open
#14,779 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Category: Filesystem OS: Windows Status: Verified
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

Additional dots ignored windows Windows treats filenames with trailing dots in a special way, namely that these are basically ignored by most APIs.
But, anyway on windows we can create this files with prefix "\\?\", for example:

ECHO 123> \\?\C:\app\flag.txt....

Check file is created

C:\app>dir
 Volume in drive C has no label.
 Volume Serial Number is F6CA-D975

 Directory of C:\app

07/03/2024  07:53 AM    <DIR>          .
06/23/2024  03:03 PM    <DIR>          ..
07/03/2024  07:53 AM                 5 flag.txt....

So file exists but realpath function not find it, and functions who use VCWD_REALPATH iside same not found it and open_basedir check can not passed because use VCWD_REALPATH

<?php
var_dump(realpath("C:\\app\\flag.txt...."));
var_dump(bindtextdomain('xxx', "C:\\app\\flag.txt...."));
var_dump(file_get_contents("C:\\app\\flag.txt...."));

try to use "\\?\" prefix

<?php
var_dump(realpath("\\\\?\\C:\\app\\flag.txt...."));
var_dump(bindtextdomain('xxx', "\\\\?\\C:\\app\\flag.txt...."));
var_dump(file_get_contents("\\\\?\\C:\\app\\flag.txt...."));

Resulted in this output:

bool(false)
bool(false)
Warning: file_get_contents(C:\app\flag.txt....): Failed to open stream: No such file or directory in C:\app\test.php on line 3
bool(false)

bool(false)
bool(false)
Warning: file_get_contents(\\?\C:\app\flag.txt....): Failed to open stream: No such file or directory in C:\app\test.php on line 3
bool(false)

But I expected this output instead:

string(19) "C:\app\flag.txt...."
string(19) "C:\app\flag.txt...."
string(3) "123"

string(19) "C:\app\flag.txt...."
string(19) "C:\app\flag.txt...."
string(3) "123"

If we enable open_basedir and set it to C:\app\ it falied on open_basedir check with prefix "\\?\"

<?php
var_dump(file_get_contents("C:\\app\\flag.txt...."));
var_dump(file_get_contents("\\\\?\\C:\\app\\flag.txt...."));
Warning: file_get_contents(C:\app\flag.txt....): Failed to open stream: No such file or directory in C:\app\test.php on line 1
bool(false)
Warning: file_get_contents(): open_basedir restriction in effect. File(\\?\C:\app\flag.txt....) is not within the allowed path(s): (C:\\app\\) in C:\app\test.php on line 2
Warning: file_get_contents(\\?\C:\app\flag.txt....): Failed to open stream: Operation not permitted in C:\app\test.php on line 2
bool(false)

All function who use open_basedir check fail to check if use "\\?\" prefix, but if open_basedir not set functions: is_readable,file_exists,is_writable,filesize,fileatime .. maybe more - is working prefect with "\\?\" prefix,, im not check all functions.
Not working functions: realpath,file_get_contents,bindtextdomain,readfile,file,opcache_invalidate,SplFileInfo->getRealPath ... maybe more

PHP Version

PHP 8.3.6

Operating System

Windows Server 2022

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the trailing-dot and \?\ path cases on Windows Server 2022 using the PHP snippets, then trace VCWD_REALPATH and the listed functions, including realpath(), file_get_contents(), bindtextdomain(), and open_basedir checks. Done means existing files with trailing dots are resolved and accessed consistently, with the security checks still applying correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.