Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS preflight fails in Firefox but works in Chrome for Apache CXF

I am adding support for CORS requests to a Java web application, and for some unknown reason, Firefox is not correctly sending (or receiving) the Content-Type header. The application runs on a Jetty web server, but everything works correctly in Chrome.

I'm not sure if the issue lies within Firefox, Jetty, or our front end application, but something weird is going on.

The request and response headers according to Firefox:

Request

Host: localhost:8889
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Origin: http://localhost:7778
DNT: 1
Connection: keep-alive

Response

Access-Control-Allow-Origin: http://localhost:7778
Content-Length: 0
Date: Wed, 14 Sep 2016 17:10:36 GMT, Wed, 14 Sep 2016 17:10:36 GMT
Server: Jetty(8.1.14.v20131031)
access-control-allow-credentials: true
access-control-allow-headers: authorization, -type
access-control-allow-methods: POST

And the same request made in Chrome:

Request

OPTIONS *redacted* HTTP/1.1
Host: localhost:8889
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:7778
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Access-Control-Request-Headers: authorization, content-type
Accept: */*
DNT: 1
Referer: http://localhost:7778/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

Response

HTTP/1.1 200 OK
Date: Wed, 14 Sep 2016 16:14:34 GMT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: authorization, content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: http://localhost:7778
Content-Length: 0
Date: Wed, 14 Sep 2016 16:14:34 GMT
Server: Jetty(8.1.14.v20131031)

The code making the request is a plain jQuery call;

$.ajax({
    "url": "http://localhost:8889/...",
    "method": "POST",
    "accepts": "*/*",
    "headers": {
        "Authorization": "Basic ..." // yes, I know. it's a legacy app
    },
    "xhrFields": {
        "withCredentials": true
    },
    "contentType": "application/json",
    "data": "..."
})

I've tried searching for odd interactions between Jetty and Firefox, dug around in Mozilla's bug tracker (no luck), and disabled all extensions in both browsers to eliminate any weird plugin issues. Nothing I have done so far makes a difference. I am at wit's end here. What am I missing?

like image 202
ChimericDream Avatar asked Oct 18 '22 01:10

ChimericDream


1 Answers

tl;dr

Apache CXF had a bug in its CORS Filter class. The bug is only present in really old versions. Updating CXF to version 2.7.6 or later resolves the issue.


I came back to this bug recently when we had a few more customer issues related to it. I finally tracked down the source and thought I'd post it here in case anyone else runs into the same. Given the nature of the fix, though, I'd hope most people will be safe.

The cause boiled down to the CrossOriginResourceSharingFilter class in the Apache CXF library. The version we were on (an old one) had a bug in its header parsing which has been patched in later versions.

Specifically, the filter used ,\w* as the delimiter for header values, which I presume was intended to be ,\s*. As a result, comma-delimited lists which don't also have whitespace following the comma get parsed incorrectly.

Since the bug was fixed so long ago, I hope few people have need for this answer. But knowing that corporations can move slowly when it comes to updating third-party libraries (as in our case), I wanted to put this out there.

like image 93
ChimericDream Avatar answered Oct 30 '22 13:10

ChimericDream