swagger-tools icon indicating copy to clipboard operation
swagger-tools copied to clipboard

content-type validation fails for empty request body

Open philippevk opened this issue 9 years ago • 12 comments

What happens:

  • In my swagger doc I define 'consumes' at the top-level to 'application/json'
  • I have a POST operation that doesn't need a body
  • If I send a request without a Content-Type for this operation, the content-type validation fails (the empty content type is interpreted as application/octet-stream)

It is basically the same thing as #275

But I don't think it's a client error. Consider an operation that consumes application/json. However imagine the body is optional. How would you implement this?

  1. Accept both application/json and application/octet-stream This would be wrong. An octet-stream is not a valid body

  2. Force client to send 'Content-Type: application/json' header when body is empty It would work but it adds a "gotcha" to the api. http://stackoverflow.com/questions/29784398/should-content-type-header-be-present-when-the-message-body-is-empty

What I would expect is...

  • If Content-Length is '0' do not validate Content-Type at all

Thoughts?

philippevk avatar Aug 10 '16 12:08 philippevk

I'm not completely opposed to this. I wonder what @fehguy or @webron have to say about this.

whitlockjc avatar Aug 10 '16 16:08 whitlockjc

spec-wise, the client would be expected to send the content type header as application/json. However, when it comes to validation, I'm fairly indifferent to this case. Seems like a reasonable suggestion.

webron avatar Aug 10 '16 17:08 webron

That's my stance as well. If you say you consume application/json but fail to set Content-Type to application/json, that's on you. But with that being said, I'm not against updating the logic such that if Content-Length is 0, we do not validate it at all. Of course, as I typed that I immediately thought of how this could be used to avoid validation at all which could be an issue.

whitlockjc avatar Aug 10 '16 17:08 whitlockjc

I'm pretty sure that http-spec wise sending a request with Content-Length 0 makes the server ignore the body (i.e. The header overrides the actual body length)

Because of this I don't think Content Length 0 can be abused

philippevk avatar Aug 10 '16 23:08 philippevk

Here's the Content Length rfc: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4

philippevk avatar Aug 11 '16 00:08 philippevk

What I meant by abused is if someone wanted to be malicious, all they'd have to do is send Content-Length: 0 and all validation is disabled but that does not guarantee that the web framework will not attempt to process the body. I could be wrong. Thoughts?

whitlockjc avatar Aug 11 '16 18:08 whitlockjc

My understanding of the rfc is that a implementation that processes an http request MUST use Content-Length to determine how many bytes it reads to form the body.

Therefore, Content-Length 0 can't be abused because by setting it to 0 the web server MUST ignore the body. In other words, a web framework that follows the spec is guaranteed to give an empty body if Content-Length is 0.

I'll write a test for this just to be sure.

philippevk avatar Aug 11 '16 18:08 philippevk

As I thought! https://gist.github.com/philippevk/303f6bab050a02e64fa0bb8f675fd161

philippevk avatar Aug 11 '16 19:08 philippevk

Well, since you've proven the web frameworks are working as expected then my concern of abuse is dissolved. We'll get this supported.

whitlockjc avatar Aug 11 '16 20:08 whitlockjc

Any updates on this guys? Do you plan to implement skipping the body validation whenContent-Length is set to 0?

akoskm avatar Jan 20 '17 12:01 akoskm

I just submitted a pull request with a fix. In the meantime you can add the following middleware to your pipeline before swaggerValidator

expressApp.use((req, res, next) => {
  if (req.headers['content-length'] === '0' && req.headers['content-type'] == null) {
    req.headers['content-type'] = 'application/json' // or whatever your api consumes
  }
  next()
})

It's VERY hacky, but it works. Eh.

philippevk avatar Jan 20 '17 13:01 philippevk

@philippevk looks good to me. I'll wait for this to be merged, until then I'll stick to overriding application/octet-stream in the path. IMO not-too-hacky but still meh.

akoskm avatar Jan 20 '17 13:01 akoskm