Closed augensalat closed 3 years ago
IMHO the correct response to a request header Content-Type
that doesn't match any of the content
specifications in the OpenAPI specification file should be a 415 Unsupported Media Type
.
Same issue with OpenAPI v3 spec. More information below.
requires 'Mojolicious', '== 9.17';
requires 'JSON::Validator', '== 4.17';
requires 'Mojolicious::Plugin::OpenAPI', '== 4.03';
Spec has body required: true
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserFull"
}
}
}
}
my $c = shift->openapi->valid_input or return;
Work correctly only with exact header
Content-Type: application/json
But unvalidated body goes to controller code even with:
Content-Type: application/json;charset=UTF-8
Charset sent with almost any client browser.
@augensalat: It would be so much easier for yourself and me if you learned how to write unit tests, instead of using curl.
Either way, this is fixed in json-validator, and will be released later today.
Is this the "correct" behaviour for v2 as well? Or v3 even? I've been trying to figure out if content type should be validated against consumes
and produces
in v2, but have found no evidence to suggest that it should be so. To be fair: I have also found no evidence that it shouldn't be validation here. However it looks to me based on discussions in the OAS working group that those attributes were meant and were used in a more informational capacity, and thus is not something that should be validated against.
Anyway: the change to enforce validation is actually a breaking change in that if you have clients that don't send content type presently and the API is updated with the latest version of JSON::Validator
then those clients will suddenly have previously working requests be rejected. Is this a change that is suitable for a minor release?
We don't have to look far to find clients that don't send a default content type ($t->post_ok('/foo' => $data)
). When looking in our logs I'd say it is an even mix between those clients that send content type and those that do not.
Sorry, my mistake here. Incomplete reading of the change you've made. It does indeed not break existing clients that don't send Content-Type
or Accept
. It does however break endpoints that for one reason or another don't have consumes
and produces
set.
{
"errors": [
{
"message": "Expected - got text/plain.",
"path": "/header/Accept"
}
],
"status": 400
}
I haven’t looked up the v2 spec in a while, but I’m pretty sure using consumes and produces is optional. I have however made a change to use this information after 4.xx IIRC.
Please ask on IRC or open an issue if you found a bug, as this issue if for v3. (Sorry, but I’m unsure what you try to point out in the last comment)
related downstream issue, https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=29595#
(Maybe some sort of duplicate of #76?)
Start daemon and curl a request (keep an eye on the request
Content-Type
):This is strange since the daemon happily processes the request body as JSON - seems the
Content-Type: application/x-www-form-urlencoded
is ignored. More severe: The input gets accepted even though the required body parametername
is missing!You get the same wrong behavior with an explicitly wrong
Content-Type
header, i.e.However input validation works as expected when request comes with correct
Content-Type
:and also without a
Content-Type
:Final note: Swagger/OpenAPI2 seems to do it right. Here is my v2 spec:
Money quote: A malicious client can dodge input validation for OpenAPI3 spec by sending a non-json
Content-Type
header.