The browser basically never forces you into a particular format. You don't even need to do the trick with the form stuff that the sibling was talking about. Consider the following JavaScript:
var xhr = new XMLHttpRequest();
var url = "http://localhost:12345/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
xhr.send('{"hello":"world"}');
No trickery required, it just does it.[Edited to illustrate my point better.]
If that's the case, then yes, the forms method would be 'better'.
Are people using JSON parser as proxy for access control? "Payload successfully parsed as JSON, therefore you are allowed to use this endpoint"?
My apps speak only JSON, so one of the first things I do is create a middleware that requires any POST/PUT/PATCH request to be application/json and reject everything else with a 415 error. That's so I can turn off the CSRF protection mechanics in the framework completely, but the two concerns are related.
I guess the same trick might work with urlencoded forms, but it wouldn't work with multipart/form-data
> Are people using JSON parser as proxy for access control? "Payload successfully parsed as JSON, therefore you are allowed to use this endpoint"?
For better or worse, yes, or at least as one layer. That's one of the rationales behind the "safe" requests AFAIK.
And this wouldn't be the first time, protocols are made intentionally incompatible on the wire, so an attacker can't smuggle one inside the other. That's the entire reason for WebSocket's weird handshake dance and the "xor encoding" it applies to messages from the client.
Until now, I wasn't aware of that either. My response is about the fact you can massage the plaintext part to contain valid JSON somehow being a problem, one that apparently is a security issue in practice.
We're not talking about some clever polyglot quine like those COM executables that are somehow also valid Bash and C code and PDF files or something. text/plain is a superset of everything that can be represented by plain text, which includes approximately all code and data formats, JSON and XML included.
> And this wouldn't be the first time, protocols are made intentionally incompatible on the wire, so an attacker can't smuggle one inside the other.
I need to learn more about it, thanks for pointing it out.
Though at the surface, it reads to me like removing a feature. "Smuggling a protocol inside the other" sounds to me like an important feature, or perhaps more accurately, I find myself being part of the "attacker" population much more often than not. "Tunnel $whatever through HTTPS because corporate/ISP firewalls" is both a meme and success story for plenty a SaaS at this point.
Not in the context of web forms.
Just checked the spec and "text/plain" just seems to be an alias for "application/x-www-form-urlencoded" [1] - i.e. stuff that looks like
key=value&anotherkey=anothervalue
on the wire.Apparently though, keys and values can contain arbitrary characters and arent percent-encoded, so you can do a "quine" where the "key" is
{"foo": "bar", "ignore": "
and the "value" is "}
And then the browser will happily send {"foo": "bar", "ignore": "="}
over the wire, which is valid json.[1] https://html.spec.whatwg.org/multipage/form-control-infrastr...
It does, though. See my reply at https://news.ycombinator.com/item?id=48618539 .