Security Issue - Allowing user to add his own JavaScript (only during runtime) - javascript

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.

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.

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.

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.

Related

How to check if website was loaded securely

I was wondering whatever there is way to check in JavaScript that the website was loaded fully securely, and that it was not modified on user's site (for example by malicious addon)
I found that often such malicious addons are breaking SSL by adding adverts or other malicious scripts, therefore I am wondering how could I detect mixed content warning such as displayed on this image:
(the image taken from https://www.ssl2buy.com/wiki/fix-mixed-content-nonsecure-items-error-on-ssl-secure-site )
I have found the following questions, however I believe that those questions do not fully answer my question:
How can I use JavaScript on the client side to detect if the page was encrypted?
How do I determine whether a page is secure via JavaScript?
My question is how to detect if website was loaded insecurely (or modified at user's end), even if protocol used was https://
side note: I know that such script could be easily deleted by an addon that adds the malicious scripts/adverts/etc., however I prefer to have additional layer of security.
I was wondering whatever there is way to check in JavaScript that the
website was loaded fully securely
Well assuming a malicious addon is able to manipulate your DOM content I belive you can't.
You can however check whether the page was loaded fully encrypted.
One approach for doing so is to check the protocol of A) the current URL and B) all href and src attributes in your DOM.
But this cannot proof that your page was loaded fully securely. It may only confirm that all loaded content on your site was encrypted, but an attacker can (and they actually do) get a TLS/SSL certificate (e.g. using letsencrypt) and simply distributes its malicious code using HTTPS.
Furthermore, you would have to check your DOM for iFrames which might also be able to execute malicious code.
The only thing you could do that might addresses the issue is to check all hrefs & src as mentioned above and additionally compare them against a whitelist.
Eventually as you already mentioned, your script can be easily blocked by the malicious addon. Therefore, I am not convinced such a script is worth the time.

Prefilling form on extern webpage

There's some website (not mine, it's third party) that has a form on it. In order to spare the user from having to fill out this form, I want to somehow prefill it with data I have stored in my database.
Let's say it looks like this:
<form id='form1'>
<input type='text' id='input1' />
<input type='submit' />
</form>
I though a solution would be to create my webpage, and on it create an iframe with the form I want to fill.
<iframe id='myFrame' src='http://www.someSite.html'>
I have followed some suggestions here about how to access content in an iframe: Getting Contents of Iframe with Pure JavaScript, How to get the body's content of an iframe in Javascript?, but the problem is, when I follow them, it says that the content of the page is null.
I found out that it's because the page with the form is on a different domain, so web browsers don't allow it. It's possible to turn this off in the browser, but I need it to work independently of browser settings.
You can't do what you're asking in a simple web page. The security restrictions exist for a reason; imagine if a malicious user wanted to load, say, your banking site in an iframe and have you login. The malicious script on the hosting page would then have access to the form where you enter your credentials, account information, etc, etc.
As #mplungjan stated, you have to work around this by either making requests from your server and proxying them, so that the remote content actually goes through your site first, or by getting the user to modify their browser environment with a plugin or a bookmarklet.

3'rd party cookie - advertisers - implementation clarification?

