Securing the Web without site-specific passwords

Preview:

DESCRIPTION

Has anyone else noticed that the OWASP Top 10 is not changing very much? Especially in the realm of authentication-related problems. I don't claim to have the one true solution for this, but one thing is certain: if we change how things are done on the web and relieve developers from having to store passwords, we can make things better. We need to let web developers outsource their authentication needs to people who can do it well. Does that mean we should force all of our users to join Facebook? Well not really. That might work for some sites, but outsourcing all of our logins to a single for-profit company isn't a solution that works for the whole web. The open web needs a better solution. One that enable users to choose their identity provider and shop for the most secure one if that's what they're into. This is the promise behind Persona and the BrowserID protocol. Choose your email provider carefully and let's get rid of all of these site-specific passwords that are just sitting there waiting to be leaked and cracked.

Citation preview

François Marier – @fmarier

Securing the Web without site-specific passwords

François Marier – @fmarier

F**k all of these passwords, we can do better than this!

problem #1:

passwords are hard to secure

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

20132013

passwordpassword

guidelines

guidelines

passwords are hard to secure

they are a liability

ALTER TABLE userDROP COLUMN password;

problem #2:

passwords are hard to remember

pick an easy password

pick an easy password

use it everywhere

negative externality:

sites that don't care about securityimpose a cost on more important sites

passwords are hard to remember

they need to be reset

controlemail

account

controlall

accounts=

existing login solutions

client certificates

decentralised

myid.com/u/francois

privacy®

existing login systemsare not good enough

ideal web-wide identity system

● decentralised● simple● cross-browser

ideal web-wide identity system

● decentralised● simple● cross-browser

ideal web-wide identity system

● decentralised● simple

cross-browser

ideal web-wide identity system

what if it were a standardpart of the web browser?

how does it work?

fmarier@gmail.com

fmarier@gmail.com

getting a proof of email ownership

authenticate?

authenticate?

public key

authenticate?

public key

signed public key

you have a signed statement from yourprovider that you own your email address

logging into a 3rd party site

Valid for: 2 minutes

wikipedia.org

assertion

Valid for: 2 minutes

wikipedia.org

check audience

assertion

Valid for: 2 minutes

wikipedia.org

check audiencecheck expiry

assertion

Valid for: 2 minutes

wikipedia.org

check audiencecheck expirycheck signature

assertion

assertion

Valid for: 2 minutes

wikipedia.org

public key

assertion

Valid for: 2 minutes

wikipedia.org

assertion

session cookie

demo #1:

http://www.voo.st/

fmariertest@eyedee.me

Persona is already adecentralised system

SMS with PIN codes

SMS with PIN codes

Jabber / XMPP

SMS with PIN codes

Jabber / XMPP

Yubikeys

SMS with PIN codes

Jabber / XMPP

Yubikeys

LDAP accounts

SMS with PIN codes

Jabber / XMPP

Yubikeys

LDAP accounts

Client certificates

SMS with PIN codes

Jabber / XMPP

Yubikeys

LDAP accounts

Client certificates

Password-wrapped secret key

{ "public-key": { "algorithm": "RS", "n":"685484565272...", "e":"65537" }, "encrypted-private-key": { "iv": "tmg7gztUQT...", "salt": "JMtGwlF5UWY", "ct": "8DdOjD1IA1..." }, "authentication": "...", "provisioning": "..."}

decentralisation is the answer, but it's not

a product adoption strategy

we can't wait for all domainsto adopt Persona

we can't wait for all domainsto adopt Persona

solution: a temporarycentralised fallback

demo #2:

http://sloblog.io/

fmariertest@aol.com

Persona already workswith all email domains

identity bridging

demo #3:

http://www.reasonwell.com/

fmariertest@yahoo.com

Persona supportsall modern browsers

>= 8

Persona is decentralised,simple and cross-browser

it's simple for users, but is it also

simple for developers?

<script src=”https://login.persona.org/include.js”></script></body></html>

navigator.id.watch({ loggedInEmail: “francois@mozilla.com”, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

navigator.id.watch({ loggedInUser: “francois@mozilla.com”, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; }});

navigator.id.request()

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; }});

