- caused by improper sanitization of user input on the page
when the script is permanently stored for example in the database and included on the page
when the script is reflected from the web server and included the page’s source code
(for example, a parameter from the URL is reflected on the website)
happens on the client-side when the payload modifies the DOM in some way
a variant of any of the previous XSS types, when the payload is executed on a different page
(for example XSS in the contact form that is executed in the admin dashboard)
Sanitize user input
- the most important prevention for all kinds of attacks
- be aware of in what context the input is (tag contents, tag attribute, script tag) and escape it accordingly
- for example in PHP use
htmlspecialchars(escape angle brackets, quotes, etc.)
Content Security Policy
- header sent in page’s HTTP response, whitelisting allowed URLs
- in CSP v2 we can use the nonce parameter with a random value that is generated every on every request, and is appended to every script that we want to run
- is a CSP directive to prevent DOM XSS attacks
- by default disables potentially dangerous functions, for example: eval, innerHTML, insertAdjacentHTML, document.write, setting <iframe srcdoc>
Correct Content-Type for JSON requests
- always set an appropriate Content-Type header for the request
- using Content-Type: text/html for a JSON HTTP response will execute the HTML when the request is viewed directly
- github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS Injection
- an attack that executes an action or changes data on a website on behalf of an authenticated user
- works because the browser automatically appends cookies to the request
Logout using img tag
Change user data
<form action="https://example.com/api/changeProfile" method="POST">
<input type="text" name="name" value="New name">
<input type="text" name="email" value="firstname.lastname@example.org">
<input type="text" name="address" value="123 Road">
- generated on the server and sent to the user
- appended in the request body (for example, input type=”hidden”) or in the headers
- the server then verifies the token
- mitigate the risks of CSRF by marking cookies to be sent only from the same site
- supported in most browsers
- doesn’t replace CSRF tokens, only as an additional layer of defense
Verify the Origin
- check if the Origin header in the request matches the correct origin of the website
Verify the Content-Type
- using an HTML form you can only submit GET requests and POST requests
- form enctype cannot be set to
application/json, so if you’re sending a JSON request, verify if the Content-Type is correct
- also only serves as an additional layer of defense
- an attack where untrusted user input is inserted into an SQL query
- can enable the attacker to read, modify or delete data from the database
User submits a login form containing a username and password field. It is then submitted via an HTTP request and the server builds an SQL query by concatenating the query with these fields.
"SELECT * FROM users WHERE username='" + username + "' AND hash = '" + hash + "'"
If the user submits this username:
admin' AND 1=1--, the query becomes:
"SELECT * FROM users WHERE username='admin' AND 1=1--' AND hash = '123'"
which is equivalent to:
"SELECT * FROM users WHERE username='admin'"
Since the rest of the query is commented out using two dashes, the user will be able to log in as ‘admin’.
- when the server doesn’t directly show the output or error of the query
- can be exploited for example by using the
- when a user-submitted value containing an SQL injection payload is first correctly stored in a database, but then when building another query it is incorrectly deemed safe and unsafely used in an SQL query
Using prepared statements instead of directly concatenating the query is the best approach to prevent SQLi.
Set the least possible privilege for the database user to prevent eventual damages by an SQLi.
- vulnerability allowing the attacker to include a file from the server because of incorrectly sanitized/validated input
Not using user-input directly for resolving a file
Instead of directly including the filename passed from the user, have a list of the files and load the file by an assigned unique token/identifier.
- attack on an application that parses XML, allowing, for example, to include files from the filesystem or perform SSRF
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
Correctly configure the XML parser
Disable DTD (Document Type Definition) in the XML parser and set other recommended configurations for the specific parser.
- occurs when the server of a web application is not correctly configured, leading to various security flaws
Default username and password like admin:admin may allow attackers to gain access to the system.
Directory listing is enabled
An attacker will be able to see the list of all files and directories in the current directory.
Using outdated software with known security issues may allow attackers to use those vulnerabilities.
Showing verbose error messages / stack traces / debugging information may help attackers to misuse this information.
Change the credentials
Update the default credentials with a safe password.
Disable directory listing
Disable listing files in directories/buckets by default.
Update the software
Regularly install the latest updates and patches.
Disable verbose error messages
Disable debugging or error messages that might reveal unwanted information.
- combined with an access control vulnerability allows the attacker to access an object by directly providing its identifier
- for example using incremental IDs
Using incremental IDs and not checking if the user has permission to access them.
Enforce access control
Implement user authorization to check if the user has permission to access/modify the resource.
🔖 Also check out: Bookmarklets for developers
– auth bypass
– path traversal
– http response splitting
– null byte injection
As the title implies, this is just a cheatsheet and not a comprehensive guide and it is by no means exhaustive. You can find links below each section for further reading.
If you found a mistake or want to add something, please let me know.