WordPress / openverse

Openverse is a search engine for openly-licensed media. This monorepo includes all application code.
https://openverse.org
MIT License
240 stars 194 forks source link

Proxy frontend API requests through Nuxt #3473

Open sarayourfriend opened 10 months ago

sarayourfriend commented 10 months ago

Problem

Our approach to anonymous rate limiting inadvertently affects single IP address institutions like schools and libraries. In these cases, all users on their networks are rate limited as a single user. We've observed this happening especially when the referrer is openverse.org, meaning these are likely to be regular frontend users getting rate limited.

Description

The Openverse frontend should proxy API requests and forward the SSR server's API key with requests. This would prevent anonymous rate limiting applying to API requests from the frontend and would allow us to safely turn anonymous rate limiting back on in the API.

If it's quick to do, using a CSRF token + cookie combination would make this slightly more resilient to attacks, but we can do that in a follow up PR if it's too complex to implement right away.

Documents

Due to the small size of this project, a project plan can be skipped and only an implementation plan should be necessary

Issues

Prior Art

sarayourfriend commented 10 months ago

This is way harder than I thought it would be, mostly because of the api service object pattern.

I think things could be simplified quite a bit (type wise and code wise) if we refactored to get rid of the service object pattern and instead had a single configured axios instance injected into the Nuxt context (which would have the base URL and the access token when needed), and then helper functions to make specific requests as needed. The current pattern is a weird mash up of functional and OOP that's resulted in some really confusing patterns. Most of that comes from creating the stateful api service object in multiple different places with slightly different configurations. A set of helper functions when needed that take in a configured axios instance and make the call as needed, returning the types as needed as well, would be a big cleaner and would eliminate the multiple-entrypoint issue with axios right now.

I don't know what the right thing to do here is though. @obulat @dhruvkb and @krysal what do y'all think? How would y'all proceed?

sarayourfriend commented 5 months ago

Closing this in favour of https://github.com/WordPress/openverse-infrastructure/issues/746. This project is nullified by the linked issue.

sarayourfriend commented 1 week ago

I am reopening this as an independent project, because it will ultimately be necessary to solve this for the frontend no matter what. There is, unfortunately, no way around it. However, I think the work with #4908 sets a decent precedent of what something could look like for light-weight proxying of API requests, that doesn't let someone easily hijack the frontend to make unlimited requests to the API (and which, anyway, we will continue to have WAF-level rate limits on the frontend to prevent the most egregious examples of that).