I'm trying to find if there's a good way to prevent CSRF on a javascript widget embedded on customers' websites.
The widget would enable end users to make requests against our customers' accounts via JSONP to a a PHP server which proxies those requests to our (non-public) API.
To this point, I haven't come up with a surefire way to ensure all requests are coming from only our customers' websites. Some ideas I've had:
Is this at all possible? I've come across Fotomoto's widget which seems to allow the same type of functionality we are looking for, but am not sure how they're doing it.
You will never find a solution that ensures that requests that come from random third parties (users) are in fact initiated by accessing your customers' website. If your security relies on that, then you have to remove that assumption. (If you really mean "ensure that requests are coming from only our customers' websites" servers then this is trivial: SSL with client-side certificates. But I assume you mean "coming from random user machines with the intent to use our customers' websites.")
What you should be looking for how to prevent users from being tricked (CSRF). So for instance, the fact that Referer can be spoofed is irrelevant for this problem. The only question is whether there is a browser that has a flaw that would allow a third party to trick a user into creating a spoofed Referer. So you should check Referer as necessary but not sufficient. That is to say, if Referer is wrong, hang up on the caller. But the fact that Referer is right does not mean you're actually receiving a legitimate request. Most CSRF I believe is due to failure to check Referer, not browser bugs.
The Wikipedia article on CSRF has a decent summary of the obvious prevention techniques. Just checking Referer is a big first step.