Mais conteúdo relacionado Semelhante a Dip Your Toes in the Sea of Security (20) Mais de James Titcumb (18) Dip Your Toes in the Sea of Security4. @asgrim
Some simple code...
<?php
$a = (int)filter_var($_GET['a'],
FILTER_SANITIZE_NUMBER_INT);
$b = (int)filter_var($_GET['b'],
FILTER_SANITIZE_NUMBER_INT);
$result = $a + $b;
printf('The answer is %d', $result);
19. @asgrim
SQL Injection (#1)
<?php
// user_id=1; DROP TABLE users; --
$user_id = $_GET['user_id'];
$sql = "
SELECT * FROM users
WHERE user_id = {$user_id}";
$db->execute($sql);
✘
25. @asgrim
Cross-Site Scripting / XSS (#3)
<?php
$unfilteredInput = '<script type="text/javascript">...</script>';
// Unescaped - JS will run :'(
echo $unfilteredInput;
// Escaped - JS will not run :)
echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
27. @asgrim
Cross-Site Request Forgery / CSRF (#8)
<?php
if (!$isPost) {
$csrfToken = base64_encode(random_bytes(32)));
$_SESSION['csrf_token'] = $csrfToken;
// ... output the form ...
echo '<input type="hidden" name="csrf_token" value="'.$csrfToken.'" />';
} else if ($isPost) {
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Token invalid...");
}
// ... handle the form ...
}
28. @asgrim
<?php
if (!$isPost) {
$csrfToken = base64_encode(random_bytes(32)));
$_SESSION['csrf_token'] = $csrfToken;
// ... output the form ...
echo '<input type="hidden" name="csrf_token" value="'.$csrfToken.'" />';
} else if ($isPost) {
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Token invalid...");
}
// ... handle the form ...
}
Cross-Site Request Forgery / CSRF (#8)
29. @asgrim
Cross-Site Request Forgery / CSRF (#8)
<?php
if (!$isPost) {
$csrfToken = base64_encode(random_bytes(32)));
$_SESSION['csrf_token'] = $csrfToken;
// ... output the form ...
echo '<input type="hidden" name="csrf_token" value="'.$csrfToken.'" />';
} else if ($isPost) {
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Token invalid...");
}
// ... handle the form ...
}
30. @asgrim
Timing attacks
// From zend_is_identical:
return (Z_STR_P(op1) == Z_STR_P(op2) ||
(Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));
31. @asgrim
Timing attacks
Actual string: “foobar”
● a (0.00001)
● aa (0.00001)
● aaa (0.00001)
● aaaa (0.00001)
● aaaaa (0.00001)
● aaaaaa (0.00002) ← success!
● aaaaaaa (0.00001)
● aaaaaaaa (0.00001)
● aaaaaaaaa (0.00001)
32. @asgrim
Timing attacks
1 int memcmp(const void* s1, const void* s2,size_t n)
2 {
3 const unsigned char *p1 = s1, *p2 = s2;
4 while(n--)
5 if( *p1 != *p2 )
6 return *p1 - *p2;
7 else
8 p1++,p2++;
9 return 0;
10 }
http://clc-wiki.net/wiki/C_standard_library:string.h:memcmp#Implementation
33. @asgrim
Timing attacks
Actual string: “foobar”
● “aaaaaa” (0.00001)
● “baaaaa” (0.00001)
● …
● “faaaaa” (0.00002) ← success!
● “fbaaaa” (0.00002)
● “fcaaaa” (0.00002)
● …
● “foaaaa” (0.00003) ← success!
76. @asgrim
iptables
#!/bin/bash
IPT="/sbin/iptables"
$IPT --flush
$IPT --delete-chain
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
# Loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Inbound traffic
$IPT -A INPUT -p tcp --dport ssh -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT
# Outbound traffic
$IPT -A OUTPUT -p tcp --dport 80 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 443 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
84. @asgrim
Resources
● http://securingphp.com/
● https://www.owasp.org/
● http://blog.ircmaxell.com/
● https://github.com/paragonie/random_compat
● https://github.com/ircmaxell/password_compat
● https://paragonie.com/blog
● https://websec.io/resources.php
● https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04
● https://www.kali.org/
85. @asgrim
The Golden Rules
1. Keep it simple
2. Know the risks
3. Fail securely
4. Don’t reinvent the wheel
5. Never trust anything / anyone