Slide 1

Slide 1 text

Shreyansh Pandey — @acodingpanda How Not to Do Authentication

Slide 2

Slide 2 text

About Me tl;dr I am pretty boring.

Slide 3

Slide 3 text

Authentication — What? Why? How?

Slide 4

Slide 4 text

Bad Ways to do it… MD5, direct-database storage, etc.

Slide 5

Slide 5 text

MD5? So? “I-can-use-MD5-SHA-etc-because" starter pack: 1. It’s still a one-way hash function. 2. It’s secure. It can’t be broken. 3. I enforce strong password rules. 4. I like copying code.

Slide 6

Slide 6 text

So… How does it matter?

Slide 7

Slide 7 text

Few pointers: 1. It’s still a one-way hash function. Yes, it is. But that does not mean it is secure. 2. It’s secure. It can’t be broken. CVE-2012-3287 — md5crypt (b-crypt means blowfish-crypt).

Slide 8

Slide 8 text

Do NOT read me: yes, you’re right. I created a new slide specifically for this xkcd. I enforce strong password rules.

Slide 9

Slide 9 text

Discourse in cryptography • Entropy • ROT-3, Caesar’s Cipher (broken?) • Paradox?

Slide 10

Slide 10 text

Buzzword — bcrypt/SHA-* • With SHA, it’s about implementation. FGPA or GPU. • SHA has a 32-bit design. • bcrypt is pretty decent at what it does: take more time.

Slide 11

Slide 11 text

Viś-a-viś, the problem • Consider SHA-256. It’s implemented using a 32-bit architecture. Very easy on GPU. • bcrypt, not so much. In-memory tables. Iterative recalculation. • GPU in the past, FPGA now. bcrypt can be exploited. • DDoS with bcrypt. Probable.

Slide 12

Slide 12 text

Then what? • NIST SP-800-132. • Use PBKDF2 with high iteration count (Apple uses 10,000.)

Slide 13

Slide 13 text

New kid on the block • Argon2* family of hashes. • One problem Hint: it’s overly complicated to implement.

Slide 14

Slide 14 text

The Golden Rule It’s impossible to build something absolutely hacker-safe. You can make it hacker- deterrent.

Slide 15

Slide 15 text

Barriers • Cryptography is hard. Without a mathematics degree, it’s Greek (literally). • There are some tutorials on how to do credential-storage but they aren’t real world examples. • PBKDF2: Microsoft, 1Password… (also Google?) • Don’t go about building your library*.

Slide 16

Slide 16 text

The Solution •Try learning Cryptography. It’s not that hard. •Always be updated on the latest trends and 0- Day’s. •Don’t follow a tutorial (or a talk) blindly. •If you have some proprietary logic for credential storage, get it audited. •Always remember — in cryptography, you will most certainly need a tailor-made solution.

Slide 17

Slide 17 text

That’s theory, what about tangible “stuff”? 1. Don’t overdo your length. It can lead to a DOS. (*) 2. Use an adaptive one-way function (PBKDF2, bcrypt, Argon2, etc.) with a cost-factor (“time delay”). 3. Use keyed functions like HMAC, etc. in conjunction with (2). 4. Never store plaintext passwords (evidently). 5. The key for HMAC should be treated like a private key; don’t store it in your database.

Slide 18

Slide 18 text

Right… What about in JavaScript? • There are some really cool libraries which take out the guess-work: • libsodium (https://github.com/jedisct1/libsodium) • credential (https://github.com/ericelliott/credential) • node-argon2 (https://github.com/ranisalt/node-argon2)

Slide 19

Slide 19 text

Viś-a-viś… Most of the credential storage tutorials don’t cover password reset… which is a worry.

Slide 20

Slide 20 text

1. Predictable tokens A. LCG, pseudo-random number generators, time-based function. B. Bruteforce. So, a large entropy? But that doesn’t mean it’s secure. Consider the substitution cipher. 2. Their value. They are as meaningful as passwords; then why are they not stored as such? 3. (Bonus: side-channel verifications. Security questions, rate limiting, audit records.)

Slide 21

Slide 21 text

Real-World Examples

Slide 22

Slide 22 text

public function index() { $session = $this->request->session(); $login = $session->read('Administrators.id'); if(!empty($login)) { return $this->redirect( ['controller' => ‘SecuredAdmin', 'action' => 'dashboard']); } $this->viewBuilder()->layout('admin_login'); $this->set(compact('user')); $this->set('_serialize', ['user']); } function login() { $username = $this->request->data['username']; $password = $this->request->data['password']; $admins = TableRegistry::get('Admins'); $row = $admins ->find() ->where(['username' => $username]) ->where(['password' => md5($password)]) ->first(); ...

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

const payload = request.payload; if (payload.resettoken != '' && payload.resettoken != null) { User().filter({ resettoken: resettoken }).getJoin({ ‘reset’: true }).then(function(err, data) { if (err) { return { isSuccess: false } } return h.view('resetPassword', { resettoken: resettoken }); }) }

Slide 30

Slide 30 text

app.handle('/', 'post', function(req, h) { User().filter({ resettoken: req.payload.resettoken }).getJoin({ 'reset': true }).then(function(err, data) { if (err) { return { isSuccess: false } } User.get(data.id).apply({ password: Helpers.calculatehash(password) }).then(function(err, data) { if (err) { return { isSucccess: false } } return { h.view('success-password-' + data.name); } }); }); });

Slide 31

Slide 31 text

Talk is boring. Show me code.

Slide 32

Slide 32 text

Sample Application The repository is divided into a couple of branches. 1. master — this contains a badly designed Node.js application. 2. better-storage — a better credential storage paradigm. 3. better-auth — a complete RESTful API with auth.

Slide 33

Slide 33 text

http://bit.ly/jsfoo-node-auth

Slide 34

Slide 34 text

Questions? https://github.com/labsvisual https://linkedin.com/in/acodingpanda/ https://isomr.co/