Basic Web Application Security
User Input
Kick Your Arse
Three Ways (All Awesome)
Validation
Passive (No touchy-touchy)
This is a Number. 2
This is not a Number. a
This is really not a Number. alert(‘loldongs’)
Filtering
Destructive (One-Way Street)
Only letting the good stuff in.
or
Keeping out the bad stuff.
What’s the diff? (Bro.)
Both can be error- prone...
White-Listing Usability Problems What happens when you screw it up? Black-Listing Security Problems (Always a trade-off.)
Escaping
Transport Point A Point B
Data will be the same on both sides.
Different Media, Different Escaping
HTML Huh. <b>Huh.</b> Huh
SQL Sam O’Brien INSERT INTO mah_peeps (name) VALUES (‘Sam O\’Brien‘); 1, Sam O’Brien, :30:00
XSS (Cross-Site Scripting)
(XTREME Site Scripting) SS
Sticking Scripts Where They Don’t Belong. You there, down the back. Stop sniggering.
alert(‘HACKED BY LOLDONGS’) Amateurs!
alert(document.cookie) Hmm.
document.write(‘ ’); Oh shit.
Why is this uncool? (Yeah! Why?)
document.write(‘ ’); Ooooh shit.
document.write(‘ ’); Oooooooooooh shit.
document.write(‘ ’); Oooooooooooooooooh shit.
Why is this really uncool? (Because shut up.)
HTTP Hyper-Text Thingy I-forgot-again
Stateless
No Idea Who You Are.
It can guess. (Badly.) IP Address Browser User-Agent
Sends a cookie with each request. (A basket of goodies that the browser sends faithfully every request.)
The Server puts a unique ID in the basket. PHPSESSID=123your456mum78 9 __utma= is_a_furry=1
Browser sends the ID every request. PHPSESSID=123your456mum78 9
document.write(‘ ’); Look again.
THEY HAVE YOUR COOKIE. Ooooooooooooooooooooooo-
Preventing Shenanigans
HTML Validation Really Hard.
HTML Filtering Still Really Hard. Use a library, eg. HTML Purifier.
HTML Escaping Dead Easy. Most languages have stuff to handle this, eg. htmlentities(), cgi.escape(), CGI.escape()
How hard is filtering? (It’s just, right?)
THIS HARD. alert('a') ”> <IMG SRC=javascr ipt:aler t('XSS')> <IMG SRC=javascr ipt:aler t('XSS')> (Well, then.) alert('a') alert("a");// RIPT>alert('a'); RIPT> <img src=”javascript:alert('a')”
THIS HARD. <iframe src= < BODY{-moz- binding:url(" (Well, then.) žscriptualert(EXSSE)ž/scriptu (US-ASCII encoding evasion) <META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64, PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
THIS HARD. <DIV STYLE="background- image:\0075\0072\006C\0028'\006a \0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061 \006c\0065\0072\0074\ \ \0053\0027\0029' exp/* alert('a'); (Well, then.).x{background- image:url("javascript:alert('a')");} <EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzd....j wvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"> ]]>
One more thing about XSS. (Groan.)
Remember alert() ? (Yes, I do. Shut up.)
alert() can be ANY JAVASCRIPT. (Yes, and...?)
Do you have any forms on your page? (Yes.)
Do you have any javascript functions your site uses to do anything useful? (... Yes.)
Do your site make any AJAX calls to do anything useful? (... Oh.)
That injected code can trigger forms, run javascript functions, or make AJAX calls. (... Oooooh.)
Send someone to a link that looks like: doStuff(); (... Oooooooooh.)
Or store something that will output this on someone’s profile page: doStuff(); (... Oooooooooooooooh.)
... And you’re hosed. (Shit.)
The Human Element Touchy-Feely Commie Bullshit.
We are very fallible.
We will forget things.
When time gets short, we take the easy path.
Design systems so that they naturally encourage security.
SQL Insert(“INSERT INTO posts VALUES (‘”.sql_safe($title).”’, ‘“.sql_safe($content).”’, ‘”.sql_safe($author).”’)”);
SQL or
SQL insert(“INSERT INTO posts VALUES (:title, :content, :author)”, $title, $content, $author);
HTML - Written by
HTML or
HTML - Written by
Questions?
Now get out.