eyJhbGciOiJEUzEyOCJ9.eyJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IkRTIiwieSI6ImNhZDg2ZDgyNWU0MjBkMGI4Njk5MjM4ZDM5ZTFjYjIyOGMyMTk1NWFiMzcwOTQ1YzExNzBhMzM4NjcyNDM0ZDJmNGYxZDg5ZjFkZjMzNmU1ZjZjZjk2YjhiOTlmMjgyNmFjNTYxZmI1YWMyYTc4ZjNhMzBkNGYxNTVhYjc3ZGExYmY3MWU4ZGMzNjQ0MmU2NjQ3MmE5Mjg0N2I2YjFlNDRkMTJlM2IwMjVjOWZmNTFmNDdhMWE5ZWYyMGZhOTVjMTcxZjBkMTYzNGE4ZTY4YTk5NWU3ZjFjY2FiYTJlOTRjYTI3ODE1ZWVkMTcxYjY1YTJmZGQzNTE1NjY3OTI0ZjUiLCJwIjoiZmY2MDA0ODNkYjZhYmZjNWI0NWVhYjc4NTk0YjM1MzNkNTUwZDlmMWJmMmE5OTJhN2E4ZGFhNmRjMzRmODA0NWFkNGU2ZTBjNDI5ZDMzNGVlZWFhZWZkN2UyM2Q0ODEwYmUwMGU0Y2MxNDkyY2JhMzI1YmE4MWZmMmQ1YTViMzA1YThkMTdlYjNiZjRhMDZhMzQ5ZDM5MmUwMGQzMjk3NDRhNTE3OTM4MDM0NGU4MmExOGM0NzkzMzQzOGY4OTFlMjJhZWVmODEyZDY5YzhmNzVlMzI2Y2I3MGVhMDAwYzNmNzc2ZGZkYmQ2MDQ2MzhjMmVmNzE3ZmMyNmQwMmUxNyIsInEiOiJlMjFlMDRmOTExZDFlZDc5OTEwMDhlY2FhYjNiZjc3NTk4NDMwOWMzIiwiZyI6ImM1MmE0YTBmZjNiN2U2MWZkZjE4NjdjZTg0MTM4MzY5YTYxNTRmNGFmYTkyOTY2ZTNjODI3ZTI1Y2ZhNmNmNTA4YjkwZTVkZTQxOWUxMzM3ZTA3YTJlOWUyYTNjZDVkZWE3MDRkMTc1ZjhlYmY2YWYzOTdkNjllMTEwYjk2YWZiMTdjN2EwMzI1OTMyOWU0ODI5YjBkMDNiYmM3ODk2YjE1YjRhZGU1M2UxMzA4NThjYzM0ZDk2MjY5YWE4OTA0MWY0MDkxMzZjNzI0MmEzODg5NWM5ZDViY2NhZDRmMzg5YWYxZDdhNGJkMTM5OGJkMDcyZGZmYTg5NjIzMzM5N2EifSwicHJpbmNpcGFsIjp7ImVtYWlsIjoiZm9vQG1vY2tteWlkLmNvbSJ9LCJpYXQiOjEzNzY1MzY0NjM1MTgsImV4cCI6MTM3NjU0MDA2MzUxOCwiaXNzIjoibW9ja215aWQuY29tIn0.IeUR0_3ayAZkdNSXjF4aaCwSHnHa4X1lzrjX-qkNcPIbXx1hmQQPwg~eyJhbGciOiJEUzEyOCJ9.eyJleHAiOjEzNzY1MzY3MDc2MzUsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3QifQ.NJ8H1qZcWXbXfPJSdgB_mORHQ442ZkY0XYfdQsZZsIjooG7k7qWyVw

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; }});

require_once('Auth/BrowserID.php');

$verifier = new Auth_BrowserID('http://123done.org');$result = $verifier->verifyAssertion($_POST['assertion']);

{ status: “okay”,

audience: “http://123done.org”,

expires: 1344849682560,

email: “francois@mozilla.com”,

issuer: “login.persona.org”}

require_once('Auth/BrowserID.php');

$verifier = new Auth_BrowserID('http://123done.org');$result = $verifier->verifyAssertion($_POST['assertion']);

if ($result->status === 'okay') { echo "Hi " . $result->email;} else { echo "Error: " . $result->reason;}

{ status: “failed”,

reason: “assertion has expired”}

require_once('Auth/BrowserID.php');

$verifier = new Auth_BrowserID('http://123done.org');$result = $verifier->verifyAssertion($_POST['assertion']);

if ($result->status === 'okay') { echo "Hi " . $result->email;} else { echo "Error: " . $result->reason;}

navigator.id.logout()

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; }});

1. load javascript library

1. load javascript library

2. setup login & logout callbacks

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

4. verify proof of ownership

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

4. verify proof of ownership

no API keyneeded

you can add support forPersona in four easy steps

one simple request

building a new site:default to Persona

working on an existing site:add support for Persona

before

after

after

navigator.id.request()

ALTER TABLE userDROP COLUMN password;

To learn more about Persona:

https://login.persona.org/http://identity.mozilla.com/

https://developer.mozilla.org/docs/Persona/Why_Personahttps://developer.mozilla.org/docs/Persona/Quick_Setup

https://github.com/mozilla/browserid-cookbookhttps://developer.mozilla.org/docs/Persona/Libraries_and_plugins

http://123done.org/https://wiki.mozilla.org/Identity#Get_Involved

@fmarier http://fmarier.org

identity provider API

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

© 2013 François Marier <francois@mozilla.com>This work is licensed under aCreative Commons Attribution-ShareAlike 3.0 New Zealand License.

Top 500 passwords: http://xato.net/passwords/more-top-worst-passwords/

Parchment: https://secure.flickr.com/photos/27613359@N03/6750396225/

Cookie on tray: https://secure.flickr.com/photos/jamisonjudd/4810986199/

Uncle Sam: https://secure.flickr.com/photos/donkeyhotey/5666065982/

Australian passport: https://secure.flickr.com/photos/digallagher/5453987637/

Stop sign: https://secure.flickr.com/photos/artbystevejohnson/6673406227/

Photo credits:

Recommended