1

I'm currently working on a content generator and I have objects which allow users to add custom scripts to the page.

I'm concerned about the preview of my plugin. Pages cannot be saved in the preview, but can the user mess with my preview page permanently if I allow him to use dynamically added javascript?

I'd also like to mention, the javascript is sent via AJAX to a php file, then appended to the body.

SomeKittens
  • 38,868
  • 19
  • 114
  • 143
Grozav Alex Ioan
  • 1,559
  • 3
  • 18
  • 26
  • If nothing can be saved, nothing can be messed up permanently. However it seems unlikely that nothing can be saved, isn't that the whole purpose of your content generator? – Bergi Apr 05 '14 at 20:16
  • Who does use the content generator? Who will view the generated content (including scripts)? Where do the custom scripts come from? – Bergi Apr 05 '14 at 20:16
  • Indeed, that's the purpose of the content generator. However, it's going to be a paid application and I'm disabling the save features for the preview. The disabling is done with an if(disablesave == true){}, so I'm not sure if this is very efficient. – Grozav Alex Ioan Apr 05 '14 at 20:21
  • Oh that's what you meant by "preview", I had thought about "content preview". If the custom scripts and pages don't leave the client's computer, or you can make sure they will not be served to other people (which implies they're not stored on the server) then you're safe. – Bergi Apr 05 '14 at 20:24

3 Answers3

1

Pages cannot be saved in the preview, but can the user mess with my preview page permanently if I allow him to use dynamically added javascript?

Not permanently, no. He can only mess up his own current page.

If the custom scripts and pages don't leave the client's computer, or you can make sure they will not be served to other people (which implies they're not stored on the server) then you're safe from XSS attacks.

However, notice that as soon as your plugin leaves "preview" and you allow saving pages that are shown to other visitors, you will have that problem.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Yes, this is a big attack vector known as Cross Site Scripting (XSS). You should never run JavaScript provided by your users on arbitrary pages, unless you absolutely must.

For instance, I could add:

document.body.style.display = 'none';

and that would hide the entire page.

SomeKittens
  • 38,868
  • 19
  • 114
  • 143
0

Although your script only displays to the current user, your page may be vulnerable to a Cross Site Scripting attack. The way to handle it in this case (as you are allowing scripts) is to use a similar mechanism to a Cross Site Request Forgery prevention (although CSRF and XSS are completely different).

e.g. if your page https://www.example.com/preview displays all content (HTML and script) POSTed to it (for thie example assume the POSt parameter is called content), an attacker may include the following code on their page and then entice the victim to visit it whilst logged into your website.

On www.evil.com:-

<form method="post" action="https://www.example.com/preview">

<input type="hidden" name="content" value="<script>alert('foo');</script>" />

</form>

and this form could be submitted automatically via JavaScript (document.forms[0].submit()).

This will cause the script in content to be executed in the context of your site, possibly passing cookie values of the user's session to www.evil.com rather than my benign example of an alert box.

However, as your are POSTing the content value to your own site using AJAX, you can prevent this attack by checking that the X-Requested-With request header is set to XMLHttpRequest. This header cannot be POSTed cross domain (without your server agreeing to this using CORS).

Also, if your page is for a preview - what is the preview for if your preview cannot be saved? If this is related to your full save functionality, then it is possible to allow a user to save scripts safely by running the entered content within a sandbox.

Community
  • 1
  • 1
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145