# CORS support and workarounds

**URL:** <https://forum.beeminder.com/t/cors-support-and-workarounds/5935>\
**Category:** Bugabee\
**Created:** [October 26, 2019, 7:40pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935 "2019-10-26T19:40:41Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![olimay](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/olimay/32/4839_2.png) [@olimay](https://forum.beeminder.com/u/olimay)\
**Post date:** [October 26, 2019, 7:40pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/1 "2019-10-26T19:40:41Z")

</div>

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:

> [@Show me the Future!](https://forum.beeminder.com/t/show-me-the-future/5484/29):
>
> A few years ago, I was working on hacking up something like what @phi is describing with the Beeminder API and D3. I kind of dropped it when I learned about cross domain scripting restrictions and realized I needed to code a backend. (I was jumping into D3 without having properly learned JS.) It’s sitting around somewhere. The purpose of my thing was more specific, though. Back then I had several time input goals, and I wanted to have a dashboard that could warn me before things saturated. I wa…

I was incidentally working again with D3 in [Observable](https://observablehq.com/) 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](https://glitch.com/), which I still haven’t tried.

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

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [October 27, 2019, 12:01am UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/2 "2019-10-27T00:01:32Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [October 27, 2019, 2:24pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/3 "2019-10-27T14:24:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [October 27, 2019, 3:43pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/4 "2019-10-27T15:43:03Z")

</div>

> [@adamwolf](#):
>
> 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

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.

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [October 27, 2019, 5:13pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/5 "2019-10-27T17:13:55Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![olimay](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/olimay/32/4839_2.png) [@olimay](https://forum.beeminder.com/u/olimay)\
**Post date:** [October 27, 2019, 6:20pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/6 "2019-10-27T18:20:24Z")

</div>

> [@adamwolf](#):
>
> 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.

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.

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [October 27, 2019, 7:32pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/7 "2019-10-27T19:32:16Z")

</div>

I here ya, @adamwolf. 🙂

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [October 27, 2019, 7:44pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/8 "2019-10-27T19:44:45Z")

</div>

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

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](http://api.beeminder.com), with a wildcard CORS policy, rather than open up a [www.beeminder.com/api](http://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.

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [October 27, 2019, 8:29pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/9 "2019-10-27T20:29:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [October 27, 2019, 8:41pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/10 "2019-10-27T20:41:44Z")

</div>

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](https://www.beeminder.com/api/v1/auth_token.json)?  
Would the browser send the [beeminder.com](http://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.

---

<div class="post-metadata">

**Author:** ![mutdmour](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/mutdmour/32/3081_2.png) [@mutdmour](https://forum.beeminder.com/u/mutdmour)\
**Post date:** [October 29, 2019, 8:41am UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/11 "2019-10-29T08:41:52Z")

</div>

Ended up deploying my own backend to get around this

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [October 29, 2019, 8:08pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/12 "2019-10-29T20:08:17Z")

</div>

Look at that! If we make sure that

Access-Control-Allow-Credentials: true

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

---

<div class="post-metadata">

**Author:** ![adamwolf](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/adamwolf/32/484_2.png) [@adamwolf](https://forum.beeminder.com/u/adamwolf)\
**Post date:** [November 8, 2019, 8:23pm UTC](https://forum.beeminder.com/t/cors-support-and-workarounds/5935/13 "2019-11-08T20:23:56Z")

</div>

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