Closed Bug 1558395 Opened 6 years ago Closed 5 years ago

HTML5 Audio player skipping cookies in media fetching calls

Categories

(Core :: Audio/Video: Playback, defect, P3)

67 Branch
defect

Tracking

()

RESOLVED INVALID

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

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.

Component: Untriaged → Audio/Video
Flags: needinfo?(hassnain)
Product: Firefox → Core

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

Flags: needinfo?(hassnain)

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.

Flags: needinfo?(hassnain)

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

Flags: needinfo?(hassnain)

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.

Status: UNCONFIRMED → NEW
Component: Audio/Video → Audio/Video: Playback
Ever confirmed: true
Priority: -- → P3

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?

Flags: needinfo?(honzab.moz)

Will look sometimes this week. Thanks for the comments.

(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"
Flags: needinfo?(honzab.moz)

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.

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.