Skip to content

fix $_SERVER['SCRIPT_NAME'], 'PHP_SELF', and 'PATH_INFO' #2317

Open
henderkes wants to merge 6 commits intomainfrom
fix/script_name
Open

fix $_SERVER['SCRIPT_NAME'], 'PHP_SELF', and 'PATH_INFO' #2317
henderkes wants to merge 6 commits intomainfrom
fix/script_name

Conversation

@henderkes
Copy link
Copy Markdown
Contributor

@henderkes henderkes commented Mar 27, 2026

fixes #2274 (comment)

apache/nginx/caddy pass PHP_SELF as SCRIPT_NAME + PATH_INFO, but our PATH_INFO wasn't working because our matcher stripped the rest of the path.

request url: localhost/index.php/en

# was non-worker:
SCRIPT_NAME: /index.php
PATH_INFO: 
PHP_SELF: /index.php
REQUEST_URL: /en

# was fastcgi:
SCRIPT_NAME: /index.php
PATH_INFO:  /en
PHP_SELF: /index.php/en
REQUEST_URL: /en

# was php_server worker
SCRIPT_NAME:
PATH_INFO:
PHP_SELF: /en
REQUEST_URL: /en

# now is always:
SCRIPT_NAME: /index.php
PATH_INFO: /en
PHP_SELF: /index.php/en
REQUEST_URL: /en

…rkers

apache passes PHP_SELF as SCRIPT_NAME + REQUEST_URL, but the docs say it's the same as SCRIPT_NAME and that's how Caddy+fpm behave too
@henderkes henderkes requested a review from AlliBalliBaba March 27, 2026 15:49
@henderkes henderkes marked this pull request as ready for review March 27, 2026 15:49
@henderkes henderkes marked this pull request as draft March 27, 2026 16:26
@henderkes henderkes changed the title fix $_SERVER['SCRIPT_NAME'] and $_SERVER['PHP_SELF'] in php_server workers fix $_SERVER['SCRIPT_NAME'], 'PHP_SELF', and 'PATH_INFO' Mar 27, 2026
@henderkes henderkes marked this pull request as ready for review March 27, 2026 17:05
cgi.go Outdated
// If a worker is already assigned explicitly, derive SCRIPT_NAME from its filename
if fc.worker != nil {
fc.scriptFilename = fc.worker.fileName
fc.scriptName = strings.TrimPrefix(fc.worker.fileName, fc.documentRoot)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm probably would be better to leave scriptName empty if the worker is in the public path:

root /some/path
worker /other/path {
  match *
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about that. Shouldn't it show /other/path/index.php then?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure either TBH. In CGI spec it's the path relative to the root, so /other/path/index.php might be misleading.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically that's a path relative to the root, haha.

I don't see a better solution. Emptying it out would be even more of a violation.

}
rewriteHandler := rewrite.Rewrite{
URI: "{http.matchers.file.relative}",
URI: "{http.matchers.file.relative}{http.matchers.file.remainder}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm without this change the path for PHP_SELF will not be forwarded? Not sure what other consequences changing the matcher here might have.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it'll be missing like PATH_INFO.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH PHP_SELF and PATH_INFO have always confused me, we probably need some tests verifying that their behaviors conform to CGI spec exactly. Modern frameworks mostly handle routing themselves, but more traditional setups might rely on these very specific routing rules to not be vulnerable to some kind of bypassing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Time to put my AI credits to good use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

$_SERVER['SCRIPT_NAME'] is empty in worker mode

2 participants