As I'm reading a lot about third party javascript/cookies - I have an implementation question.
I've seen this slide show (#45) (the context of the slide is about cross domain but it is used also for advertisers)
AFAIK it goes like this :
First enterence to Site #1 : the site has a page .that page also holds an advertiser iframe from TotalNotTrackingYou.com.
The SRC of the iframe has general info for that particular page content ( if any ).
So TotalNotTrackingYou.com sends a cookie with identification token when the page #1 loads .
This way - when you browse to other pages besides site #1 ( notice ! the user didn't click on any add yet !) - TotalNotTrackingYou.com knows what intereting topics you are interested .
Now the user has left site #1 and went to site #2 which also holds an iframe from TotalNotTrackingYou.com. Same goes here. the cookie which was generated by site #1 request (which in turn loads an iframe) - is sent back to TotalNotTrackingYou.com which again - reads the referrer and the relevant querystring (at SRC) for that iframe .
TotalNotTrackingYou.com (sends you cookies when their iframe loads at sites #1..#5) and learning only your navigation habbit (using referrer - which site you were on).But when you click on the advertising add - TotalNotTrackingYou.com now knows for sure what you are intereted in , and they add it to their db.
from now on - all sites (which holds TotalNotTrackingYou.com iframe) will send relevant adds according to the user interests list..
Question
A script reference <script src='www.TotalNotTrackingYou.com/cookiecreator.ashx' /> can also send / recieve cookies. So why advertisers don't use scripts but iframes ?
Additional info.
I know that 3rd party cookies are disabled by default in Safari. but there is a hack to create an iframe and a form and to post that form to that iframe - which will write cookie.
This hack in safari to allow 3rd party cookies by posting was fixed. (Btw, Google also received a hefty fine from the FCC for exploiting this "hack": http://www.theverge.com/2012/7/31/3207388/fcc-approval-google-fine-safari-cookies )
In any case, the reason that they use iframes is because the preferred method for storing data associated with the 3rd-party domain is no longer a 3rd party cookie, but instead localStorage. To access the localStorage of the 3rd-party domain, the javascript code has to be running under a document from that domain, hence why the iframe works, and not a script loaded on the 1st party domain.
The benefits of localStorage vs the cookie is that it's not blocked even when the user requests blocking of 3rd-party cookies. See for example this thread from Firefox development:
https://bugzilla.mozilla.org/show_bug.cgi?id=536509 or this article running through the code itself http://log.scalemotion.com/2012/10/how-to-trick-safari-and-set-3rd-party.html

Security implications of textarea direct to DOM

I have a requirement to paste text from a textarea into the DOM as a preview area, much like the one you get on Stackoverflow when you make a comment etc.
I allow users to insert any and all html tags, including javascript tags. I know this will allow embedded javascript and flash content etc, but I then remove all of this server side so no other user will see, they just see plain text.
However are there any security issues in letting the user insert these things in there own page?
My guess is there isn't otherwise tools like firebug would be a security risk, but I'm not sure.
However are there any security issues in letting the user insert these things in there own page?
I can't see any - the DOM is freely manipulable in the client's browser, anyway. Whether they do it using a tool like Firebug or your JavaScript function, doesn't matter.
As long as the data isn't shown unfiltered in other users' browsers, I think you're safe doing this.
Actually in rare set of circumstance, it might be an issue. It highly depends on how this particular feature works, but I can imagine making first use of CSRF to 'post' in the preview area some malicious javascript/ajax, and use that to steal cookies, change account password or whatever tickles your fancy.
So the attack would go something like this; I send a user a link to a 'legitimate' website. On that website there is a hidden payload (eg via img tag in case of GET, or hidden iframe with auto-submitting form for POST) which silently redirects the user to your website with the XSS payload, which then will be executed by the user through the injection in the preview area, for instance logging user's cookies, without him ever knowing.
Again it all depends how your preview feature works, and if you for instance use form tokens etc., but the point is that it in fact could be an issue.

How can I give users a javascript widget to pull content securely from my site

I need to be allow content from our site to be embeded in other users web sites.
The conent will be chargeable so I need to keep it secure but one of the requirements is that the subscribing web site only needs to drop some javascript into their page.
It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site. Is there any other way to do this given that we don't know the client browsers who will be hitting the subscribing sites?
Is the best way to do this to supply a javascript include file that populates a known page element when the page loads? I'm thinking of using jquery so the include file would first call in jquery (checking if it's already loaded and using some sort of namespace protection), then on page load populate the given element.
I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.
Does this sound like a reasonable approach? Is there anything else I should consider?
Thanks in advance,
Mike
It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site.
Ah, but in client-side or server-side code?
They both have their disadvantages. Doing it with server-side code is unreliable because some browsers won't be passing a Referer header at all, and if you want to stop caches keeping a copy of the script, preventing the Referer-check from taking place, you have to serve with nocache or Vary: Referer headers, which would harm performance.
On the other hand, with client-side checks in the script you return, you can't be sure your environment you're running in hasn't been sabotaged. For example if your inclusion script tag was like:
<script src="http://include.example.com/includescript?myid=123"></script>
and your server-side script looked up 123 as being the ID for a customer using the domain customersite.foo, it might respond with the script:
if (location.host.slice(-16)==='customersite.foo') {
// main body of script
} else {
alert('Sorry, this site is not licensed to include content from example.com');
}
Which seems simple enough, except that the including site might have replaced String.prototype.slice with a function that always returned customersite.foo. Or various other functions used in the body of the script might be suspect.
Including a <script> from another security context cuts both ways: the including-site has to trust the source-site not to do anything bad in their security context like steal end-user passwords or replace the page with a big goatse; but equally, the source-site's code is only a guest in the including-site's potentially-maliciously-customised security context. So a measure of trust must exist between the two parties wherever one site includes script from another; the domain-checking will never be a 100% foolproof security mechanism.
I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.
You can certainly add stylesheet elements to the document's head element, but you would need some strong namespacing to ensure it didn't interfere with other page styles. You might prefer to use inline styles for simplicity and to avoid specificity-interference from the page's main style sheet.
It depends really whether you want your generated content to be part of the host page (in which case you might prefer to let the including site deal with what styles they wanted for it themselves), or whether you want it to stand alone, unaffected by context (in which case you would probably be better off putting your content in an <iframe> with its own styles).
I'm thinking of using jquery so the include file would first call in jquery
I would try to avoid pulling jQuery into the host page. Even with noconflict there are ways it can conflict with other scripts that are not expecting it to be present, especially complex scripts like other frameworks. Running two frameworks on the same page is a recipe for weird errors.
(If you took the <iframe> route, on the other hand, you get your own scripting context to play with, so it wouldn't be a problem there.)
You can store the users domain, and a key within your local database. That, or the key can be an encrypted version of the domain to keep you from having to do a database lookup. Either one of these can determine whether you should respond to the request or not.
If the request is valid, you can send your data back out to the user. This data can indeed load in jQuery and and additional CSS reference.
Related:
How to load up CSS files using Javascript?
check if jquery has been loaded, then load it if false

Categories

Resources