I Don’t Care About Security
And Neither Should You
@joel__lord
#SFNode
About Me
@joel__lord
joellord
@joel__lord
#midwestjs
About Me
@joel__lord
joellord
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
That reminds me of OAuth!
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
@joel__lord
#midwestjs
OAuth - Flows
Authorization Code
But Why?
Delegation!
Traditional
Applications
! Browser requests a
login page
Traditional
Applications
! Browser requests a
login page
Traditional
Applications
! Browser requests a
login page
Traditional
Applications
! Browser requests a
login page
! The server validates
on its database
Traditional
Applications
! Browser requests a
login page
! The server validates
on its database
👍
Traditional
Applications
! Browser requests a
login page
! The server validates
on its database
! It creates a session
and provides a
cookie identifier
What’s wrong with
traditional auth?
! Multiple platforms
connecting to your
application
What’s wrong with
traditional auth?
! Multiple platforms
connecting to your
application
! Tightly coupled
What’s wrong with
traditional auth?
! Multiple platforms
connecting to your
application
! Tightly coupled
! Sharing credentials
to connect to another
API
What’s wrong with
traditional auth?
! Multiple platforms
connecting to your
application
! Tightly coupled
! Sharing credentials
to connect to another
API
! Users have a
gazillion passwords
to remember, which
increases security
risks
OAuth
OAuth - The Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
OAuth - The Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
@joel__lord
#midwestjs
Authentication Flows
Implicit Flow
Tokens 101
@joel__lord
#midwestjs
OAuth
Tokens
Access Token Refresh Token
! Give you access to a resource
! Controls access to your API
! Short lived
! Enables you to get a new token
! Longed lived
! Can be revoked
@joel__lord
#midwestjs
OAuth
Tokens
Refresh Token
! Enables you to get a new token
! Longed lived
! Can be revoked
@joel__lord
#midwestjs
OAuth
Tokens
Refresh Token
! Enables you to get a new token
! Longed lived
! Can be revoked
@joel__lord
#midwestjs
OAuth
Tokens
! WS-Federated
! SAML
! JWT
! Custom stuff
! More…
JSON Web Token
! Header
! Payload
! Signature
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload
{
"sub": "1234567890",
"name": "Joel Lord",
"scope": "posts:read posts:write"
}
Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload), secret)
JSON Web Token
! Header
! Payload
! Signature
Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZWwgTG
9yZCIsImFkbWluIjp0cnVlLCJzY29wZSI6InBvc3RzOnJlY
WQgcG9zdHM6d3JpdGUifQ
Signature
XesR-pKdlscHfUwoKvHnACqfpe2ywJ6t1BJKsq9rEcg
JSON Web Token
! Header
! Payload
! Signature eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj
M0NTY3ODkwIiwibmFtZSI6IkpvZWwgTG9yZCIsImFkbWl
uIjp0cnVlLCJzY29wZSI6InBvc3RzOnJlYWQgcG9zdHM6d
3JpdGUifQ.XesR-
pKdlscHfUwoKvHnACqfpe2ywJ6t1BJKsq9rEcg
JSON Web Token
! Header
! Payload
! Signature
Image: https://jwt.io
Codiiiing Time!
Auth Server API
var express = require('express');
var Webtask = require('webtask-tools');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var jwt = require("jsonwebtoken");
var app = express();
var users = [
{id: 1, username: "joellord", password: "joellord"},
{id: 2, username: "guest", password: "guest"}
];
app.use(bodyParser.json());
app.post("/login", function(req, res) {
if (!req.body.username || !req.body.password) return res.status(400).send("Need
username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.status(200).send({token: token});
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
module.exports = Webtask.fromExpress(app);
var express = require('express');
var Webtask = require('webtask-tools');
var bodyParser = require('body-parser');
var jwt = require("jsonwebtoken");
var app = express();
var users = [
{id: 1, username: "joellord", password: "joellord"},
{id: 2, username: "guest", password: "guest"}
];
app.use(bodyParser.urlencoded());
app.get("/login", function(req, res) {
var loginForm = "<form method='post'><input type=hidden name=callback value='" +
req.query.callback + "'><input type=text name=username /><input type=text name=password /
><input type=submit></form>";
res.status(200).send(loginForm);
});
app.post("/login", function(req, res) {
if (!req.body.username || !req.body.password) return res.status(400).send("Need
username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.redirect(req.body.callback + "#access_token=" + token);
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
Auth Server
var express = require('express');
var bodyParser = require('body-parser');
var jwt = require("jsonwebtoken");
var app = express();
// ...
@joel__lord
#midwestjs
Auth Server
var express = require('express');
var bodyParser = require('body-parser');
var jwt = require("jsonwebtoken");
var app = express();
// ...
@joel__lord
#midwestjs
Auth Server
var express = require('express');
var bodyParser = require('body-parser');
var jwt = require("jsonwebtoken");
var app = express();
// ...
@joel__lord
#midwestjs
Auth Server
var express = require('express');
var bodyParser = require('body-parser');
var jwt = require("jsonwebtoken");
var app = express();
// ...
@joel__lord
#midwestjs
Auth Server
// Requires ...
var users = [
{id: 1, username: "joellord", password: "joellord"},
{id: 2, username: "guest", password: "guest"}
];
@joel__lord
#midwestjs
Auth Server
// Requires ...
var users = [...];
app.use(bodyParser.urlencoded());
app.post("/login", function(req, res) {
// POST for login
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
Auth Server
// Requires ...
var users = [...];
app.use(bodyParser.urlencoded());
app.post("/login", function(req, res) {
// POST for login
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
Auth Server
app.post("/login", function(req, res) {
// POST for login
if (!req.body.username || !req.body.password)
return res.status(400).send("Need username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.redirect(req.body.callback + "#access_token=" + token);
});
@joel__lord
#midwestjs
Auth Server
app.post("/login", function(req, res) {
// POST for login
if (!req.body.username || !req.body.password)
return res.status(400).send("Need username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.redirect(req.body.callback + "#access_token=" + token);
});
@joel__lord
#midwestjs
Auth Server
app.post("/login", function(req, res) {
// POST for login
if (!req.body.username || !req.body.password)
return res.status(400).send("Need username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.redirect(req.body.callback + "#access_token=" + token);
});
@joel__lord
#midwestjs
Auth Server
app.post("/login", function(req, res) {
// POST for login
if (!req.body.username || !req.body.password)
return res.status(400).send("Need username and password");
var user = users.find(function(u) {
return u.username === req.body.username && u.password === req.body.password;
});
if (!user) return res.status(401).send("User not found");
var token = jwt.sign({
sub: user.id,
scope: "api:read",
username: user.username
}, "mysupersecret", {expiresIn: "10 minutes"});
res.redirect(req.body.callback + "#access_token=" + token);
});
@joel__lord
#midwestjs
Auth Server
// Requires ...
var users = [...];
app.use(bodyParser.urlencoded());
app.post("/login", function(req, res) {
// POST for login
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
app.listen(8080, () => console.log("Auth server running on 8080"));}
@joel__lord
#midwestjs
API
var express = require('express');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var expressjwt = require("express-jwt");
var app = express();
@joel__lord
#midwestjs
API
var express = require('express');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var expressjwt = require("express-jwt");
var app = express();
@joel__lord
#midwestjs
API
var express = require('express');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var expressjwt = require("express-jwt");
var app = express();
@joel__lord
#midwestjs
API
var express = require('express');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var expressjwt = require("express-jwt");
var app = express();
@joel__lord
#midwestjs
API
var express = require('express');
var bodyParser = require('body-parser');
var randopeep = require("randopeep");
var expressjwt = require("express-jwt");
var app = express();
@joel__lord
#midwestjs
API
// Requires ...
var jwtCheck = expressjwt({
secret: "mysupersecret"
});
@joel__lord
#midwestjs
API
// Requires and config ...
app.get("/headline", function(req, res) {
// Unprotected
res.status(200).send(randopeep.clickbait.headline());
});
app.get("/protected/headline", jwtCheck, function(req, res) {
// Protected
res.status(200).send(randopeep.clickbait.headline("Joel Lord"));
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
API
// Requires and config ...
app.get("/headline", function(req, res) {
// Unprotected
res.status(200).send(randopeep.clickbait.headline());
});
app.get("/protected/headline", jwtCheck, function(req, res) {
// Protected
res.status(200).send(randopeep.clickbait.headline("Joel Lord"));
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
API
// Requires and config ...
app.get("/headline", function(req, res) {
// Unprotected
res.status(200).send(randopeep.clickbait.headline());
});
app.get("/protected/headline", jwtCheck, function(req, res) {
// Protected
res.status(200).send(randopeep.clickbait.headline("Joel Lord"));
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
API
// Requires and config ...
app.get("/headline", function(req, res) {
// Unprotected
res.status(200).send(randopeep.clickbait.headline());
});
app.get("/protected/headline", jwtCheck, function(req, res) {
// Protected
res.status(200).send(randopeep.clickbait.headline("Joel Lord"));
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
@joel__lord
#midwestjs
API
// Requires and config ...
app.get("/headline", function(req, res) {
// Unprotected
});
app.get("/protected/headline", jwtCheck, function(req, res) {
// Protected
});
app.get('*', function (req, res) {
res.sendStatus(404);
});
app.listen(8888, () => console.log("API listening on 8888"));
@joel__lord
#midwestjs
Front-End
Add the headers
Live Demo
https://github.com/joellord/
secure-spa-auth0
Delegation!
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
Introducing OpenID Connect
@joel__lord
#midwestjs
OpenID Connect
! Built on top of OAuth 2.0
! OpenID Connect (OIDC) is to OpenID what
Javascript is to Java
! Provides Identity Tokens in JWT format
! Uses a /userinfo endpoint to provide the info
@joel__lord
#midwestjs
OpenID Connect
Scopes
! openid
! profile
! email
! address
! phone
@joel__lord
#midwestjs
OpenID Connect Flows
Authorization Code
scope=openid%20profile
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
@joel__lord
#midwestjs
Authentication Flows
Authorization Code
/userinfo
@joel__lord
#midwestjs
OpenID Connect
Full flow
https://openidconnect.net
Delegation!
I Don’t Care About Security
@joel__lord
joellord
MidwestJS, Minneapolis, MN
August 10, 2018

More Related Content

PDF
I Don't Care About Security (And Neither Should You)
PDF
I Don't Care About Security
PDF
PHP Identity and Data Security
PDF
Node.js Authentication and Data Security
PDF
Ruby Robots
PPTX
Token Based Authentication Systems with AngularJS & NodeJS
PPTX
Secure Payments Over Mixed Communication Media
PDF
Protecting the Future of Mobile Payments
I Don't Care About Security (And Neither Should You)
I Don't Care About Security
PHP Identity and Data Security
Node.js Authentication and Data Security
Ruby Robots
Token Based Authentication Systems with AngularJS & NodeJS
Secure Payments Over Mixed Communication Media
Protecting the Future of Mobile Payments

What's hot (20)

PDF
Secure Payments Over Mixed Communication Media
PDF
Clean code
DOCX
Error found
PDF
Elasticsearch for Pharo Smalltalk
PPTX
Building Secure User Interfaces With JWTs (JSON Web Tokens)
PDF
Speeding up Red Team engagements with carnivorall
ZIP
Dr.Repi
PDF
JWT - To authentication and beyond!
PPTX
Representing Material Culture Online: Historic Clothing in Omeka
TXT
Havij dork
KEY
前端概述
PDF
R57php 1231677414471772-2
PDF
I Don't Care About Security (And Neither Should You)
PDF
A bug bounty tale: Chrome, stylesheets, cookies, and AES
PDF
Yuriy Voziy "Fantastic Template Strings and Where to Use Them"
PDF
Building Advanced XSS Vectors
DOCX
Index chrome
PDF
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
PDF
ZIP
Anex....,,,.
Secure Payments Over Mixed Communication Media
Clean code
Error found
Elasticsearch for Pharo Smalltalk
Building Secure User Interfaces With JWTs (JSON Web Tokens)
Speeding up Red Team engagements with carnivorall
Dr.Repi
JWT - To authentication and beyond!
Representing Material Culture Online: Historic Clothing in Omeka
Havij dork
前端概述
R57php 1231677414471772-2
I Don't Care About Security (And Neither Should You)
A bug bounty tale: Chrome, stylesheets, cookies, and AES
Yuriy Voziy "Fantastic Template Strings and Where to Use Them"
Building Advanced XSS Vectors
Index chrome
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
Anex....,,,.
Ad

Similar to I Don't Care About Security (And Neither Should You) (20)

PDF
I Don't Care About Security (And Neither Should You)
PDF
Modern API Security with JSON Web Tokens
KEY
Advanced CSRF and Stateless Anti-CSRF
PPT
Securing Java EE Web Apps
PDF
Quick run in with Swagger
KEY
Building a real life application in node js
PDF
Finding things on the web with BOSS
PDF
RoadSec 2017 - Trilha AppSec - APIs Authorization
PDF
How to test complex SaaS applications - The family july 2014
PDF
PPTX
Twas the night before Malware...
PDF
Going realtime with Socket.IO
PPT
External Data Access with jQuery
PDF
Make WordPress realtime.
PDF
Roll Your Own API Management Platform with nginx and Lua
PPTX
REST with Eve and Python
PDF
How to implement golang jwt authentication and authorization
PPTX
Token Based Authentication Systems
PDF
Mojolicious. Веб в коробке!
PPTX
API Pain Points (PHPNE)
I Don't Care About Security (And Neither Should You)
Modern API Security with JSON Web Tokens
Advanced CSRF and Stateless Anti-CSRF
Securing Java EE Web Apps
Quick run in with Swagger
Building a real life application in node js
Finding things on the web with BOSS
RoadSec 2017 - Trilha AppSec - APIs Authorization
How to test complex SaaS applications - The family july 2014
Twas the night before Malware...
Going realtime with Socket.IO
External Data Access with jQuery
Make WordPress realtime.
Roll Your Own API Management Platform with nginx and Lua
REST with Eve and Python
How to implement golang jwt authentication and authorization
Token Based Authentication Systems
Mojolicious. Веб в коробке!
API Pain Points (PHPNE)
Ad

More from Joel Lord (20)

PDF
From Ceasar Cipher To Quantum Cryptography
PDF
I Don't Care About Security (And Neither Should You)
PDF
I Don't Care About Security (And Neither Should You)
PDF
I Don't Care About Security (And Neither Should You)
PDF
Forgot Password? Yes I Did!
PDF
I Don't Care About Security (And Neither Should You)
PDF
Mot de passe oublié? Absolument!
PDF
Asynchronicity: concurrency. A tale of
PDF
Learning Machine Learning
PDF
Forgot Password? Yes I Did!
PDF
WTH is a JWT
PDF
Forgot Password? Yes I Did!
PDF
WTH is a JWT
PDF
Asynchonicity: concurrency. A tale of
PDF
Secure your SPA with Auth0
PDF
Learning Machine Learning
PDF
Learning Machine Learning
PDF
Rise of the Nodebots
PDF
Let's Get Physical
PDF
Learning About Machine Learning
From Ceasar Cipher To Quantum Cryptography
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
Forgot Password? Yes I Did!
I Don't Care About Security (And Neither Should You)
Mot de passe oublié? Absolument!
Asynchronicity: concurrency. A tale of
Learning Machine Learning
Forgot Password? Yes I Did!
WTH is a JWT
Forgot Password? Yes I Did!
WTH is a JWT
Asynchonicity: concurrency. A tale of
Secure your SPA with Auth0
Learning Machine Learning
Learning Machine Learning
Rise of the Nodebots
Let's Get Physical
Learning About Machine Learning

Recently uploaded (20)

PPTX
Slides World Games Great Redesign Eco Economic Epochs.pptx
PDF
The_Decisive_Battle_of_Yarmuk,battle of yarmuk
PPTX
Networking2-LECTURE2 this is our lessons
PDF
How Technology Shapes Our Information Age
PDF
JuanConnect E-Wallet Guide for new users.pdf
DOCX
MLS 113 Medical Parasitology (LECTURE).docx
PDF
AGENT SLOT TERPERCAYA INDONESIA – MAIN MUDAH, WD CEPAT, HANYA DI KANCA4D
DOCX
Audio to Video AI Technology Revolutiona
PPT
chapter 5: system unit computing essentials
PPSX
AI AppSec Threats and Defenses 20250822.ppsx
PPTX
using the citation of Research to create a research
PDF
healthwealthtech4all-blogspot-com-2025-08-top-5-tech-innovations-that-will-ht...
PPTX
购买林肯大学毕业证|i20Lincoln成绩单GPA修改本科毕业证书购买学历认证
PDF
ilide.info-huawei-odn-solution-introduction-pdf-pr_a17152ead66ea2617ffbd01e8c...
PPTX
WEEK 15.pptx WEEK 15.pptx WEEK 15.pptx WEEK 15.pptx
PPTX
Digital Project Mastery using Autodesk Docs Workshops
PPTX
北安普顿大学毕业证UoN成绩单GPA修改北安普顿大学i20学历认证文凭
PPTX
在线订购名古屋艺术大学毕业证, buy NUA diploma学历认证失败怎么办
PDF
Testing & QA Checklist for Magento to Shopify Migration Success.pdf
PPTX
Concepts of Object Oriented Programming.
Slides World Games Great Redesign Eco Economic Epochs.pptx
The_Decisive_Battle_of_Yarmuk,battle of yarmuk
Networking2-LECTURE2 this is our lessons
How Technology Shapes Our Information Age
JuanConnect E-Wallet Guide for new users.pdf
MLS 113 Medical Parasitology (LECTURE).docx
AGENT SLOT TERPERCAYA INDONESIA – MAIN MUDAH, WD CEPAT, HANYA DI KANCA4D
Audio to Video AI Technology Revolutiona
chapter 5: system unit computing essentials
AI AppSec Threats and Defenses 20250822.ppsx
using the citation of Research to create a research
healthwealthtech4all-blogspot-com-2025-08-top-5-tech-innovations-that-will-ht...
购买林肯大学毕业证|i20Lincoln成绩单GPA修改本科毕业证书购买学历认证
ilide.info-huawei-odn-solution-introduction-pdf-pr_a17152ead66ea2617ffbd01e8c...
WEEK 15.pptx WEEK 15.pptx WEEK 15.pptx WEEK 15.pptx
Digital Project Mastery using Autodesk Docs Workshops
北安普顿大学毕业证UoN成绩单GPA修改北安普顿大学i20学历认证文凭
在线订购名古屋艺术大学毕业证, buy NUA diploma学历认证失败怎么办
Testing & QA Checklist for Magento to Shopify Migration Success.pdf
Concepts of Object Oriented Programming.

I Don't Care About Security (And Neither Should You)