Do modern browsers largly prevent reflected XSS attacks? - security

If evildoer injects a malicious URL query string into the victim's browser address bar then that string needs to perform an HTML request in order for the server to reflect the malicious script in the query string. That script will then execute in the victim's browser. When I tried to get a really simple URL query string to perform an HTML request, no request was made. This was the query string and it didn't generate an alert:
localhost:\\index.html?username=<script>alert('xss just happened');</script>
This is a typical reflected xss attack that I've seen presented as an example. Most of the examples seem to be about 10 years old. Is the example lacking some details or are modern browsers better at repelling XSS attacks? Any pointers to background knowledge, as well as a specific explanation, would be very welcome. Thanks!

I'm pretty sure that XSS attack are mostly server vulnerabilities, and happen if a user input is not properly sanitized. I can't tell why your example wouldn't work, but in order for the <script> to execute the entire username field would have to be displayed to the page as-is. Which can still happen, and generally the browser has no default protection for this (Just tried it with a php example of an XSS I had lying around). Try with a dynamic website generator ie. PHP, that takes the query string and directly displays the entire string.
There are standard HTTP headers in place for the prevention and mitigation of XSS attacks, notably X-XSS-Protection and Content-Security-Policy, but as I understand it those are up to the website devs to implement.
It seems that XSS protection hasn't really improved, on the contrary, it has been somewhat removed from most browsers.
There's a reason that most examples you find are 10+years old, as XSS is a somewhat simple and basic vulnerability, that can be solved very well by making sure that no user input ever goes directly through the server, and must be properly sanitized.

localhost:\\index.php?username=<script>alert('xss just happened');</script>
You'll have a reflected XSS if index.php do not escape value from query string, for example:
<?php echo "Hello, ".$_GET['username']; ?>
localhost:\\index.html?username=<script>alert('xss just happened');</script>
You'll have a reflected XSS if script in index.html do not escape value from query string and print it at the page, for example:
<script>
const urlParams = new URLSearchParams(window.location.search);
const username = urlParams.get('username');
document.write('Hello, ' + username);
</script>
Above are "classic XSS" examples, those are very rare in professional code.
But there is a lot of other XSS attack vectors, because evil code can get into page via other vulns (DNS spoofing, MItM attack, malicious browser plugins, etc):
Scriptless XSS like CSSAR, SVG-keylogger
Script XSS like "DOM based XSS", "Dangling markup attacks", PRSSI, "Client side prototype pollution" - reCaptcha Google still vulnerable.
various techniques for bypassing CSPs, for example by using the browser cache if page is lodade from cache, the HTTP headers are nor restored.
There are so many XSS attack vectors that it is impossible to describe them all in one article. But Google will help you, just ask it.

Related

Why do some consider 2nd-order (aka persistent) XSS to not be true XSS?

I'm reading "The Web Application Hacker's Handbook", and it talks about the differences between 1st-order (aka reflected) XSS and 2nd-order (aka persistent) XSS. It mentions how reflected XSS takes advantage of incomplete or nonexistent sanitization of query string params to execute arbitrary scripts into the user's DOM without persisting any malicious code to the application's database, and how 2nd-order XSS does in fact persist that malicious code, to be executed in the user's DOM at some later time.
My question relates to the author's desription of 2nd-order XSS (on page 438, if you've got a copy handy). The description from the book states that:
Attacks against stored XSS vulnerabilities typically involve at least
two requests to the application. In the first, the attacker posts some
crafted data containing malicious code that the application stores. In
the second, a victim views a page containing the attacker’s data, and
the malicious code is executed when the script is executed in the
victim’s browser. For this reason, the vulnerability is also sometimes
called second-order cross-site scripting. (In this instance, “XSS” is
really a misnomer, because the attack has no cross-site element. [emphasis mine] The
name is widely used, however, so we will retain it here.)
In 2nd-order XSS, the malicious code that the attacker still injects is (presumably) still some arbitrary script pointing to an external server (for example, injecting an img tag with a src attribute of "http://www.malicioussite.dom" + document.cookie). I'm confused why the author then states that this attack has no cross-site element. Making a request to the malicious external server seems to me like a proper cross-site element. Am I missing something?
To me, 'cross-site' in XSS means that the malicious script itself is directly sent from another site. Like for example in case of reflected XSS on an url parameter, a malicious website A.com can craft a link to the victim website B.com with its attack in a vulnerable parameter of B, and when a user visits A and clicks the link, he will execute the script on B.
So I think it's not about what the malicious script is doing, it's where it comes from (and how).
In case of stored XSS, the script is usually entered on the vulnerable website directly, however that may not always be the case, such maintaining the original 'cross-site' element. But it doesn't matter, the name is the same, because the underlying problem and also the solution in code are the same, so the name of the vulnerability is the same too. :)
Whatever people call it though, the important thing is to avoid it. :)

