WordPress.org

Make WordPress Core

Opened 10 months ago

Last modified 3 months ago

#39586 new defect (bug)

Handle absolute request URI-s

Reported by: szepe.viktor Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.8
Component: Rewrite Rules Keywords: close reporter-feedback
Focuses: Cc:

Description (last modified by dd32)

For example the iPhone Facebook app sends absolute request URI-s like the ones in proxy requests but with the same domain name.

GET http://www.art-plasztika.hu:80/mellnagyobbitas

that is the equivalent for GET /mellnagyobbitas "http://www.art-plasztika.hu" being the home URL

We may know scheme+host name+port from the home option.

Please consider supporting absolute request URI-s.

Change History (11)

#1 @szepe.viktor
10 months ago

*that is the equivalent for GET /mellnagyobbitas

#2 @szepe.viktor
10 months ago

One note: Apache - and possibly most webservers - support this.

See https://tools.ietf.org/html/rfc2616#section-3.2.1

Last edited 10 months ago by szepe.viktor (previous) (diff)

#3 follow-up: @rmccue
10 months ago

  • Keywords close added

I'm not sure where we should be supporting this. This is something handled above WordPress, typically by your web server (Apache/nginx). What exactly in WordPress would need to handle this?

#4 follow-up: @dd32
10 months ago

IMHO this would be a candidate for wp_fix_server_vars() if a webserver configuration is incorrectly passing the full URI in what we expect to only contain a path.

We'd need to document (on this ticket) the server circumstances under which the scenario is possible, and also the contents of the unaltered $_SERVER variables, and what we mangle them to.

There have been cases in the past where we'd mangle an otherwise good $_SERVER variable to something incorrect because of something odd the server was passing in a variable though.

Last edited 10 months ago by dd32 (previous) (diff)

#5 @dd32
10 months ago

  • Description modified (diff)

#6 in reply to: ↑ 3 @szepe.viktor
10 months ago

Replying to rmccue:

I'm not sure where we should be supporting this. This is something handled above WordPress, typically by your web server (Apache/nginx). What exactly in WordPress would need to handle this?

Actually webservers handle this type of absolute URI.
WordPress gives a 404 response as it is not able to properly parse the request URI.

#7 in reply to: ↑ 4 ; follow-up: @szepe.viktor
10 months ago

Replying to dd32:

We'd need to document (on this ticket) the server circumstances under which the scenario is possible, and also the contents of the unaltered $_SERVER variables, and what we mangle them to.

This "circumstance" is the above mentioned standard.

We need to mention that browsers usually send only relative URI-s. Actually it took me 2 weeks to find out that it is valid to send an absolute URI.

#8 @dd32
10 months ago

  • Keywords reporter-feedback added

This "circumstance" is the above mentioned standard.

I meant specific server configurations. Web servers normalise the incoming request before providing it to PHP, most configurations would make GET / (against example.com) and GET http://example.com/ appear the same to the application. WordPress supports GET http://example.com/post-slug/ properly when the web server in front of it sanitizes the incoming request correctly.
Apache and Nginx both do this by default, unless you incorrectly configure proxy functionality IIRC.

What server environment are you running under, and are there any specific configuration settings in play?

#9 in reply to: ↑ 7 @rmccue
10 months ago

Per @dd32's note, it depends on your server here, but Apache/nginx _should_ be correctly passing the URL in and handling the URL parsing correctly here.

By "What exactly in WordPress would need to handle this?", I meant more, "what exactly is breaking in WordPress?". Evidently something in $_SERVER is set incorrectly, but the question is "what"? :) (My guess is REQUEST_URI)

Replying to szepe.viktor:

We need to mention that browsers usually send only relative URI-s. Actually it took me 2 weeks to find out that it is valid to send an absolute URI.

Actually, technically speaking, it is not. Servers are split into two types in HTTP: proxy servers, and origin servers. The absolute form is only used for proxy servers, but Apache/nginx act as origin servers, so the client is acting in an invalid way.

