XSS = Cross-site scripting
- javascript injection into a website
- caused by improper sanitization of user input on the page
Types
Stored (persistent)
when the script is permanently stored for example in the database and included on the page
Reflected (non-persistent)
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)
DOM-based
happens on the client-side when the payload modifies the DOM in some way
(for example, using eval(), innerHTML, setting javascript to <a href=>)
Blind
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)
Prevention
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
Trusted Types
- 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
(application/json; charset=utf-8) - using Content-Type: text/html for a JSON HTTP response will execute the HTML when the request is viewed directly
Further reading
- portswigger.net/web-security/cross-site-scripting
- owasp.org/www-community/attacks/xss
- cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- wikipedia.org/wiki/Cross-site_scripting
- github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS Injection
CSRF = Cross-site request forgery
- 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
Examples
Logout using img tag
<img src="//example.com/logout">
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="new@example.com">
<input type="text" name="address" value="123 Road">
</form>
<script>
document.forms[0].submit();
</script>
Prevention
CSRF tokens
- 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
SameSite cookies
- 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
Further reading
SQL injection
- 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
Example
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’.
Types
Blind SQLi
- when the server doesn’t directly show the output or error of the query
- can be exploited for example by using the
SLEEP
function
Second-order SQLi
- 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
Prevention
Prepared statements
Using prepared statements instead of directly concatenating the query is the best approach to prevent SQLi.
Least privilege
Set the least possible privilege for the database user to prevent eventual damages by an SQLi.
Further reading
LFI = Local File Inclusion
- vulnerability allowing the attacker to include a file from the server because of incorrectly sanitized/validated input
Example
<?php
include($_GET['url']);
https://example.com/?url=/etc/passwd
Prevention
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.
Further reading
XXE = XML External Entity
- attack on an application that parses XML, allowing, for example, to include files from the filesystem or perform SSRF
Example
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
Prevention
Correctly configure the XML parser
Disable DTD (Document Type Definition) in the XML parser and set other recommended configurations for the specific parser.
Further reading
Security Misconfiguration
- occurs when the server of a web application is not correctly configured, leading to various security flaws
Examples
Default credentials
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.
Outdated software
Using outdated software with known security issues may allow attackers to use those vulnerabilities.
Debugging enabled
Showing verbose error messages / stack traces / debugging information may help attackers to misuse this information.
Prevention
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.
Further reading
IDOR = Insecure Direct Object Reference
- combined with an access control vulnerability allows the attacker to access an object by directly providing its identifier
- for example using incremental IDs
Examples
Incremental IDs
Using incremental IDs and not checking if the user has permission to access them.
GET /api/users/12345
PATCH /api/users/12345
{
"email": "evil@example.com"
}
Prevention
Enforce access control
Implement user authorization to check if the user has permission to access/modify the resource.
Further reading
🔖 Also check out: Bookmarklets for developers
To add:
– auth bypass
– path traversal
– http response splitting
– null byte injection
– clickjacking
– SSRF
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.