What is cross site scripting?

On this site (archived snapshot) under “The Theory of XSS’, it says:
the hacker infects a legitimate web page with his malicious client-side script
My first question on reading this is: if the application is deployed on a server that is secure (as is the case with a bank for example), how can the hacker ever get access to the source code of the web page? Or can he/she inject the malicious script without accessing the source code?
With cross-site scripting, it's possible to infect the HTML document produced without causing the web server itself to be infected. An XSS attack uses the server as a vector to present malicious content back to a client, either instantly from the request (a reflected attack), or delayed though storage and retrieval (a stored attack).
An XSS attack exploits a weakness in the server's production of a page that allows request data to show up in raw form in the response. The page is only reflecting back what was submitted in a request... but the content of that request might hold characters that break out of ordinary text content and introduce HTML or JavaScript content that the developer did not intend.
Here's a quick example. Let's say you have some sort of templating language made to produce an HTML page (like PHP, ASP, CGI, or a Velocity or Freemarker script). It takes the following page and substitutes "<?=$name?>" with the unescaped value of the "name" query parameter.
<html>
<head><title>Example</title></head>
<body>Hi, <?=$name?></body>
</html>
Someone calling that page with the following URL:
http://example.com/unsafepage?name=Rumplestiltskin
Should expect to see this message:
Hi, Rumplestiltskin
Calling the same page with something more malicious can be used to alter the page or user experience substantially.
http://example.com/unsafepage?name=Rumplestiltskin<script>alert('Boo!')</script>
Instead of just saying, "Hi, Rumplestiltskin", this URL would also cause the page to pop up an alert message that says, "Boo!". That is, of course, a simplistic example. One could provide a sophisticated script that captures keystrokes or asks for a name and password to be verified, or clears the screen and entirely rewrites the page with shock content. It would still look like it came from example.com, because the page itself did, but the content is being provided somewhere in the request and just reflected back as part of the page.
So, if the page is just spitting back content provided by the person requesting it, and you're requesting that page, then how does a hacker infect your request? Usually, this is accomplished by providing a link, either on a web page or sent to you by e-mail, or in a URL-shortened request, so it's difficult to see the mess in the URL.
<a href="http://example.com?name=<script>alert('Malicious content')</script>">
Click Me!
</a>
A server with an exploitable XSS vulnerability does not run any malicious code itself-- its programming remains unaltered-- but it can be made to serve malicious content to clients.
That attacker doesn't need access to the source code.
A simple example would be a URL parameter that is written to the page. You could change the URL parameter to contain script tags.
Another example is a comment system. If the website doesn't properly sanitize the input/output, an attacker could add script to a comment, which would then be displayed and executed on the computers of anyone who viewed the comment.
These are simple examples. There's a lot more to it and a lot of different types of XSS attacks.
It's better to think of the script as being injected into the middle of the conversation between the badly coded web page and the client's web browser. It's not actually injected into the web page's code; but rather into the stream of data going to the client's web browser.
There are two types of XSS attacks:
Non-persistent: This would be a specially crafted URL that embeds a script as one of the parameters to the target page. The nasty URL can be sent out in an email with the intent of tricking the recipient into clicking it. The target page mishandles the parameter and unintentionally sends code to the client's machine that was passed in originally through the URL string.
Persistent: This attack uses a page on a site that saves form data to the database without handling the input data properly. A malicious user can embed a nasty script as part of a typical data field (like Last Name) that is run on the client's web browser unknowingly. Normally the nasty script would be stored to the database and re-run on every client's visit to the infected page.
See the following for a trivial example: What Is Cross-Site Scripting (XSS)?

Validating inputted strings as URLs - worth it for security?

