I cannot understand what damage does an XSS attack do. When I add to input, e.g onmouse() function and it display an image, this image will not appear for another user, but for me and will disappear after refreshing. how can we save it on the server via html?
XSS attacks work by exploiting vulnerabilities in a website code.
To take a trivial example:
Given an input which prompts the user to enter their name and then responds with "Hello, YOUR NAME". If the site just echos back what was input unchanged (i.e. without XSS protection) then someone could type <script> ... </script> and run some JavaScript on the site.
If that's the case then an attacker could write a form on their site but set the action to that page. They could then have a hidden input containing some JavaScript. Then they could submit the form with JS.
Now, if the attacker tricked the victim into visiting the attacker's site, the form would be submitted to the original site by the victim's browser and the JS would run in their browser.
The JS could then do something bad such as copying data out of their cookies and sending it to the attacker. The attacker could then inject that cookie into their browser and use the original site while logged in as the victim.
Now imagine if the original site was your online banking or webmail. All your personal data would be available to the attacker.
That example is of a reflected XSS attack.
The other kind of attack is a stored XSS attack.
Take, for example, a forum. It allows you to post messages. These are saved to a database and displayed to all the visitors.
Now if the data stored in the database was echoed back without XSS protection then the JS would run for everyone visiting the site.
So in short:
how can we save it on the server via html?
You can't use HTML to do this.
You need to send an HTTP request (stored) or cause the victim to do so (stored or reflected) which exploits a flaw in the site's code.
Related
I have watched lots of articles about XSS attack,
but one thing that make me confused is that, how the script injection works actually?
For example, if attackers enter something like <script>alert('Attack!')</script>as the input, why it can stay in the browser permanantly and every user visiting the website can see the alert.
From my understanding, after attackers's input, a POST request will be sent with payload <script>alert('Attack!')</script>. Meanwhile the <header> tag or <script> should only be manipulated on Client Side Source Code/Web Server.
How can it work?
The easiest way to understand the classic XSS mechanism:
If there are no security mesurements, an Attacker inputs the script into a comment section's textbox under an article and then sends it in. This way the script gets stored in the server's database. Every time someone visits that page with the comment section the script will be loaded on the visitor's client side.
To remediate that sanitize input, escape output and use Content-Security-Policy.
There are several types of XSS vulnerabilities.
I'll assume you are talking about a persistent-XSS since that's one type related to your question.
In a persistent-XSS vulnerability, you can POST a request which is then stored in the server-side backend of the application (i.e. a database).
For example, a table in a database storing the comments sections of an article.
When other clients of the application then request that page, the server responds with the related article HTML page including the comments section, where the attacker's payload exists. Then, each client receiving that HTML page, will also receive a comment with a malicious <script>payload</script> script.
From here, the client's browser automatically renders the HTML and executes <script> tags as legitimate JS code received from the server.
Since this code was injected by an attacker, and runs in the clients' browsers, it can be harmful - stealing the client's cookies, session keys, etc. and sending them to a remote server.
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.
I understand the scenario of stealing information with XSS on a GET post as below workflow:
Hacker identifies a page from a web application with vulnerability of being XSS injected through query string parameters.
Hacker composes a url with XSS injected query string appended.
Hacker sends the url to a victim, for example, by email.
Victim receives the mail and clicks on the url (suppose the victim has less knowledge of security).
The opened web page has XSS injected, any further action on the page could result in a security issue.
This is possible because clicking on the url link will open the web page in GET mode. So, I am wondering if the page is XSS vulnerable for POST request, will it be a security issue? I could not figure out a "reasonable" attack workflow.
So, I am wondering if the page is XSS vulnerable for POST request, will it be a security issue?
Of course it would be. Why should the method via which external code is embedded matter at all? That it does happen is the problem, not how.
I could not figure out a "reasonable" attack workflow.
Consider a simple HTML form, that gets pre-populated with the previous user input after a failed server-side validation.
If this pre-popuplating allows XSS (basically meaning, escaping all data before outputting it in an HTML context was neglected) – then I could easily set up a form in my own page, have its action attribute point to your form handling address, and pass any data I like via hidden fields – and have to user send that data to your server via a simple submit button, that is maybe formated to look just like a normal link, and only saying “click here to go to example.com”. The user expects that to just ”normally” open a page like any other link – but in reality it send values that triggers displaying the form with pre-populated fields again.
Et voilà, XSS attack successfully performed.
(All that under the premise that the target site does not have additional security against “foreign” form data in place.)
The attacker could also build a 'data:' URL containing an auto-submitting form:
data:text/html;base64,PGh0bWw+CiAgPGJvZHkgb25sb2FkPSJkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKSI+CiAgICA8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iaHR0cDovL2xvY2FsaG9zdCI+CiAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImVybnN0IiB2YWx1ZT0iPHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4iPgogICAgPC9mb3JtPgo8L2h0bWw+
which is equivalent to navigating to a page containing this markup:
<html>
<body onload="document.forms[0].submit()">
<form method="post" action="...">
<input type="hidden" name="ernst" value="<script>alert('XSS')</script>">
</form>
</html>
Just went through this exact issue while performing a penetration test for a client. When reporting, we usually try to show a proof of concept exploit using a GET request as this is much easier. Remember too that some servers may allow you to change a POST to a GET request. Some servers will also accept POST parameter values in a URL. In my most recent experience, the server would only accept a request as a POST with the input entered into the form fields. The only thing that stopped an XSS attack was the fact that they had Cross Site Request Forgery prevention in place (via ViewState). So, in this case, it is simply a reflection fault. Still not good, but not as bad. You should ALWAYS use both ingress and egress filtering and NEVER trust user-controllable data.
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)?
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.)