cdnjs / api-server

📡 API server for api.cdnjs.com - The #1 free and open source CDN built to make life easier for developers.
https://api.cdnjs.com
MIT License
89 stars 38 forks source link

SRI lookup #92

Closed alexandrosmagos closed 1 year ago

alexandrosmagos commented 1 year ago

Feature request

Feature description

The feature that I am suggesting is the addition of an SRI validation endpoint to the CDNJS api. This endpoint would allow developers to verify the integrity of the third-party libraries in their web projects, ensuring that they have not been tampered with or modified during delivery. Endpoint (since the SRI can contain a /):

/sri_lookup/:hash1
/sri_lookup/:hash1/
/sri_lookup/:hash1/:hash2
/sri_lookup/:hash1/:hash2/

How the feature is useful

The usefulness of this feature to users of the API is significant, as it provides an extra layer of security when using third-party libraries. Developers can use SRI to check if a library has been tampered with or modified, while saving 2-3 requests that would have been done to get the SRI. My use example, is that I'm building a web app that scans modified library files for malicious code, and in order to mark is modified, the app tries to find the library associated to the file, by doing a few requests, then gets the version of the library found with the version mentioned in the file, then checks the hashes. By just sending the hash to the API and getting and yes or no, helps a bit.

EDIT: This is clearly a suggestion/improvement, not a bug. I can not attach a label, so I'm mentioning it here. :)

MattIPv4 commented 1 year ago

Hey! I'm not sure I follow what you're asking for here -- what exactly are you expecting this endpoint to do with an SRI hash to "validate" it?

SRI hashes are already validated by the browser... that is how they work. We give you the expected SRI hash for an asset (you can get them via the API or website), you set the integrity attribute to that SRI hash in your script/link tags, and when the browser attempts to load the asset it automatically checks the contents match that hash.

If you're loading an asset where browsers don't support SRI, then you'll want to compute the hash of the loaded asset and check that it matches the expected SRI hash you got from us.

In either case, the expected SRI hash is something you hard-code, so you know it can't be meddled with. If you were to make a runtime API call to get or "validate" it, someone could just intercept that along with intercepting the request to get the asset itself and modify both.

alexandrosmagos commented 1 year ago

Hello, and thanks for the fast reply.

As for my use case, my service I am building downloads the internal library files loaded on a site, and generates the hash for the file, in the sha512 format as the ones provided from your service. For the endpoint I am suggesting, I will be sending the SRI hash I generated, and the endpoint will tell me if it exists, therefore valid/unmodified file.

Would have coded an example in the api-worker myself, but not really familiar with the cloudflare worker, and couldn't get it to load information from the backend (something with the keys).

If the endpoint search, isn't that resource instensive, I believe this could improve some other malicious website scanners as well.

jimaek commented 1 year ago

Maybe something like this? https://www.jsdelivr.com/docs/data.jsdelivr.com#tag--Lookup

MattIPv4 commented 1 year ago

I will be sending the SRI hash I generated, and the endpoint will tell me if it exists, therefore valid/unmodified file.

That is not how SRI checking should work -- SRI checking is an end-user activity, not a host activity. You should have an expected SRI value, and check that your computed hash matches that. Asking us if a given hash exists verifies almost nothing -- the request could've been intercepted to always return true etc., and a malicious file's hash could theoretically match the hash of another random file on cdnjs.

Based on the explanation of what you are doing, as I said earlier, you should be setting the integrity value for those libraries loaded on the site, so you know what the expected hash is and can compare your computed one to it to make sure it's valid. If for some reason that isn't possible and you want to look up expected SRI hashes against our API at runtime (which as I've noted isn't particularly secure as someone could intercept that request if they're already intercepting the request for the library itself to inject malicious code), our library version endpoint reports the expected SRI hashes for a given library which you could then compare to your locally computed hashes

If the endpoint search, isn't that resource intensive

The way the data for the API is structured is based on libraries, so given an SRI hash, we would have to search over every library and every version of said library. That is incredibly resource-intensive.

MattIPv4 commented 1 year ago

(Also, fwiw, our SRI hash calculations don't always seem to be correct -- this has been flagged to the folks responsible at Cloudflare many times, but nothing has been done yet as far as I know: https://github.com/cdnjs/cdnjs/issues/14080)

MattIPv4 commented 1 year ago

Maybe something like this? https://www.jsdelivr.com/docs/data.jsdelivr.com#tag--Lookup

I think in isolation, what's being requested here is essentially that, yes. The context here though seems to be using it to verify that a file's contents are what is expected, which seems like a very dangerous use of an endpoint like that (as I've outlined above).

alexandrosmagos commented 1 year ago

Maybe something like this? https://www.jsdelivr.com/docs/data.jsdelivr.com#tag--Lookup

Thanks for the suggestion, that's exactly what I've looking for.

(Also, fwiw, our SRI hash calculations don't always seem to be correct -- this has been flagged to the folks responsible at Cloudflare many times, but nothing has been done yet as far as I know: cdnjs/cdnjs#14080)

I mean a single extra space in the code, changes the whole hash, so yeah. Haven't read that exactly what happened there, but yeah.. Thanks your time anyways!