Specifically, per RFC7230, §5.3:

When making a request directly to an origin server, other than a
CONNECT or server-wide OPTIONS request (as detailed below), a client
MUST send only the absolute path and query components of the target
URI as the request-target.

The RFC also says "all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies." As far as I can tell, Apache/nginx should be converting this to the relative form before passing to PHP, but it appears it's not.

I suspect this is probably a misconfiguration at the server level (Apache/nginx), but seeing as we can fix it on our end, we may as well.

#10 @szepe.viktor
10 months ago

Thank you for your answers.

I came through mpm-itk+mod-php and mpm-event+mod-fastcgi Currently
mpm-event + mod-proxy-fcgi is connected to PHP-FPM pools through Unix domain socket file.
https://github.com/szepeviktor/debian-server-tools/blob/master/webserver/apache-sites-available/Skeleton-site-ssl.conf#L77-L103

I set {{ProxyRequests Off}} so external proxy requests are not supported.
Although same-domain proxy requests are accepted.

Test

Request

GET http://www.XXXbeatrix.hu:80/in.php HTTP/1.1

Response ($_SERVER)

array(33) {
  ["USER"]=>
  string(7) "XXXb"
  ["HOME"]=>
  string(13) "/home/XXXb"
  ["FCGI_ROLE"]=>
  string(9) "RESPONDER"
  ["SCRIPT_URL"]=>
  string(7) "/in.php"
  ["SCRIPT_URI"]=>
  string(34) "http://www.XXXbeatrix.hu/in.php"
  ["HTTP_HOST"]=>
  string(20) "www.XXXbeatrix.hu"
  ["HTTP_USER_AGENT"]=>
  string(77) "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20130809 Firefox/47.0"
  ["HTTP_ACCEPT"]=>
  string(9) "text/html"
  ["HTTP_ACCEPT_LANGUAGE"]=>
  string(2) "en"
  ["HTTP_CONNECTION"]=>
  string(5) "close"
  ["PATH"]=>
  string(60) "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  ["SERVER_SIGNATURE"]=>
  string(65) "<address>Apache Server at www.XXXbeatrix.hu Port 80</address>"
  ["SERVER_SOFTWARE"]=>
  string(6) "Apache"
  ["SERVER_NAME"]=>
  string(20) "www.XXXbeatrix.hu"
  ["SERVER_ADDR"]=>
  string(14) "79.172.214.123"
  ["SERVER_PORT"]=>
  string(2) "80"
  ["REMOTE_ADDR"]=>
  string(13) "62.201.94.190"
  ["DOCUMENT_ROOT"]=>
  string(32) "/home/XXXb/public_html/server"
  ["REQUEST_SCHEME"]=>
  string(4) "http"
  ["CONTEXT_PREFIX"]=>
  string(0) ""
  ["CONTEXT_DOCUMENT_ROOT"]=>
  string(32) "/home/XXXb/public_html/server"
  ["SERVER_ADMIN"]=>
  string(19) "webmaster@szepe.net"
  ["SCRIPT_FILENAME"]=>
  string(39) "/home/XXXb/public_html/server/in.php"
  ["REMOTE_PORT"]=>
  string(5) "45710"
  ["GATEWAY_INTERFACE"]=>
  string(7) "CGI/1.1"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["QUERY_STRING"]=>
  string(0) ""
  ["REQUEST_URI"]=>
  string(37) "http://www.XXXbeatrix.hu:80/in.php"
  ["SCRIPT_NAME"]=>
  string(7) "/in.php"
  ["PHP_SELF"]=>
  string(7) "/in.php"
  ["REQUEST_TIME_FLOAT"]=>
  float(1484656326.2476)
  ["REQUEST_TIME"]=>
  int(1484656326)
}

So the request URI stays the original: "http://www.XXXbeatrix.hu:80/in.php" and I suggest WordPress could strip scheme,host,port.

#11 @swissspidy
3 months ago

Sounds like a duplicate of #17047.

Note: See TracTickets for help on using tickets.