How do I protect sensitive information from cross site access? - cross-domain

My web application displays some sensitive information to a logged in user. The user visits another site without explicitly logging out of my site first. How do I ensure that the other site can not access the sensitive information without accept from me or the user?
If for example my sensitive data is in JavaScript format, the other site can include it in a script tag and read the side effects. I could continue on building a blacklist, but I do not want to enumerate what is unsafe. I want to know what is safe, but I can not find any documentation of this.
UPDATE: In my example JavaScript from the victim site was executed on the attacker's site, not the other way around, which would have been Cross Site Scripting.
Another example is images, where any other site can read the width and height, but I don't think they can read the content, but they can display it.
A third example is that everything without an X-Frame-Options header can be loaded into an iframe, and from there it is possible to steal the data by tricking the user into doing drag-and-drop or copy-and-paste.

The key point of Cross Site Attack is to ensure that your input from user which is going to be displayed, is legal, not containing some scripts. You may stop it at the beginning.

If for example my sensitive data is in JavaScript format, the other site can include it in a script tag
Yep! So don't put it in JavaScript/JSONP format.
The usual fix for passing back JSON or JS code is to put something unexecutable at the front to cause a syntax error or a hang (for(;;); is popular). So including the resource as a <script> doesn't get the attacker anywhere. When you access it from your own site you can fetch it with an XMLHttpRequest and chop off the prefix before evaluating it.
(A workaround that doesn't work is checking window.location in the returned script: when you're being included in an attacker's page they have control of the JavaScript environment and could sabotage the built-in objects to do unexpected things.)

Since I did not get the answer I was looking for here, I asked in another forum an got the answer. It is here:
https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.security/9U6HTOh-p4g
I also found this page which answers my question:
http://code.google.com/p/browsersec/wiki/Part2#Life_outside_same-origin_rules

First of all like superpdm states, design your app from the ground up to ensure that either the sensitive information is not stored on the client side in the first place or that it is unintelligible to a malicious users.
Additionally, for items of data you don't have much control over, you can take advantage of inbuilt HTTP controls like HttpOnly that tries to ensure that client-side scripts will not have access to cookies like your session token and so forth. Setting httpOnly on your cookies will go a long way to ensure malicious vbscripts, javascripts etc will not read or modify your client-side tokens.

I think some confusion is still in our web-security knowledge world. You are afraid of Cross Site Request Forgery, and yet describing and looking for solution to Cross Site Scripting.
Cross Site Scripting is a vulnerability that allows malicious person to inject some unwanted content into your site. It may be some text, but it also may be some JS code or VB or Java Applet (I mentioned applets because they can be used to circumvent protection provided by the httpOnly flag). And thus if your aware user clicks on the malicious link he may get his data stolen. It depends on amount of sensitive data presented to the user. Clicking on a link is not only attack vector for XSS attack, If you present to users unfiltered contents provided by other users, someone may also inject some evil code and do some damage. He does not need to steal someone's cookie to get what he wants. And it has notnig to do with visiting other site while still being logged to your app. I recommend:XSS
Cross Site Request Forgery is a vulnerability that allows someone to construct specially crafted form and present it to Logged in user, user after submitting this form may execute operation in your app that he didin't intended. Operation may be transfer, password change, or user add. And this is the threat you are worried about, if user holds session with your app and visits site with such form which gets auto-submited with JS such request gets authenticated, and operation executed. And httpOnly will not protect from it because attacker does not need to access sessionId stored in cookies. I recommend: CSRF

Related

When to use random tokens to prevent XSS?

This isn't a language specific question, but I am using PHP5.
I am working on a project that has some amount of PII. Legally we are required to secure this data from hacking attempts, and because of that I have been researching best practices for defending common attack types. Obviously all database calls are using parameterized queries, and all data provided by the user is sanitized to prevent injection. I have also implemented sessions and methods to prevent session hijacking.
When it comes to defending against XSS attacks on forms, best practice seems to be to include a hidden input with a form token, then after the post to check the tokens match. There are further ways to make this more secure.
I have imagined one type of attack and haven't found a solution for it. What if a malicious site loads a hidden iframe pointed at my site (eg, view-member.php?id=1234) and because the victim user is logged into my site, their session continues in that iframe. What is stopping this malicious site from iterating through the IDs and ripping the data to get ahold of PII? Should I be creating a unique token for each page view, and checking that token when the page loads?
I am not 100% sure, but assuming my site is using HTTPS, the browser should warn the user and/or prevent the connection. Is that correct? Is that enough security?
In fact, everytime you present a form or any kind of interaction, you should include a randomized, verifiable piece of information that changes every time. This is not for preventing XSS but CSRF: https://en.wikipedia.org/wiki/Cross-site_request_forgery
The main problem is: An attacker can just send automated requests to your input-handling script without going through the "pain" of filling in your form manually (or even visit your page).
However, you won't prevent XSS attacks with this technique, as XSS attacks are mainly user input containing executable code (javascript) that is not filtered by the input validation. So to prevent XSS as well, you should always make sure not to deliver unfiltered user-generated content anywhere.
HTTPS won't help you in either case unless you use client-side certificates that allow access to your website only from trusted clients. HTTPS mainly acts as a transmission scrambler and identity verifier but does not prevent a bot from sending valid (but malicious) data to your form.
Hosting a website in an iFrame does not grant the attacker the permission to read cookies or information from the target page (that would be awful) as long as you follow the same-origin policy: https://en.wikipedia.org/wiki/Same-origin_policy
With this, only domains you whitelist will get access to information hosted on your page.

GET vs. POST in Session Validation

So I just read this article by Jeff Atwood and I wanted to make sure I understand it correctly as to how it applies to my use case. I am trying to validate a session for silent login. For security purposes this should be done with a POST right? Does it matter? I am just passing the sessionID and username from the cookie.
When it comes to CSRF (Cross-site request forgery), you can cause a user to take any action on any site which they are logged in to provided that the action requires only a GET. Forcing this to be done over a POST request defeats the approach of embedding an image, script tag, whatever in another page.
Even POST isn't completely secure in this scenario. There are other ways to mount a CSRF attack on a site using POST. Clickjacking/UI-Redressing enables another site to trick a user into submitting a form to a different website.
Basically the best way to validate is to add an automatically generated, hidden form element. You can store this inside your session data (Example: $_SESSION for PHP) so that you only need to generate a token at the start of a session. Of course, an attack could try do something like clickjacking (mentioned above) in combination with a iframe pointing directly to your site and possibly some JS to hide things a little.
For anything important you should re-prompt the user for their password, thereby greatly diminishing the value of any successful CSRF attacks.

are precautions against CSRF needed for view-only pages?

All the examples of CSRF exploits tend to be against pages which process the incoming request.
If the page doesn't have a form processing aspect do I need to worry about CSRF ?
The situation I'm looking # :
the page in question contains sensitive data
as such users need to establish a session to view the page
... my understanding is that a malicious page will be able to redirect a client to this page by embedding a link to it, however since there's no action on the target to perform there's no harm that can result, right ?
There's no way for said malicious site can view the sensitive page, correct ?
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility, and so I'd like to avoid them if possible.
There's no way for said malicious site can view the sensitive page, correct ?
Correct in terms of CSRF.
The blog you linked is talking about Cross-Origin Script Inclusion, which is a different animal. To be vulnerable to XOSI your sensitive page would have to be interpretable as JavaScript, and you'd have to be either serving it without a proper HTML MIME type, or the browser would have to be an old one that didn't enforce type checking on scripts.
You might also potentially worry about clickjacking, where another site includes yours in a frame and overlays misleading UI elements. There are some sneaky ways that has been used to extract sensitive data (see the next generation clickjacking paper and this amusing info leak in Firefox) so you may wish to disallow framing with the X-Frame-Options header.
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility
You definitely shouldn't be putting a CSRF token in a GET URL. Apart from the ugliness, and breakage of navigation, URLs are easy to leak from the browser or other infrastructure, potentially compromising the confidentiality of the token.
Normal practice is not to put CSRF protection on side-effect-free actions.
In general, CSRF is independent from whether the request causes any side effects or not. The CWE describes CSRF (CWE-352) as follows:
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
So CSRF is a general request intention authenticity problem.
However, although CSRF is not really feasible without any effects other than data retrieval as the same-origin policy restricts the attacker from accessing the response, the attacker could exploit another vulnerability to profit from retrieval-only requests as well and gain access to sensitive data.

Admin access through a GET parameter

I'm working on a really simple web site. I usually do a full blown admin to edit the site, but this time I thought about editing in place (contenteditable="true").
To simplify login for the user, I'd like to just give him a password that he can type in the address bar to log him in, instead of the usual login form. So he would visit domain.com/page?p=the_password and then I would store his data in a session and give him a cookie with a session id (usual stuff) and redirect him to domain.com/page.
How safe / unsafe is this? I'm doing this in PHP, but I guess it applies to any server-side language.
Your login idea is unsafe: URLs for requests end up in web server logs and other places besides, so that means passwords will end up in web server logs.
Your "contentedittable" idea is probably unsafe, but in a more subtle way. It's also (again, probably) non-compliant with the HTTP specification.
GET requests should always be idempotent. This is because user agents (browsers, caches, etc...) are allowed to reissue the same GET request any number of times without user consent. One reason why a browser might do that is because the user pressed the back button and the previous page is no longer in the cache. If the request is not idempotent then issuing it a second time may have an unexpected and unwanted side effect.
It sounds like your "editing in place" feature might not always be idempotent. There are many kinds of simple edits which are in fact idempotent so I could be wrong, but as soon as you have for example the ability to add a new item to a list via this kind of interface it's not.
Non-idempotent requests should be issued through methods like PUT, POST, and DELETE.
To add to #Celada answer. The URL will be stored in the browser history or network caches/proxies, so the password can leak in this way. Also it would be trivial to login a random Internet user as someone else (Login Cross Site Request Forgery attack), by for example having a web site with an img element pointing to domain.com/page?p=the_password
You don't write about this, but once the user is logged in your scheme needs to protect against Cross Site Request Forgery (so a random page can not perform admin actions on behave of the logged-in user).

XSS as attack vector even if XSS data not stored?

I have a question about XSS
Can forms be used as a vector for XSS even if the data is not stored in the database and used at a later point?
i.e. in php the code would be this:
<form input="text" value="<?= #$_POST['my_field'] ?>" name='my_field'>
Showing an alert box (demonstrate that JS can be run) on your own browser is trivial with the code above. But is this exploitable across browsers as well?
The only scenario I see is where you trick someone into visiting a certain page, i.e. a combination of CSRF and XSS.
"Stored in a database and used at a later point": the scenario I understand about CSS is where you're able to post data to a site that runs JavaScript and is shown on a page in a browser that has greater/different privileges than your own.
But, to be clear, this is not wat I'm talking about above.
Yes, it's still an attack vector.
What you need to consider is:
Can an authenticated user be tricked into viewing this page with maliciously-crafted data?
The answer is this case is yes (assuming you have authenticated users). Because it's possible to direct someone to your site and pass in malicious variables to that field.
Yeah, it's still an attack vector, although impact is more situational.
Here's a contrived scenario that expands on previous answers if the form requires authentication to reach (and is easier if the site doesn't care if forms are submitted via POST or GET):
1) Attacker uses CSRF to login the victim using the attacker's credentials (e.g. <iframe src=http://../login?id=...&pass=..."></iframe>). This way the attacker brings the form to the victim and it doesn't matter if the victim doesn't have an account.
2) Attacker uses another CSRF to execute XSS against the form, which asks the victim for some credentials, etc. (This is where some convincing social engineering needs to occurr or the attacker has some useful JavaScript to use within the browser's Same Origin for the site.)
Another contrived scenario in which the vulnerable form performs some important action, like transfer money between accounts:
0) Vulnerable form uses hidden form fields with random values to prevent CSRF. The attacker doesn't know what the values are and can't set up a proper attack.
1) Attacker creates a CSRF payload that includes JavaScript to read a form's random csrf tokens (i.e. pull them from the browser's DOM).
2) Victim logs into site.
3) Attacker lures victim to CSRF payload, CSRF bootstraps the form request with the correct csrf tokens because it's executing in the victim's browser, within the victim site's Same Origin, and using the victim's auth session. The attacker doesn't need to know the csrf tokens, just be able to manipulate the form fields that store them.
4) Attacker benefits from having the victim submit the form -- no pop-ups or social engineering necessary aside from luring the victim to the CSRF payload, but the form needs to do something "useful" for the attacker.
i think what you are mean is, since User 2 cannot be showing previous data added by User 1, so can the XSS happen? So if User 1 hack the URL so that some $_GET params got displayed on the webpage as well (and then even, change it to a tinyurl), and spread this URL saying that it is really worthwhile to see this page, etc, then it might be possible.
So it is still better to escape all params when displaying the page.
That is absolutely a valid form of XSS. XSS comes in two forms - stored and reflected. Reflected is much more common, but stored has the potential to be more damaging. Reflected XSS is usually used as part of a social engineering attack. An attacker creates a URL like the following:
http://host.com/page.php?my_field=malicious_code
They will often shorten the URL with tinyutl or bit.ly, and get it out with the usual social engineering methods (email, message board, twitter, hijacked facebook accounts, etc.)

Resources