4

I'm experimenting with Firefox's Content Security Policy. Basically it's a special header for the webpage that tells the browser which resources are valid.

When some resource is invalid because it's breaks the policy, Firefox sends a report to a given URI in json format.

This is a typical report

array(1) {
  ["csp-report"]=>
  array(4) {
    ["request"]=>
    string(71) "GET http://example.com/?function=detail&id=565 HTTP/1.1"
    ["request-headers"]=>
    string(494) "Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0b10pre) Gecko/20110115 Firefox/4.0b10pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ar,en-us;q=0.8,es;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: UTF-8,*
Keep-Alive: 115
Connection: keep-alive
Referer: http://example.com/index.php?function=search&query=Pata+de+cambio+
Cookie: the cookie
"
    ["blocked-uri"]=>
    string(4) "self"
    ["violated-directive"]=>
    string(30) "inline script base restriction"
  }
}

The content type is application/json; charset=UTF-8

Now. I would expect this to be avaliable in $_POST as REQUEST_METHOD==POST but post is always empty. I can access it from php://input, but the question is: Why the request isn't avaliable in $_POST?

I can't even use filter_input and $_REQUEST is empty...

The Disintegrator
  • 4,147
  • 9
  • 35
  • 43

3 Answers3

8

$_POST gives you form variables, which show up in the page like this:

POST /some_path HTTP/1.1

myvar=something&secondvar=somethingelse

But what you're getting isn't a valid query string. It probably looks something like this:

POST /some_path HTTP/1.1

{'this':'is a JSON object','notice':'it\'s not a valid query string'}

php://input gives you everything after the headers in raw form, so in this case I think it's the only way to get what you want.

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • mmm, I think you got a point there. but usually json data is sent across post witout problems. Why it fais in this particular case and not with a post via javascript? – The Disintegrator Jan 16 '11 at 05:25
  • @The Disintegrator: I have very little experience with this, but the framework I've used (ExtJS) converts JSON objects to query strings. – Brendan Long Jan 16 '11 at 18:54
  • @BrendanLong. You'll want to escape that apostrophe in *it's*. – TRiG Aug 07 '12 at 22:34
8

If a request is sent as POST it is not necessarily encoded as normal application/x-www-form-urlencoded or multipart/form-data. Should Firefox send a JSON body, then PHP doesn't know how to decode it.

You have to check $_SERVER["HTTP_CONTENT_TYPE"]. If it contains application/json then you must indeed read php://stdin:

if (stripos($_SERVER["HTTP_CONTENT_TYPE"], "application/json")===0) {
     $_POST = json_decode(file_get_contents("php://input"));
// or something like that
mario
  • 144,265
  • 20
  • 237
  • 291
1

It can be several of other http request types (I am aware of 7 right now, and several place holders for more to come).
I would print the $_REQUEST and $_SERVER to see how it actually arrives.

Itay Moav -Malimovka
  • 52,579
  • 61
  • 190
  • 278