HTML5 Audio player skipping cookies in media fetching calls
Categories
(Core :: Audio/Video: Playback, defect, P3)
Tracking
()
People
(Reporter: hassnain, Unassigned)
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Steps to reproduce:
I am using Firefox latest version to test my website running mp3 files fetched via proxy We are using cookie authentication to validate user and play audio file Here is our current implementation
We send a request to our media proxy with a user token and it validates and set a cookie in response with a mp3 URL We set this mp3 URL in audio src and cookie is saved in browser
The problem is that <audio> player fetch media from src but it does not send the cookie we saved for that media proxy instead it does not send a single request cookie although in our XHR call we were sending many cookies
When no cookie is sent to our media proxy a 401 response is sent and audio player stops
Here are some requests from workflow
Actual results:
XHR Response
HTTP/2.0 200 OK date: Mon, 03 Jun 2019 07:21:45 GMT content-type: text/plain;charset=UTF-8 content-length: 10 access-control-allow-credentials: true access-control-allow-origin: https://consumer.example.com set-cookie: x-id-token=********** expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" vary: Accept-Encoding server: cloudflare cf-ray: 4e0fe97e6ccfd791-MRS X-Firefox-Spdy: h2
XHR Request
Host: media.example.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: application/json, text/plain, / Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://consumer.example.com/listen/uuid Origin: https://consumer.example.com Connection: keep-alive Cookie: ajs_anonymous_id=%22f6ae4eca-8ea9-4560-86e3-627457ef4a81%22; _gat=1; __cfduid=d695230e812d89679db4755d7f0b1cc311559546465; optimizelyEndUserId=oeu1559546469968r0.12488801925201709; tracking-preferences={%22version%22:1%2C%22destinations%22:{%22Amazon%20Kinesis%22:true%2C%22Branch%20Metrics%22:true%2C%22Google%20Analytics%22:true%2C%22MailChimp%22:true%2C%22Optimizely%22:true}%2C%22custom%22:{%22marketingAndAnalytics%22:true%2C%22advertising%22:true%2C%22functional%22:true}}; ajs_user_id=%221bd49c39-b295-4e31-87af-1ac3745190fb%22; ajs_group_id=null; _ga=GA1.2.1103036539.1559546471; _gid=GA1.2.2051257759.1559546471; fbsstage=*****
After this request i see that X-Id-Token cookie set in browser but in a subsequent call to same URL not even a single cookie is sent although in above request 4-5 cookies were sent
Subsequent Request
Host: media.example.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: audio/webm,audio/ogg,audio/wav,audio/;q=0.9,application/ogg;q=0.7,video/;q=0.6,/;q=0.5 Accept-Language: en-US,en;q=0.5 Referer: https://consumer.example.com/listen/uuid Range: bytes=0- Origin: https://consumer.example.com Connection: keep-alive TE: Trailers expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 4e0fe9823aecd791-MRS X-Firefox-Spdy: h2
Expected results:
This works fine in chrome as the cookie is sent in all requests but not in firefox. There is no CORS issue in browser console. I see only these errors from audio player AbortError: The fetching process for the media resource was aborted by the user agent at the user's request. AbortError: The operation was aborted. AbortError: The operation was aborted.
This happened because the media fetch call returned 401 because cookie was not present Can anyone tell me whats wrong here?
Here is what i understand from my testing
This specific issue happens when the media call is sent with bytes range
Everything works fine and all cookies are attached to the request when the call is made with the header below:
Range: bytes=0-
But as soon as the next chunk is fetched and header change to anything like > Range: bytes=18644992-
It just stop working and does not send a single cookie although in the working scenario it sends all five cookies for example.com domain
Comment 2•6 years ago
|
||
Hi @hassnain, in order to test the issue please add a TC- TestCase- (or a HTML format or something that could be attached ), also accurate steps describing the actions that need to be made.
Additionally, I will set a component for the issue and if isn't the right one please fell free to change it.
Thanks.
I have written sequential XHR media calls. They can be used to reproduce the issue
The issue originate when one page fetches an audio file from another domain as described in XHR calls
then audio player does not attach browser cookies
Comment 4•6 years ago
|
||
Hi @hassnain, on 1st paragraph of YOUR steps to reproducing you've said ..."my website running mp3"=> which is this website? So, please fulfill the requests from comment 2 in order to test it.
Thanks.
The link is private so i cant share it but this scenario can be easily reproduced using anyother site or an example HTML page loading MP3 content form a third part site using cookies
Comment 6•6 years ago
|
||
I confirmed this by going to http://example.com, having a local web server at 127.0.0.1:8080 that for /audio.mp3 would set a cookie in the response and return an mp3 file.
I pasted the below code into the devtools console and inspected headers in the devtools network tab.
data = {}; a = new Audio(); x = new XMLHttpRequest(); x.open("HEAD", "http://127.0.0.1:8080/audio.mp3"); p = new Promise(r => x.onload = r); p.then(d => { data = d; a.src = "http://127.0.0.1:8080/audio.mp3"; }); x.send();
The cookie was set in the response to the XHR, but not part of the request from the audio element.
Comment 7•6 years ago
|
||
Sorry, the appropriate code should use crossOrigin = "use-credentials"; per mdn, and the server needs to respond with headers Access-Control-Allow-Origin: http://example.com and Access-Control-Allow-Credentials: true.
data = {}; a = new Audio(); a.crossOrigin = "use-credentials"; x = new XMLHttpRequest(); x.open("HEAD", "http://127.0.0.1:8080/audio.mp3"); p = new Promise(r => x.onload = r); p.then(d => { data = d; a.src = "http://127.0.0.1:8080/audio.mp3"; }); x.send();
Still, doing this, I don't see cookies passed in the request from the audio element, nor do I see a preflight request to the server. Debugging briefly I see that we exit early from nsCORSListenerProxy::CheckPreflightNeeded.
Intuitively I would have thought that the http channel would know that a cookie is set for the url in question and add that to the list of cors-unsafe headers but that seem to not be the case.
I don't know enough about CORS to give a complete answer. Honza, do you know what can be expected here?
Comment 8•6 years ago
|
||
Will look sometimes this week. Thanks for the comments.
Comment 9•5 years ago
|
||
(the long week is over)
I retested this and I can see:
- the XHR response doesn't make us to store cookies at all - I don't even see a message about the cookie acceptance/rejection, like we would not even tried (this is probably the core of the bug, I don't know why exactly this should not happen); needs investigation
- the audio request doesn't store cookies because of: "cookie rejected because failed the samesite tests"
Comment 10•5 years ago
|
||
I had to read the code from comment 7 more carefully. The XHR is missing withCredentials = true which makes us ignore cookies sent by the server.
Description
•