CORS support and workarounds

Hey fellow coders!

I’ve had some half implemented ideas for visualizations and dashboards that use Beeminder data. Some of them have been sitting around since 2015. I’m getting back into vis recently, and was looking forward to prototype once my commitments clear up a bit.

For example:

I was incidentally working again with D3 in Observable a few weekends ago, so I gave some thought to this again. Observable makes prototyping D3 stuff a lot easier, so I thought maybe I don’t have to wait months to get back to recreating was I was working on a few years ago.

One thing: Observable relies on CORS to pull from APIs, which I don’t think the Beeminder API currently supports, and might take a while to support.

I was wondering if anyone had any workarounds, besides deploying their own backend. For example, I know the API works with Glitch, which I still haven’t tried.

Just thinking about the easiest way to do this. Thanks!

2 Likes

Curious why adding CORS support would be so hard for Beeminder to do? That’s just adding a couple headers to responses, yes? I just did this for TaskRatchet, so it’s fresh in my memory.

2 Likes

While I don’t think it would be difficult for Beeminder to set a
specific CORS policy for the API, it’s probably faster to work around
it yourself in development. (You’d either want a backend component or
you’d want Beeminder to set a CORS policy before you deployed to the
public.) The key here is that CORS is really something that’s enforced
at the browser of the client. This is something you nominally
control, so there are a few ways around it. For instance, you can set
up a local proxy that just takes any requests to localhost on a port
and forwards them to Beeminder’s API. I did this a while ago for some
experiments of mine and it’s been working fine. There are a variety
of extensions that turn off CORS protection, but the browser rules
change periodically so there’s a lot of them that don’t work without
extra dinking around in browser settings. I’m certain there’s other
ways, but those are the two I’ve used for various projects recently.

1 Like

I could see that being true for a single user. But it seems doubtful to me if there were more than one user who ran into the issue.

Well, narthur, it’s Sunday, and I’m skeptical any of the Beeminder folks are going to change the CORS policy over a weekend. I set up a local proxy for a web project last week in 10 minutes, so… /shrug?

Makes sense for local projects. I was wondering more because of cloud-based notebook environments like Observable—I thought it would be a cool thing non-technical users being able to try out the notebook, drop their API key into the notebook, and being able to do stuff with their data. The notebook code would run in their browser and would talk directly to the API, all without having to run a proxy themselves.

I could create a proxy in the cloud for people to use, but then I’d be uncomfortable sharing the notebook.

No worries, though. I’m still not going to get around to this for some time. I was just asking ahead.

1 Like

I here ya, @adamwolf. :slight_smile:

OK, so let’s think this through to make it real easy for Beeminder to make this an easy UVI :slight_smile:

So the first gut-level idea is to put a wildcard CORS policy on the current API. I think that’s probably the right choice, but hmm.

What does Beeminder lose, security-wise, putting a wildcard CORS policy on their current API? Does it make sense for Beeminder to serve an API out of a subdomain, like api.beeminder.com, with a wildcard CORS policy, rather than open up a www.beeminder.com/api? I guess if you serve the same API out of either, it doesn’t really get you anything except more complication, but maybe it lays the groundwork for two versions of the API in the future… Hmm. If they ended up splitting their API into a “trusted” and “untrusted” API, they could do the CORS policy splitting then, I guess.

1 Like

What do you see as the threat model for a CORS-wildcard-enabled API? How might an attack go down?

Hmm. If Beeminder had a CORS wildcard API, a malicious website would
be able to fetch https://www.beeminder.com/api/v1/auth_token.json?
Would the browser send the beeminder.com cookie along? If so, that
would expose usernames and authtokens to the malicious site. (I am
not sure if the browser would send the cookie along… while I’ve done
a good amount of security stuff, frontend things have always been
covered by another team member.)

I’ve only been thinking about it for a few minutes, but if that’s the
only endpoint that’d be a problem, maybe this is a good argument for
my “split cors policy” from above. The one with the wildcard policy
would just block auth_token.json.

1 Like

Ended up deploying my own backend to get around this

1 Like

Look at that! If we make sure that

Access-Control-Allow-Credentials: true

is never set, the browser will never send cookies along!

3 Likes

CORS has been added to the API. Have fun, folks. Post anything fun you’re doing with it here to the forum :slight_smile:

3 Likes