Bypassing bad CORS configurations with YARP

I was recently trying to work with a (questionably designed) REST API that had its CORS configuration set up to only allow client-side requests from their own domain, effectively limiting any API integrations to being server-side.

Fortunately, CORS is basically just HTTP response headers so if you're willing to run a proxy server (and the API owners/maintainers don't prevent it), you can always set up a reverse proxy to alter the response headers from the API and allow your own domain.


While you can use pretty much any proxy-capable web server here, I'm going to demonstrate how you can do this with YARP, Microsoft's new ASP.NET Core-based reverse proxy server. You could do this with your own server, but I'm going to use my own pre-built YARP server image.

Rather than having to build this in code, we're just going to use YARP's configuration system. In short, you just need to add the following configuration to your server's configuration file:

{
    "ReverseProxy": {
        "Routes": [{
            "RouteId": "proxy-route",
            "ClusterId": "upstream-api",
            "Match": {
                "Path": "{**catch-all}"
            },
            "Transforms": [{
                "ResponseHeader": "Access-Control-Allow-Origin",
                "Set": "https://yourchosendomain.com"
            }]
        }],
        "Clusters": {
            "upstream-api": {
                "Destinations": {
                    "upstream-api/public": {
                        "Address": "https://api.upstream.com/"
                    }
                }
            }
        }
    }
}

Obviously replace your own domain (line 11) and your upstream API address (line 18).

You can also just set the ResponseHeader value to * to allow all, but I don't recommend that!

You can then just use whatever path you were using with the upstream API (/v1/users/info or whatever) with your own domain and YARP will automatically replace the Access-Control-Allow-Origin header in the response, allowing your client.

If you're using my Docker image, just bind-mount that JSON into the container's /app/reverseProxy.json

Comments

comments powered by Disqus