Question

The company I'm working for has a form that can be added to any website with one line of Javascript. Ex:

<script type="text/javascript" src="//ourserver.com/form.js?id=12345" />

On our server side, this is picked up by mod_rewrite and sent to a PHP file that generates the form code (based on the id) and does a document.write with the HTML code, and includes the jQuery Ajax code to handle the form submission.

Of course, browsers and servers aren't huge fans of cross-domain Ajax, but we got it to work by adding the header:

header('access-control-allow-origin: *');

to the form processing script (PHP) on our server. But, from what I've been reading, this (and cross-domain posting in general) can open up a lot of issues with XSS / CSRF exploits.

So, my question is, how should we set up the javascript and the PHP / server to help prevent these exploits, while still allowing the javascript to be put on any domain?

We can't limit the allow-origin header to a specific domain, and I tried setting a session token when the form is generated, and then checking it when the form is submitted, but due to how the form is implemented, the session doesn't carry over.

Was it helpful?

Solution

As you are using the Access-Control-Allow-Origin: * header, I am assuming users that submit the form do not use cookie authentication as a credentialed request is not possible with the wildcarded Access-Control-Allow-Origin.

This means that you shouldn't have to worry about CSRF attacks, because the form cannot automatically be submitted in the context of another user.

CSRF usually happens when a user is logged into a site. e.g. www.foo.com and then they visit another site (e.g. www.evil.com) without logging out of www.foo.com. Say www.evil.com includes an image request in the page.

e.g.

<img src="https://www.foo.com/DeleteAccount" />

Because the user is logged into www.foo.com the auth cookie is sent with this request and the user's account is deleted. However, as you are not using auth cookies an attack such as this would not be possible.

Also, as you are not returning any sensitive information from your server, allowing any domain in the Access-Control-Allow-Origin header should be fine, as long as it is only for the handler of the AJAX POST. If you return any error message in the AJAX JSON response, make sure that it does not include any confidential data about your server. This would be an information leakage vulnerability, which is separate to CSRF and XSS.

Onto XSS then... from what you've described there are no extra risks for XSS in your situation than there is for a normal website. The third party site is trusting your site to execute scripts in the context of their domain by including the <script> tag on their page, not the other way round. You simply need to make sure you are correctly encoding any output into your .js file or into your JSON response. JS encoding is the escaping that you need in both of these cases (not HTML encoding). See Rule #3 in the OWASP XSS Prevention Cheat Sheet.

The reason your session method doesn't work is because you haven't included the Access-Control-Allow-Credentials: true in your response, so cookies will not be sent with the POST. If you wanted to use this, you would have to change your Access-Control-Allow-Origin header to reflect the Origin header within the request (because the * wildcard is not allowed with credentialed requests).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top