In a web application I'm writing, I give logged-in visitors the opportunity to enter a URL to go with their uploaded picture, as a link back to their site.
I was going to validate the string entered to make sure it was a URL, but after mulling the complexity of the solutions out there, I thought maybe it's not necessary.
However, are there any security implications that I might be missing by not doing so? (I'm thinking of situations where a valid URL might include some malicious scripting, or similar.)
The security issue with URLs is less to do with their validity (though it's good to have basic checks in order to catch mistakes, and naturally you need to use the same input validation and output escaping code as you use for data in general); it's more to do with dangerous URL schemes.
Most notably javascript: URLs aren't really locations at all, but script content to inject into the page that links them, resulting in cross-site scripting vulnerabilities. There are other schemes with similar issues. Best is to allow only known-good schemes, for example by checking that the string begins with http:// or https://.
This feature seems to be a perfect example for a Cross-Site Request Forgery (CSRF) attack where the uploader links to a web page that triggers the CSRF attack.
To mitigate the risk of CSRF attacks, make sure that actions with site effects cannot be predicted by the attacking site. This is generally done by a so called token, a random value that is only known to your site and the logged-in visitors.
Correctly validating a URL is not trivial. You can get close, but it still won't necessarily cover everything allowed by the RFCs. As long as you aren't evaluating the URLs as input, running html_escape() or your framework's equivalent should be a sufficient precaution to protect your site from casual string mischief.
You may need to research your framework to understand what precautions, if any, you need to make against cross-site scripting, SQL injection, and other related issues. Most things that can go wrong will relate to unsanitized input, but your mileage may vary quite a bit.
Protecting the user is probably not a reasonable design goal if you expect 100% safety. The web is not a protected sandbox, after all.

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.)

Checklist for Web Site Programming Vulnerabilities

Watching SO come online has been quite an education for me. I'd like to make a checklist of various vunerabilities and exploits used against web sites, and what programming techniques can be used to defend against them.
What categories of vunerabilities?
crashing site
breaking into server
breaking into other people's logins
spam
sockpuppeting, meatpuppeting
etc...
What kind of defensive programming techniques?
etc...
From the Open Web Application Security Project:
The OWASP Top Ten vulnerabilities (pdf)
For a more painfully exhaustive list: Category:Vulnerability
The top ten are:
Cross-site scripting (XSS)
Injection flaws (SQL injection, script injection)
Malicious file execution
Insecure direct object reference
Cross-site request forgery (XSRF)
Information leakage and improper error handling
Broken authentication and session management
Insecure cryptographic storage
Insecure communications
Failure to restrict URL access
I second the OWASP info as being a valuable resource. The following may be of interest as well, notably the attack patterns:
CERT Top 10 Secure Coding Practices
Common Attack Pattern Enumeration and Classification
Attack Patterns
Secure Programming for Linux and Unix
A Taxonomy of Coding Errors that Affect Security
Secure Programming with Static Analysis Presentation
Obviously test every field for vulnerabilities:
SQL - escape strings (e.g. mysql_real_escape_string)
XSS
HTML being printed from input fields (a good sign of XSS usually)
Anything else thatis not the specific purpose that field was created for
Search for infinite loops (the only indirect thing (if a lot of people found it accidentally) that could kill a server really).
Some prevention techniques:
XSS
If you take any parameters/input from the user and ever plan on outputting it, whether in a log or a web page, sanitize it (strip/escape anything resembling HTML, quotes, javascript...) If you print the current URI of a page within itself, sanitize! Even printing PHP_SELF, for example, is unsafe. Sanitize! Reflective XSS comes mostly from unsanitized page parameters.
If you take any input from the user and save it or print it, warn them if anything dangerous/invalid is detected and have them re-input. an IDS is good for detection (such as PHPIDS.) Then sanitize before storage/printing. Then when you print something from storage/database, sanitize again!
Input -> IDS/sanitize -> store -> sanitize -> output
use a code scanner during development to help spot potentially vulnerable code.
XSRF
Never use GET request for
destructive functionality, i.e.
deleting a post. Instead, only
accept POST requests. GET makes it extra easy for hackery.
Checking the
referrer to make sure the request
came from your site does not
work. It's not hard to spoof the
referrer.
Use a random hash as a token that must be present and valid in every request, and that will expire after a while. Print the token in a hidden form field and check it on the server side when the form is posted. Bad guys would have to supply the correct token in order to forge a request, and if they managed to get the real token, it would need to be before it expired.
SQL injection
your ORM or db abstraction class should have sanitizing methods - use them, always. If you're not using an ORM or db abstraction class... you should be.
SQL injection
XSS (Cross Site Scripting) Attacks
Easy to oversee and easy to fix: the sanitizing of data received from the client side. Checking for things such as ';' can help in preventing malicious code being injected into your application.
G'day,
A good static analysis tool for security is FlawFinder written by David Wheeler. It does a good job looking for various security exploits,
However, it doesn't replace having a knowledgable someone read through your code. As David says on his web page, "A fool with a tool is still a fool!"
HTH.
cheers,
Rob
You can get good firefox addons to test multiple flaws and vulnerabilities like xss and sql injections from Security Compass. Too bad they doesn't work on firefox 3.0. I hope that those will be updated soon.

Resources