This document provides an introduction to web application security. It outlines common web attacks like cross-site request forgery (CSRF), cross-site scripting (XSS), SQL injection, and others. The document discusses how attackers view web applications and objectives for understanding how to exploit vulnerabilities. It also covers important web concepts like HTTP methods and headers, cookies, DOM, CORS, and the same-origin policy. The document is presented by three security engineers and provides an agenda for two days of training on web application security testing.
1. Introduction to Web Application Security
You can't defend against what you can't see...
Niru Ragupathy (@itsC0rg1)
Jenna Kallaher (@jmkeads)
David Tomaschik (@matir)
3. Who are we?
Niru Ragupathy Jenna Kallaher
Loves anime, comics, gaming and Corgis! Loves reading books, baking,
gaming, and Alaskan Klee Kais!
Security Engineer
Perform code / design reviews, pentests
4. Objectives
● Objectives
○ Understand how attackers (including penetration testers & red teamers) look at web applications
○ By the end, everyone should be able to understand and exploit:
■ Cross-Site Request Forgery
■ Cross-Site Scripting
■ Other web attacks like SQLi, XXE, etc.
○ Have fun
5. Reminder!
● Security testing is sometimes considered the "dark arts" of security.
● It can be used for good and evil
● Please don't be evil
● Only test sites you own or have express written permission to test!
○ Google's Vulnerability Reward Program constitutes permission to test Google sites, under
conditions.
6. The Value of a Vulnerability
● Google VRP pays $100 - $30K, depending on scope and type of vulnerability
○ In 2017 alone, we paid over $2.9m in VRP rewards
○ Over $12M paid since beginning of program
○ https://www.google.com/about/appsecurity/reward-program/
● Also pay for patches to fix vulnerabilities in Open Source
○ Not just Google products: a variety of Open Source is covered
○ https://www.google.com/about/appsecurity/patch-rewards/
7. Outline: Day 1
● CIA of Security
● Web Application - Then and Now
● Introduction to HTTP
● Introduction to Cookies, DOM
● Same Origin Policy
● HTTP Methods and Headers
● Cross-Origin Resource Sharing (CORS)
● CSRF
● Injection
○ SQL
○ Command
● Broken Session Management
● Insecure Direct Object Reference
● Missing Function Level Access Control
● Logic Errors
8. Outline: Day 2
● XSS
● Content Security Policy (CSP)
○ Reading Policies
○ Bypassing CSP
● Vulnerability Chaining
● Same Site Request Forgery (SSRF)
● XML External Entity Injection (XXE)
● Final Exercise
9. CIA of Security
● Confidentiality
○ Prevent unauthorized access to resources/data
● Integrity
○ Prevent unauthorized modification to resources/data
○ Prevent unauthorized execution
● Availability
○ Ensure the system is available (to authorized users)
○ Mostly the realm of DoS of various forms, won't be covered much
11. An Introduction to HTTP
● Application level textual protocol used for communication in web
● A request is sent from the client to the server and the server replies with a
response
● The web page is returned as HTML in the response and rendered by the client
● We will explore methods and headers in a later section
GET /search?tbm=isch&q=klee+kai+puppy HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0
HTTP/2 200
Content-Type: text/html; charset=UTF-8
Date: Fri, 03 Aug 2018 00:01:19 GMT
Content-Length: 298628
<html>...</html>
12. Status Codes
Informational
1XX
Successful
2XX
Redirection
3XX
Server Error
5XX
Client Error
4XX
100 Continue 200 OK 301 Moved Permanently
302 Found
307 Temporary Redirect
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
500 Internal Server
Error
502 Bad Gateway
503 Service Unavailable
HTTP/2 200
Content-Type: text/html; charset=UTF-8
Date: Fri, 03 Aug 2018 00:01:19 GMT
Content-Length: 298628
<html>...</html>
16. Cookies
● HTTP is a stateless protocol, cookies are data that was added in to provide
support for stateful actions
● Without it the web experience today would not be personalized
● They are sent from the server to the browser, which stores it, then sends the
cookie with future requests to the server
● Cookies can be used to authenticate a user to the server
17. Cookie attributes and flags
From Server
Set-Cookie: <name>=<value>; Expires=<Timestamp>; Domain=<current domain or subdomain>; Path=</..>;
<Flags..>
#1 - Set-Cookie: corgi=woof; Expires=Wed, 8 Sept 2018 09:30:00 GMT; HttpOnly
#2 - Set-Cookie: id=9d34e8e12; Domain=corgi.com; Path=/treats; Secure; HttpOnly; SameSite=Strict
● #1, #2 have HttpOnly cannot be accessed using document.cookie
● #2 has Secure flag and can only be sent over HTTPS channels
● #2 does not have an expiration set, and will expire when the browser is closed
● #2 uses Same site attribute, can be Lax or Strict, when set to Strict cookies will not be sent for cross
origin request (we will explore this later)
● Domain - Cookie has a different definition of origin, it can use the current domain or the parent domain
(non-public suffix)
● Path - Finer granularity of restriction, #2 is restricted to pages in the folder treats
18. Document Object Model
● The document aka webpage is represented as a tree with nodes and objects, making it
possible to parse or alter
● This representation is called DOM (Document Object Model)
<html>
<head>
<title> Best Doggie </title>
<h1> Corgi </h1>
</head>
<body>
<p id="sound">Woof</p>
</body>
</html>
html
head body
h1 title p
document.getElementById("sound") → <p id="sound">Woof</p>
document.getElementById("sound").innerHTML → Woof
19. JavaScript is Powerful
● Code Executing on the Client, provided by the Server
● Capable of Anything the User Can Do
○ Submit Forms? ✔
○ Click Links? ✔
○ Read the Page? ✔
● Can also do things the user can't (easily)
○ Modify the Page? ✔
○ Change the destination of Forms? ✔
○ Make requests in the background? ✔
21. Getting any Security At All
● Same Origin Policy
○ Pages can only "interact" with other resources having the same "origin"
○ Interact?
■ Read contents of files/pages
■ Manipulate the DOM
■ Send XMLHttpRequest
○ Origin is a combination
■ Fully-qualified Domain
■ Port
■ Protocol
● Cookies have their own rules
● HTML5 added new rules too
24. GET
● Used to fetch information, not recommended for state changing actions
● It can be cached and the parameters will be logged in browser history,
intermediate proxies
● Not recommended for sensitive data, since it is easily leaked through referrer
GET /search?tbm=isch&q=klee+kai+puppy HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
….
25. POST
POST /forum HTTP/1.1
Host: kleekais.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
….
title=hello&body=world
● Used for state changing actions
● Not cached or logged in the browser history
● Safe for handling sensitive data
26. Other methods
● HEAD - used to check the existence of a resource without fetching it
● OPTIONS - used to fetch the allowed request methods on the server
● PUT - creates or replaces a resource in the specified location
● DELETE - deletes a specified resource
● TRACE, CONNECT
30. Host Header
● From RFC7230: "The Host header field in a request provides the host and port information from the target
URI, enabling the origin server to distinguish among resources while servicing requests for multiple host
names on a single IP address."
● What happens if we provide no host header? An invalid host header?
○ Generally, an invalid host header will be routed to the first virtual host in the list
○ It's unsafe to trust the Host header because it is user-controlled
● Examples:
○ Password reset emails
○ $10k Host Header: interesting reading material
GET /search?tbm=isch&q=klee+kai+puppy HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
….
31. Origin
● The Origin header is added by the browser and describes where the request
originated
● The browser adds the header to cross-origin requests
● Cannot be altered
GET / HTTP/2
Host: bar.com
Origin: https://foo.com
[...]
32. Referer
● The Referer header contains the previous page you were on
● It's great for tracking how users found out about your website
foo.com/visit bar.com
<html>
<p>
<a href="https://bar.com">
Visit bar.com!
</a>
</p>
</html>
GET / HTTP/2
Host: bar.com
Referer: foo.com/visit
[...]
<html>
<b> Raising the bar everyday! </b>
<i> Embrace the puns! </i>
</html>
33. Referrer-Policy
● The Referer header contains the URI of the page that requested the resource.
○ The typo is intentional! Oddly enough the Referer header is misspelled, but Referrer-Policy is
spelled correctly
● There are security and privacy implications to the Referer header. The Referrer-Policy
header was created to control what is sent and when.
○ Policy options include: no-referrer, no-referrer-when-downgrade, origin,
origin-when-cross-origin, same-origin, strict-origin,
strict-origin-when-cross-origin, unsafe-url
● There are other ways to control the Referer header outside of the Referrer-Policy header.
○ <meta name="referrer" content="origin">
○ <a href="http://example.com" referrerpolicy="origin">
○ <a href="http://example.com" rel="noreferrer">
34. GET /storm HTTP/2
Host: kleekais.com
Referer: corgi.com/ein
HTTP/2 200
Date: Sun, 19 Aug 2018 17:46:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 2157
Referrer-Policy: origin-when-cross-origin
Referrer Policy in action!
GET /dogbones HTTP/2
Host: treats.com
Referer: kleekais.com
corgi.com/ein kleekais.com/storm treats.com/dogbones
35. Clickjacking
● Clickjacking happens when the user is tricked into
clicking on a element, usually by framing a victim page
● Using X-Frame-Options specifies whether or not a page
can be framed with <iframe> or similar tags
○ SAMEORIGIN - allow framing by the same origin
○ DENY - the page can never be framed
○ ALLOW-FROM - only specific origins can frame the
page
evilcorgis.com
worstdogs.com/vote
klee kais
corgis
Click Here to
downvote corgis!
visibility: hidden;
36. Caution!!
Behavior varies by browser
● Chrome and Safari do not support ALLOW-FROM and instead support a similar
feature in CSP
● SAMEORIGIN has different behavior in Safari. Only the top level origin is
checked - intermediate frames are ignored. Firefox was the same as Safari until
January 2018
kleekais.com/news
corgis.com/article
kleekais.com/settings
37. Content Sniffing
● Browsers can perform content sniffing to guess the right MIME type when Content-Type isn't set or may
have been set incorrectly
● When user uploaded or generated content is allowed, this becomes dangerous
● HTTP headers can be used to reduce the risk of content sniffing
● Content-Type
○ Indicates the type of the content. Ex. text/html, image/png
● X-Content-Type-Options: nosniff
○ Stick to the MIME types specified in the Content-Type header
● Content-Disposition: attachment; filename="file.txt"
○ Treat the content as an attachment and download it as a file
{"name":"%PDF-Q xref 0 0 trailer<</Root<</Pages<<>>/OpenAction<</S/JavaScript/JS(app.alert(URL))>>>>>>
startxref 7%%EOF "}
39. Cross-Origin Resource Sharing (CORS)
● Remember the Same Origin Policy?
● CORS provides a way to allow cross-origin requests
GET /profile
kleekais.com
data.kleekais.com
GET /user/dax
40. Cross-Origin Resource Sharing (CORS)
● CORS is done by specifying HTTP headers
● In the simplest case, it's just two HTTP headers:
○ origin: https://example.com
○ access-control-allow-origin: *
● The browser enforces the rules in these HTTP headers in order to allow some
cross-domain requests to succeed
Preflight request (optional)
Preflight response (optional)
Resource request
Resource response
41. CORS Example Preflight
OPTIONS /user/dax HTTP/2
Host: data.kleekais.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: origin, x-custom-header
Origin: https://kleekais.com
HTTP/2 200
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: origin, x-custom-header
Access-Control-Max-Age: 600
42. CORS Example Request
GET /user/data HTTP/2
Host: data.kleekais.com
X-Custom-Header: test
Origin: https://kleekais.com
[...]
HTTP/2 200
Access-Control-Allow-Origin: *
Content-Length: 1337
Content-Type: text/plain
[...]
43. CORS Access Control
● Allowing all cross-origin requests from any origin is usually not a good idea
unless it's an intentional feature
● CORS provides ways to control the origins, HTTP methods, and other attributes
of requests that are allowed to access a resource
○ access-control-allow-origin: the resource can be accessed by the specified origin(s)
■ access-control-allow-origin: *
■ access-control-allow-origin: https://foo.com, https://foo.example.com
○ access-control-allow-methods: allowed HTTP methods (GET/POST/…)
○ access-control-allow-headers: allowed HTTP headers
○ access-control-expose-headers: whitelist headers that browsers can access
○ access-control-allow-credentials: allow/deny requests with credentials
○ access-control-max-age: how long the response can be cached
46. Cross-Site Request Forgery
● Call it XSRF. Or CSRF. (Sea-Surf)
● User issues request without intent
○ And the user is logged in
○ And it is accepted by the server
○ And it causes some undesirable effect
■ Logout
■ Delete Account
■ Change Password
■ "State Changing Request"
<iframe src='https://someothersite.com/logout.php'></iframe>
47. CSRF Example
The server has no way to distinguish between user initiated requests and machine initiated requests
1) User visits evil.com,
<Cat picture go here>
<img
src="https://www.mehbank.com/trasn
fer?from=you&to=me"/>
2) User is logged into mehbank,
browser helpfully sends over the
cookies with the transfer
request
3) Server verifies the cookie and
processes the transfer
48. CSRF: What to Look For
● Request must be
○ Predictable
■ No hard-to-predict values (i.e., a large random session identifier)
○ Authenticated
■ Anonymous CSRF is generally uninteresting
○ State-Changing
■ If it doesn't change anything, getting it run doesn't serve any purpose
○ Forgeable
■ Certain headers can't be sent across origins (X-Requested-With, for example)
50. CSRF Mitigation
- Tokens [Recommended approach]
- Are per-user
- Should be unpredictable and have a limited lifetime
- Can be set in hidden form fields, HTTP headers
- Header checks - Origin / Host / Referrer
- Should block if these headers are not present
- Plugins can alter certain HTTP headers
- Double submit cookie
- Used when there is difficulty associating the token to a session
- A random value is assigned to the hidden form field and a cookie, compared at server side on
submission
- SameSite Cookies
- Form submit from attacker site, will not allow the browser to send the cookies in the request
52. Injection
Injection vulnerabilities occur when an attacker is
able to make data interpreted as code/commands
● SQL
○ SELECT * FROM users WHERE
username='foo';
● Commands
○ ping google.com
53. What could possibly go wrong?
query = "SELECT * FROM users WHERE id=" + request.params["id"]
54. What could possibly go wrong?
query = "SELECT * FROM users WHERE id=" + request.params["id"]
/profile.php?id=1;+DROP+TABLE+users
55. Little Bobby Table's Profile!
SELECT * FROM users WHERE id=1;DROP TABLE users
http://xkcd.com/327
56. SQL Injection
● User provided input is used to create a SQL query without sanitization
○ String concatenation
○ String formatting
● Using parameterized queries provides automatic escaping
● So many web programming "tutorials" show this anti-pattern!
● Can close quotes, insert strings where integers expected, etc.
57. Code Example
<? php
$uname = $_POST["username"];
$pwd = $_POST["password"];
$result = mysql_query("SELECT * from users where username ='$uname'
and password = '$pwd'");
// Code to log user in goes here
?>
58. Code Example
<? php
$uname = $_POST["username"];
$pwd = $_POST["password"];
$result = mysql_query("SELECT * from users where username ='$uname'
and password = '$pwd'");
// Code to log user in goes here
?>
"SELECT * from users where username ='admin' -- and password =
'anything'
59. Command Injection
Similar to SQL injection, but in a shell command
groups = os.system("groups " + request.params["user"])
60. Command Injection
Similar to SQL injection, but in a shell command
groups = os.system("groups " + request.params["user"])
/groupinfo?user=myuser;cat+/etc/passwd
61. Command Injection
● Commonly found:
○ Near output formatted from other tools
○ For things hard to do in native programming languages (system administration, ping, etc.)
○ Embedded devices (routers, etc.)
64. Broken Session Management
● Applications often maintain a user "session"
● Frequently done by storing data server-side and associating it with a "session
identifier"
● If session identifiers are predictable, attackers can take over user sessions
● If an attacker can force a user to use a session they provide, might also leak
information to attacker
○ This is called "session fixation"
65. Generating Session Tokens
● Sequential number
○ Obviously predictable, in sequence
● Random number
○ Maybe, random space needs to be large in comparison to # of users, 64-bit is a good choice
● Username as token
○ Obviously predictable
● MD5(username)
○ Just as predictable as above!
● Encrypted username
○ Not predictable, but possible to manipulate
● Signed username
○ HMAC is hard to forge (include expiration time)
66. Client-Side Sessions
So if identifying sessions is hard, or we need to sync across a lot of servers, why
don't we just store the session in the cookie?
67. Client-Side Sessions
● All session data will be visible to the user
○ May or may not be a problem, depending on use case
● All session data can be modified by the user
○ Almost certainly a problem
○ session={'username': 'john'}
○ session={'username': 'admin'}
● Client-side sessions need to be authenticated to avoid tampering
○ HMAC(secret_key_on_server, session_data)
69. Insecure Direct Object Reference
Is there anything concerning about a URL like this?
/showaccount?id=1336
70. Insecure Direct Object Reference
Maybe...
/showaccount?id=1336
/showaccount?id=1337
/showaccount?id=1335
/showaccount?id=1
71. Insecure Direct Object Reference
When using predictable identifiers, you need to validate access to the particular
instance requested.
Being logged in isn't enough.
72. Is this access control?
{% if admin %}
<a href='...'></a>
{% endif %}
73. NO
● That's just UI
● Need to check access at time of change or data load
● What works?
○ Middleware
○ Decorators
○ Object-level access control
74. Missing function level access control
● Authorization should be checked at the time of taking action
● "Hidden" functionality is a frequent source of vulnerabilities
● Many tools exist to find hidden URLs
○ Burp Suite (https://portswigger.net/burp/)
○ DirBuster (https://www.owasp.org/index.php/Category:OWASP_DirBuster_Project)
○ Gobuster (https://github.com/Matir/gobuster)
(Please don't run these tools on meh Bank right now for bandwidth/capacity reasons.)
75. Logic Errors: Check Assumptions!
● Developers may assume that:
○ Input is an integer
○ Input is a positive number
○ Strings don't contain >, <, ", or ' (this is how we get injection/XSS)
○ The interface will only be exposed to "internal" networks
○ Only authorized users will know the URL
80. Cross-Site Scripting (XSS)
● Not usually referred to as "injection", but similar concept
● Code is injected where data is expected…
○ Leading browser to execute the code
○ Remember, the only difference between code and data in HTML are tags
● Browser runs the javascript payload injected by the attacker
81. XSS Flavors
Reflected
● Data from the current request is reflected to the user unescaped
● Commonly seen in search boxes, etc.
Stored
● Data from a previous request is stored in the datastore and fetched back unescaped
● Commonly seen in comment fields, profiles, etc.
DOM-based XSS
● Only in the client, server is never involved
● Cropping up everywhere with more code on the client
82. Where to find DOM XSS
const user = document.location.href.substring(document.location.href.indexOf("u=")+2);
let profile = document.createElement('div');
profile.innerHTML = '<img src="' + decodeURI(user) + '.png">';
document.body.appendChild(profile);
document.write("<p> Hello " + decodeURI(user) + "!</p>");
83. Where to find DOM XSS
const user = document.location.href.substring(document.location.href.indexOf("u=")+2);
let profile = document.createElement('div');
profile.innerHTML = '<img src="' + decodeURI(user) + '.png">';
document.body.appendChild(profile);
document.write("<p> Hello " + decodeURI(user) + "!</p>");
/profile?u=" onerror=alert(document.domain)">
/profile?u=<script>alert(document.domain)</script>
84. Where to find XSS
● Everywhere! XSS has been reported as the most pervasive vulnerability class
● If you see user input from a form field or the URL displayed on the page: check
for reflected XSS
● If you see user input from another source (user profile, etc.) displayed on the
page: check for stored XSS
● If you see input taken, processed, and displayed without a page load: check for
DOM-based XSS. This may often be in location hash (the part of the URL after #)
85. Filter Evasion - A game of cat and mouse
Filter Bypass
Lowercase <script>
Lowercase and uppercase <script>
Removes case insensitive <script>
script (Including javascript)
<SCRIPT>
<ScRiPt>
<scr<script>ipt> or <SCR[0x00]IPT>
<img src='' onerror='alert(1)'>
87. XSS Mitigations
● Input validation, output encoding
● Templating systems
○ Auto-escaping
■ Replace characters that affect control flow with entities (> becomes >, etc.)
○ Contextually Aware
■ Knows if you're in a <script> tag, or in the href property of <a>, etc., to escape
appropriately
■ Soy, AngularJS
○ Not-contextually Aware
■ More dangerous
■ Jinja2, Django, etc
88. XSS Mitigations
● X-XSS-Protection helps detect and block reflected XSS,
○ X-XSS-Protection: 0
○ X-XSS-Protection: 1
○ Can additionally have mode=block and report=<report-uri>
● Avoid data sinks like document.write, innerhtml
● Leverage CSP
90. CSP
CSP is a defense-in-depth mechanism that prevents malicious script injection /
execution. It is not a replacement for careful input validation and output encoding.
● Can control where resources are being sourced from
● Prevent inline script, code execution through eval
● Can be run in one of two modes - enforcing, report only
● Directives include: Script-src, img-src, style-src, object-src, default-src, etc.
Huge shout out to our colleagues Lukas Weichselbaum and Michele Spagnuolo, who
graciously lent us their CSP slides :) *
*P.S they have been Corgi-fied
91. Content-Security-Policy:
default-src 'self';
script-src 'self' doggos.com;
report-uri /csp_violation_logger;
corgi.example.com corgi.example.com
doggos.com
attacker.com
<img src="woof.png">
">'><script>alert(42)
</script>
corgi.example.com/csp_violations_logger
CSP
blocks
inline script
not allowed
<script
src="//doggos.com/paw.js">
">'><script
src="//attacker.com">
CSP
blocks
source not
whitelisted
CSP
allows
CSP
allows
Example by Lukas Weichselbaum , Michele Spagnuolo
CSP at work - Example 1
92. CSP - Getting it right
● Many sites do not configure CSP correctly and are trivially bypassable
● There are tools like CSP Evaluator that can help scan and identify deficiencies in
the CSP policy
● Open source project (https://github.com/google/csp-evaluator) hosted at
https://csp-evaluator.withgoogle.com/
● Per Lukas and Michele's study in "Largest Empirical Study on Effectiveness of
CSPs in the Web" 94% of the policies evaluated from a sample set ~22000 were
trivially bypassable
94. JSONP
● Before CORS / XHR, was the method for cross domain data sharing
● Declare a javascript function that will parse the data
● In the site that will share the data, data is passed using a callback
Corgi.com
woof_callback({
"Name" : "Gatsby",
"Age" : "4",
"Score" : "11"
});
WeRateCorgi.com
function woof_callback(data){
console.log(data);
}
……
<script
src="http://www.corgi.com/get-corg
i?q=woof_callback"><script>
96. CSP Nonces
● Whitelists can be bypassed using JSONP endpoints, redirects. They are also
hard to maintain
● Instead all <script> tags with the correct nonce attribute will get executed
● The server is responsible for generating a unique nonce each time it transmits
the policy to the client, this needs to be inserted into the header and the script
tags
● If scripts are not in the whitelist or have the correct nonce they will be rejected
● Similarly to nonces you can also use hashes of the script
98. Taking it a step further - Strict-dynamic
● In CSP 3, the concept strict-dynamic was introduced
● It allows scripts loaded with nonces / hashes to propagate trust to scripts that
they load
● Caution! Using strict-dynamic will cause the browser to ignore whitelists and
directives like unsafe-inline. This helps maintain backwards compatibility with
CSP 2
99. Strict-Dynamic in action
1) The CSP on the main site is -
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-R4nd0m'
2) Trusted script, Nonce matches -
<script nonce="R4nd0m" src="https://corgi.com/loader.js">
3) Loader.js can perform,
var script = document.createElement('script');
script.src = "woof.js";
document.body.appendChild(script);
4) Woof.js will be trusted
100. CSP Exercise 1
Can you bypass the CSP on this website?
Content-Security-Policy:
default-src 'self' ajax.googleapis.com; style-src 'unsafe-inline' *; report-uri
/csp_report
102. CSP Exercise 2
Can you bypass the CSP on this website?
Content-Security-Policy:
script-src https://storage.googleapis.com/blackhoodie-js/allowed.js 'self'; default-src
'self'; style-src 'unsafe-inline' *; report-uri /csp_report
105. A Useless Vulnerability
● Assume a to-do manager allows only the user who created entries to see them
● What happens if there’s an XSS in this app?
106. A Useless Vulnerability
● Assume a to-do manager allows only the user who created entries to see them
● What happens if there’s an XSS in this app?
○ We call this a "self-XSS"
○ Not very useful: not going to another privilege level
107. But wait, there's more!
● Assume a to-do manager allows only the user who created entries to see them
● What happens if there’s an XSS in this app?
○ We call this a "self-XSS"
○ Not very useful: not going to another privilege level
● The app also has an CSRF allowing the creation of arbitrary to-do entries.
108. Vulnerability Chaining
● Assume a to-do manager allows only the user who created entries to see them
● If there is an XSS in the app, it would only affect yourself
○ We call this a "self-XSS"
○ Not very useful: not going to another privilege level
● The app also has an CSRF allowing the creation of arbitrary to-do entries.
● Chaining the vulnerabilities (CSRF to deliver the XSS payload) gives an attacker
full control over the user's account
110. Server Side Request Forgery (SSRF)
● SSRF happens when the server makes requests on behalf of the attacker
● SSRF vulnerabilities require the server to be able to perform actions that the user
couldn't do themselves
169.254.169.254/metadata/keys
translate.kleekai.com
GET /translate?q=169.254.169.254/metadata/keys
111. Server Side Request Forgery (SSRF)
● What to look for?
○ Any server-side requests with attacker-controlled input
○ It's best to find places where the server returns the response or error codes to the user, but
sometimes all you need is the ability to send a state-changing request
● When is it a vulnerability?
○ Fetching resources from a public resource isn't useful
○ Port scanning internal resources can provide more information
○ Fingerprinting is also useful for finding bugs
○ However, fetching a configuration file that contains private keys or passwords
112. SSRF Examples
● file://
● Database servers
● Metadata Servers provided by cloud providers
● Into the Borg - SSRF inside Google Production Network
114. XML
XML is an Extensible Markup Language, it is used to describe data. Readable for
humans, easy to parse for machines. E.g,
<dog>
<name> Gatsby </name>
<breed> corgi </breed>
<age> 6 </age>
</dog>
115. DTD
A DTD is a Document Type Definition, it defines - the structure, the legal elements and attributes
of an XML document.
<!DOCTYPE dog
[
<!ELEMENT dog (name,breed,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT breed (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
#PCDATA - Parse-able text data
116. Entities
Used to reference data using an abbreviation, this can be internal or external.
DTD Example:
<!ENTITY corgi "Gatsby">
<!ENTITY cuteness "Over 9000!!">
XML example:
<author>&corgi;&cuteness;</author>
117. XXE
● Occurs when a misconfigured XML parser processes attacker provided XML input that contains
references to external entities or DTDs
● This can be used to leak information from the file system or network endpoints, perform SSRF, scan the
internal network and so on
● Can be mitigated by adopting Input validation and turning off external entity and DTD parsing
● Gaining read access on Google's production server
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd">
]>
<dog>
<name>John</name>
<breed>&ent;</breed>
</dog>
118. Further Reading/Resources
● Web Application Hacker's Handbook
○ by Dafydd Stuttard, Marcus Pinto
● The Tangled Web
○ by Michal Zalewski
● OWASP Top 10
○ https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
● Vulnerable Applications to Test
○ https://www.vulnhub.com/
○ https://github.com/Matir/pwnableweb
○ https://xss-game.appspot.com/
(These are not an endorsement by Google, just things we've found useful.)
119. Shout-outs
● David Tomaschik (@matir), co-creator of the course
● Matthew Bryant (@iammandatory), for reviewing and giving extensive feedback
● Lukas Weichselbaum(@we1x), Michele Spagnuolo(@mikispag) for sharing their
CSP slides and walking us through CSP bypasses and correct usage