Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Third party auth scenarios that require non-cookie credentials #2017

Open
tomcrane opened this issue Jul 6, 2021 · 9 comments
Open

Third party auth scenarios that require non-cookie credentials #2017

tomcrane opened this issue Jul 6, 2021 · 9 comments

Comments

@tomcrane
Copy link
Contributor

tomcrane commented Jul 6, 2021

Auth 1.0 assumes that the client's credentialled requests for content resources are made with cookies.
This isn't a 100% requirement - the auth spec would work just as well if the server were authorising based on IP address.

IP origin and cookies share one characteristic - neither of them require the client to do anything when it makes requests for content resources - sending of cookies, and having a particular origin, are "ambient" as far as the client is concerned. They don't need a spec to do anything.

In some AV scenarios, especially where a JavaScript library is being used to support adaptive bit rate media, credentials can be presented as Authorisation header tokens, and sometimes as query string parameters. In this case, the client does need to intervene in the request for chunks, adding in credentials.

Example: https://stackoverflow.com/questions/56647256/hls-js-required-send-http-header

Is there a way a viewer could implement an IIIF Auth interaction pattern that remains independent of particular auth mechanisms, yet still offers a hook for modifying the request?

The answer to this might well be "no", or "not without making the IIIF Auth spec a horrible complex mess", but the scenario is real and I wonder if there is some way of accommodating it with allowed points at which some sort of callback could happen.

@tomcrane tomcrane added the auth label Jul 6, 2021
@azaroth42
Copy link
Member

@tomcrane
Copy link
Contributor Author

tomcrane commented Jul 8, 2021

Discussion on Auth Call 2021-07-06

Key concern of the auth spec so far is that a IIIF client has no access, and needs no access, to the credential(s) required to access the content resources.

If this is relaxed (e.g., find a way of obtaining a token so you can use it to insert headers, query string params etc for AV chunk requests, or XHR requests to an annotation server) then there is potential for an evil client to send the token somewhere else, where something makes the request with the token, obtains the content, proxies it so the unsuspecting user doesn't spot anything odd, but siphons off the content itself.

IIIF clients need to work in untrusted contexts for interoperability.

To some extent this problem is present in current AV streaming, but it's not really a problem; the client is usually trusted, in a controlled environment and the tokens have a very short lifetime. They can encode various data like the referer, origin IP, etc, making spoofing hard to do somewhere else. The token is for that user, from that location, to be used only once, and near-immediately.

A common pattern with AV auth is to give the user a tailored URL from which they can access the content - e.g., an HLS .m3u8 file URL includes timestamp, IP address or other identifying information. This URL is for use now and won't work if someone else tries to use it.

It seems reasonable (though needs lots of consideration) that the IIIF spec could accommodate a mechanism for giving the client the URL to use. The token service, which is "called" with cookie credentials because it is an iframe, knows who the user is (it can see their cookie) and could provide the actual URL to use.

But do we already have this mechanism? This could also be done by redirecting the info.json, or probe service, to a new location when requested with the auth bearer token (that was acquired with the cookie). This is how degraded access works today, the flow is already there.

This, or something like it, has already been discussed in the context of AV here:

#1290 (comment)

Not quite the same, because in that discussion the redirect is being used to deduce that the user is not allowed to see the asked-for resource and is getting something else. For the scenario above, the new contentLocation is because the user probed the "canonical" URL with a token they acquired from a cookie-enabled request to the token service, and is being given their appropriate custom URL to see the content.

This doesn't address the exact question. It's still cookie-based auth initially, used to acquire a bespoke URL via redirect/contentLocation on the probe service, that is then used by the client to access the content. The first credential is then a token, and the second credential is the unique URL.

This caters for path or querystring variations, but won't work if you need to add an HTTP header. But maybe path/querystring is enough to make this useful.

Further links

IP Address bound JWT:
https://medium.com/@adarsh.pradyut/ip-bound-jwt-6e2669d15391

https://www.chronicle.com/article/judge-throws-out-copyright-lawsuit-over-uclas-streaming-of-videos-to-students/

@tomcrane tomcrane added this to the Auth 2.0 milestone Mar 1, 2022
@tomcrane
Copy link
Contributor Author

tomcrane commented Aug 16, 2022

The work-in-progress on Auth contains an example, very much up for discussion:

The above is controversial because the client has used the access token to disover the URL of an actual content resource, that perhaps doesn't require a credential.

In this example the client might have been through an auth interaction, and acquired a bearer token.
When they present it to the probe service they get a 200 ("your credentials are good") but still get a location property ("even so, access it here"). The spec doesn't require that the indicated location checks/uses credentials, but if the implementer decides that it doesn't, and 1232123432123 is a short-lived token, then the client can request the file (or in this case the chunks) at that obscure, personalised but still open URL.

GET /my-HLS-video.m3u8/probe HTTP/1.1
Authorization: Bearer xxxyyyzzz

=>

{
    "@context": "http://iiif.io/api/auth/{{ page.major }}/context.json",
    "id": "https://authentication.example.org/my-HLS-video.m3u8/probe",
    "type": "AuthProbeService2",
    "location": "https://authentication.example.org/1232123432123/my-HLS-video.m3u8",
    "label": { "en": [ "Label for my-video.mp4's probe service" ] }
}

This pattern matches how some streaming servers work, the chunks are delivered from unsecured but obscure and short-lived URLs. The problem here is that we have crossed a line in the Auth spec, and although we're not using the bearer token at the exact moment of authorisation as a true credential, we are effectively using it as the means to access a Content Resource URL - a meaningful content resource as opposed to a JSON-LD description of the resource.

if I hijacked the client's bearer token, I could obtain that "secret" but open location, and make requests as long as it remained available.

@tomcrane
Copy link
Contributor Author

The above is an example of a modification of the request to include a credential, but one that has been done entirely blindly by following the spec (the client ended up with a modified URL to get a content resource from by using the location property, it didn't manipulate the string of the URL to insert a token at a particular point).

The stronger version of this is to allow a hook in the spec whereby the request can be arbitrarily manipulated - appending query string params as credentials, adding a JWT token in a header, adding some completely bespoke header. Can the spec include space for such a hook without committing to what the hook is? It's open for extension at this point and relies on recipes to provide implementations of extensions. This is a route to much wider access control integration but at great risk of making a spec that's only half the story.

@tomcrane tomcrane moved this to In Progress in Auth 2.0 Aug 16, 2022
@tomcrane tomcrane added the A/V label Oct 25, 2022
@tomcrane
Copy link
Contributor Author

tomcrane commented Nov 8, 2022

If the IIIF Auth token can ever be exchanged for a modified, credential-containing URL in this way, the spec needs to be reevaluated for cross site request forgery vulnerabilities. At the moment there's nothing an attacker gains from intervening or capturing aspects of the IIIF Auth flow, because it's independent of the auth flow that actually grants access to the resources (which may or may not have its own vulnerabilities but that's outside the scope).

@tomcrane
Copy link
Contributor Author

tomcrane commented Nov 8, 2022

To this end... and even though most of the parts appear to be already present in the IIIF Auth API, and it would be very tempting to start using the token as a credential for Manifests, annotation pages, search results... it would be better to keep the client's auth relationship with API resources separate, even if that means the user has one auth relationship with content resources (e.g., cookie-based) and another with API resources (e.g., using OAuth2), both independent of the client application.

I don't know whether the location trick above for AV falls into this category though, or whether it's a permitted special case.

The problem is that it's unlikely API resources are independent of the client application - it's the client application directly asking for them using fetch that's the most likely scenario.

@cjcolvar
Copy link

cjcolvar commented Nov 8, 2022

Avalon implements auth in our manifests using IIIF Auth v1 + probe service. Once a user has gone through the auth flow they then have a cookie which gets passed to an avalon endpoint for the HLS manifest with secure tokenized urls in it. The tokens (as query params) in the stream urls are tied to the user's session and are validated by the streaming server. This breaks when testing in the UV apparently because we haven't set CORS headers in a way which is seen as vulnerable: reflecting the requests origin in Access-Control-Allow-Origin and setting Access-Control-Allow-Credentials to true. It seems that this proposal would avoid the need for this CORS configuration since client wouldn't need to make credentialed requests.

@tomcrane
Copy link
Contributor Author

tomcrane commented Nov 8, 2022

reflecting the requests origin in Access-Control-Allow-Origin and setting Access-Control-Allow-Credentials to true.

Yes, we want to avoid doing that, for spec simplicity as well as keeping the domain of the spec to ACAO: * with non-credentialed requests.

The vulnerability here (and there may be others) is something like this...

A modified, evil UV now has access to the secure tokenized urls in the HLS manifest. They are intended for the user to see the video right there in the UV, but evil UV could make fetch requests to Evil HQ, sending those tokenized URLs, and some process at evil HQ requests them and saves the video streams to disk.

Or it's not Evil UV, but some other client that's processing those chunks into a video file for whatever ends.

The question is, is that kind of vulnerability an acceptable compromise? There are additional checks the server can make when serving a chunk, e.g., fingerprinting the request, but they are not perfect. Is this what happens in other AV platforms? That the chunk request is essentially non-credentialed other than the presence of the token?

@tomcrane
Copy link
Contributor Author

tomcrane commented Jun 7, 2023

The 2.0 spec allows location to provide a simple form of this functionality, but any more complex token exchange or scripted manipulation of resource requests to include credentials requires further spec work.

@zimeon zimeon added the defer label Jun 7, 2023
@zimeon zimeon removed this from the Auth 2.0 milestone Jun 7, 2023
@zimeon zimeon removed this from Auth 2.0 Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants