SlideShare a Scribd company logo
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Deconstructing REST
Security
David Blevins
Tomitribe
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œThe nice thing about standards is
you have so many to choose from.โ€
- Andrew S. Tanenbaum
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Focus Areas
โ€ข Beyond Basic Auth
โ€ข Theory of OAuth 2.0
โ€ข Introduction of JWT
โ€ข Google/Facebook style API security
โ€ข Stateless vs Stateful Architecture
โ€ข HTTP Signatures
โ€ข Amazon EC2 style API security
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Baseline
1000 users
x 3 TPS
4 hops
3000 TPS
frontend
12000 TPS
backend
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Basic Auth
(and its problems)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Basic Auth Message
POST /painter/color/object HTTP/1.1
Host: localhost:8443
Authorization: Basic c25vb3B5OnBhc3M=
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"b":255,"g":0,"name":"blue","r":0}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64
(no auth)
3000 TPS
(LDAP)
12000 TPS
(HTTP)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64
username+password
Base64
15000 TPS
(LDAP)
Password Sent
12000 TPS
(HTTP)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64
IP
whitelisting
3000 TPS
(LDAP)
12000 TPS
(HTTP)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œHey, give me all
of Joeโ€™s salary
information.โ€
โ€œI donโ€™t know
who you are,
โ€ฆ
but sure!โ€
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Latveria Attacks
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Basic Auth - Attacks
Valid
Password Sent
3000 TPS
(HTTP+SSL) IP
whitelisting
9000 TPS
(LDAP)
12000 TPS
(HTTP)
Invalid
Password Sent
6000 TPS
(HTTP+SSL)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
OAuth 2.0
(and its problems)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 - Password Grant
(LDAP)
(Token Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
Verify
Password
Generate
Token
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/object HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"r":0,"g":0,"b":255,"name":"blue"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"r":0,"g":255,"b":0,"name":"green"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/select HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 44
{"color":{"r":255,"g":0,"b":0,"name":"red"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/fill HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":0,"g":255,"b":255,"name":"yellow"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/stroke HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":255,"g":200,"b":255,"name":"orange"}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
401
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 - Refresh Grant
(LDAP)
(Token Store)
Verify
Password
Generate
Token
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"6Fe4jd7TmdE5yW2q0y6W2w",
"expires_in":3600,
"refresh_token":"hyT5rw1QNh5Ttg2hdtR54e",
}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Old pair
โ€ข Access Token 2YotnFZFEjr1zCsicMWpAA
โ€ข Refresh Token tGzv3JOkF0XG5Qx2TlKWIA
New pair
โ€ข Access Token 6Fe4jd7TmdE5yW2q0y6W2w
โ€ข Refresh Token hyT5rw1QNh5Ttg2hdtR54e
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 46
{"color":{"r":0,"g":255,"b":0,"name":"green"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/select HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 44
{"color":{"r":255,"g":0,"b":0,"name":"red"}}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message
POST /painter/color/fill HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":0,"g":255,"b":255,"name":"yellow"}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
What have we achieved?
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
You have more passwords
(at least your devices do)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Term Alert
โ€ข Password Grant???
โ€ข Logging in
โ€ข Token?
โ€ข Slightly less crappy password
โ€ข Equally crappy HTTP Session ID
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
3000 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
4 hops
12000 TPS
backend
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œWho the heck
is
6Fe4jd7TmdE5y
W2q0y6W2w
???????โ€
โ€œNo idea, dude.
Ask the token
server.โ€
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
3000 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
12000 TPS
(token checks)
8 hops
24000 TPS
backend
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
3000 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
12000 TPS
(token checks)
8 hops
24000 TPS
backend
55% of all traf๏ฌc
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
0 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
0 TPS
(token checks)
0 hops
0 TPS
backend
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2
Pointer Pointer
State
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Access Token
Access Pointer?
Access Primary Key?
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
OAuth 2.0
High Frequency Password
Exchange Algorithm?
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Problem: how to detect if a ๏ฌle's
contents have changed?
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Hashing and Signing
Symmetric and Asymmetric
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Hashing Data
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
01010000010001000011011011101000110101001001100001010011110000
00111010101111111111111111000101111101001110111000100010000000000
111111101011100001001100100000101011111001101111111100111011000011
111011001101100100000101011110011001100001011011110101110110001
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
01010000010001000011011011101000110101001001100001010011110000
00111010101111111111111111000101111101001110111000100010000000000
111111101011100001001100100000101011111001101111111100111011000011
111011001101100100000101011110011001100001011011110101110110001
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG More Bits the Better
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Hashing Data
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Hashing Data
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Hashing Data
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Hashing Data
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Eagles beat Patriots 41 to 33
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Eagles beat Patriots 41 to 33
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Eagles beat Patriots 41 to 34
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Protecting the Hash
HMAC (Symmetric)
RSA (Asymmetric)
abc123 abc123
private
public
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG HMAC (Symmetric)
Read &
Write
Read 

& Write
Shared and equal relationship
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG RSA (Asymmetric)
Write
Read
Read
Read
One side has more authority
* the reverse is possible
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Distributed Read-Only Data
Can Write
Read
Read
Read
Data
Encrypted
Hash of Data
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
How many RSA keys does
Susan need to sign
1,000,000
documents?
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
one
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
OAuth 2.0
+
JSon Web Tokens (JWT)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG JSon Web Token
โ€ข Pronounced โ€œJOTโ€
โ€ข Fancy JSON map
โ€ข Base64 URL Encoded
โ€ข Digitally Signed (RSA-SHA256, HMAC-SHA512, etc)
โ€ข Built-in expiration
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG โ€ข { "alg": โ€œRS256", "typ": โ€œJWT" }
โ€ข {
"token-type": "access-token",
"username": "snoopy",
"animal": "beagle",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": [
โ€œtwitterโ€, "mans-best-friend"
],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
โ€ข DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv
0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzl
LJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Access Token Now
โ€ข header (JSON > Base64 URL Encoded)
โ€ข describes how the token signature can be checked
โ€ข payload (JSON > Base64 URL Encoded)
โ€ข Basically a map of whatever you want to put in it
โ€ข Some standard entries such as expiration
โ€ข signature (Binary > Base64 URL Encoded
โ€ข The actual digital signature
โ€ข made exclusively by the /oauth2/token endpoint
โ€ข If RSA, can be checked by anyone
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Access Token Previously
โ€ข 6Fe4jd7TmdE5yW2q0y6W2w
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Access Token Now
โ€ข eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi
10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hbWUiOiJzb
m9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRw
czovL2RlbW8uc3VwZXJiaXouY29tL29hdXRoMi90b2tlbiI
sInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaW
VuZCJdLCJleHAiOjE0NzQyODA5NjMsImlhdCI6MTQ3NDI3O
TE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMz
IIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8
DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1Ta
Elxc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadhVDaiqmhct0
98ocefuv08TdzRxqYoEqYNo
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Subtle But High Impact
Architectural Change
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
What we had
(quick recap)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Pull User Info
From IDP
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Generate an
Access Token
(pointer)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Insert both
into DB
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Send Access Token (pointer)
to client
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Results
Client Holds Pointer Server Holds State
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
What we can do now
(Hello JWT!)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Pull User Info
From IDP
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Format the data
as JSON
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
RSA-SHA 256
sign JSON private
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Insert only
pointer
into DB
(for revocation)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
(LDAP)
Send Access Token (state)
to client
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Client Holds State Server Holds Pointer
Desired
Results
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
Verify
Password
Generate
Signed
Token
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb
WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M
iOiJodHRwczovL2RlbW8uc3VwZXJiaXouY29tL29hdXRoM
i90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0
LWZyaWVuZCJdLCJleHAiOjE0NzQyODA5NjMsImlhdCI6M
TQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ
9.DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8
OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaO
EUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadh
VDaiqmhct098ocefuv08TdzRxqYoEqYNo",
"expires_in":3600,
"refresh_token":"eyJhbGctGzv3JOkF0XG5Qx2TlKWIAkF0X.
eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb
WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M
iOiJodHRwczovL",
}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2.0 Message with JWT
POST /painter/color/palette HTTP/1.1โ€จ
Host: api.superbiz.ioโ€จ
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXR
va2VuIiwidXNlcm5hbWUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3VwZXJ
iaXouY29tL29hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQy
ODA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdYO1GaMGl
6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZ
vzlLJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
User-Agent: curl/7.43.0โ€จ
Accept: */*โ€จ
Content-Type: application/jsonโ€จ
Content-Length: 46โ€จ
โ€จ
{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 + JWT
Tokens Sent
3000 TPS
(HTTP+SSL)
0.55 TPS
(refresh token checks)
(30 minute expiration)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
4 hops
12000 TPS
backend
3000 TPS
(signature veri๏ฌcation)
12000 TPS
(signature veri๏ฌcation)(private key)
(public key)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œHey, give me all
of Joeโ€™s salary
information.โ€
โ€œNot a chance!โ€
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œHey, give me all
of Joeโ€™s salary
information.โ€
โ€œSure thing!โ€
Every Microservice Has the Gateway's Public Key
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Latveria Attacks
(again)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 + JWT
Valid
Tokens Sent
3000 TPS
(HTTP+SSL)
0.55 TPS
(refresh token checks)
Password Sent
1000/daily
(HTTP+SSL)
(LDAP)
4 hops
12000 TPS
backend
9000 TPS
(signature veri๏ฌcation)
12000 TPS
(signature veri๏ฌcation)
Invalid
Tokens Sent
6000 TPS
(HTTP+SSL)
(private key)
(public key)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
HTTP Signatures
(Amazon EC2 style API Security)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG HTTP Signatures
โ€ข No โ€œsecretโ€ ever hits the wire
โ€ข Signs the message itself
โ€ข Proves identity
โ€ข Prevents message tampering
โ€ข Symmetric or Asymmetric signatures
โ€ข IETF Draft
โ€ข https://tools.ietf.org/html/draft-cavage-http-signatures
โ€ข Extremely simple
โ€ข Does NOT eliminate bene๏ฌts of JWT
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
POST /painter/color/palette HTTP/1.1โ€จ
Host: api.superbiz.ioโ€จ
Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*โ€จ
Content-Type: application/jsonโ€จ
Content-Length: 46โ€จ
โ€จ
{"color":{"b":0,"g":255,"r":0,"name":"green"}}
Take the full http
message
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
POST /painter/color/palette HTTP/1.1โ€จ
Host: api.superbiz.ioโ€จ
Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*โ€จ
Content-Type: application/jsonโ€จ
Content-Length: 46โ€จ
โ€จ
{"color":{"b":0,"g":255,"r":0,"name":"green"}}
Select the parts

you want to protect
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
(request-target): POST /painter/color/paletteโ€จ
host: api.superbiz.ioโ€จ
date: Mon, 19 Sep 2016 16:51:35 PDT
content-length: 46
Create a 

Signing String
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
(request-target): POST /painter/color/paletteโ€จ
host: api.superbiz.ioโ€จ
date: Mon, 19 Sep 2016 16:51:35 PDT
content-length: 46
Aj2FGgCdGhIp6LFXjxSxBsSwTp9i
C7t7nmRZs-hrYcQ
Hash the string

(sha256 shown)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
Aj2FGgCdGhIp6LFXjxSxBsSwTp9i
C7t7nmRZs-hrYcQ
Encrypt the hash

(hmac shown)
j050ZC4iWDW40nVx2oVwBEymX
zwvsgm+hKBkuw04b+w=
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signing a Message
Signature
keyId=โ€œorange-1234",
algorithm="hmac-sha256",
headers="(request-target) host date content-lengthโ€,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="โ€จ
Put it all together
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signed Message
POST /painter/color/palette HTTP/1.1โ€จ
Host: api.superbiz.ioโ€จ
Authorization: Signature keyId=โ€œorange-1234",
algorithm="hmac-sha256",
headers="(request-target) host date content-lengthโ€,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="โ€จ
Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*โ€จ
Content-Type: application/jsonโ€จ
Content-Length: 46โ€จ
โ€จ
{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signature Auth
Password Sent
0 TPS
(HTTP)
Signature (no auth)
3000 TPS
(LDAP or Keystore)
12000 TPS
(HTTP)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signature Auth
Password Sent
0 TPS
(HTTP)
Signature Signature
3000 TPS
(LDAP or Keystore)
12000 TPS
(HTTP)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
โ€œHey, give me all
of Joeโ€™s salary
information.โ€
โ€œHey, Larry!
Sure!โ€
Issue Returns
(bad)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
OAuth 2.0 Proof-of-Possession
(JWT + HTTP Signatures)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
Key Value
Identity Information
(JWT)
Key ID
Proof Of Identity
(HTTP Signature)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
{ "alg": โ€œRS256", "typ": โ€œJWT" }
{ "token-type": "access-token",
"username": "snoopy",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": ["twitterโ€, "mans-best-friend"],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc
0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksF
XGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
Access Token
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
{ "alg": โ€œRS256", "typ": โ€œJWT" }
{ "token-type": "pop",
"cnf":{ "kid": "green-1234" }
"username": "snoopy",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": ["twitterโ€, "mans-best-friend"],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc
0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksF
XGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
Access Token
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
Verify
Password
Generate
Signed
Token
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc
3MiOiJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsImV4cCI6M
TMxMTI4MTk3MCwiaWF0IjoxMzExMjgwOTcwLCJjbmYiOnsia2",
"token_type":"pop",
"expires_in":3600,
"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc
3MiOiJodHRwczovL2FzZGZhc2RzZGZzZXJ2ZXIuZXhhbXBsZS5
jb20iLCJleHAiOjEzMTEyODE5NzAsImlhdCI6MTMxMTI4MDk3M",
"key":"eyJrdHkiOiJvY3QiLCJ1c2UiOiJzaWciLCJraWQiOiJvcmFuZ
2UteXlqOUQwZWgiLCJrIjoiVlotMFFHTFoyUF9SUFVTVzEwQ0l1
MFdNeVhxLU5EMnBtRFl6QTBPVEtXVEhscDVpYWM1SzRWZWlS
ci1fQk9vWEo0WDJmU1R0NG5Id29fcXV0YTdqSkpLVDRQRVd5W
WFuQlNGc2kwRFc3b3dULUhFeEFHRHlKdEhVdE53NXhzczhOajZ
PeE5QdjZyUk9FLWtldmhMMndCOWNxZ2RJc2NidkRocmFzMzljd
2ZzIiwiYWxnIjoiSFMyNTYifQ"
}
Generate
HMAC
Key
(Key Store)
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG JSON Web Key (encoded)
eyJrdHkiOiJvY3QiLCJ1c2UiOiJzaWciLCJraWQiOiJvcmFuZ2Ut
eXlqOUQwZWgiLCJrIjoiVlotMFFHTFoyUF9SUFVTVzEwQ0l1M
FdNeVhxLU5EMnBtRFl6QTBPVEtXVEhscDVpYWM1SzRWZ
WlSci1fQk9vWEo0WDJmU1R0NG5Id29fcXV0YTdqSkpLVDRQ
RVd5WWFuQlNGc2kwRFc3b3dULUhFeEFHRHlKdEhVdE53N
XhzczhOajZPeE5QdjZyUk9FLWtldmhMMndCOWNxZ2RJc2Nid
kRocmFzMzljd2ZzIiwiYWxnIjoiSFMyNTYifQ
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG JSON Web Key (decoded)
{ "kty": "oct",
"use": "sig",
"kid": "orange-1234",
"k": "VZ-0QGLZ2P_RPUSW10CIu0WMyXq-ND2pmDYzA0OTKW
THlp5iac5K4VeiRr-_BOoXJ4X2fSTt4nHwo_quta7j
JJKT4PEWyYanBSFsi0DW7owT-HExAGDyJtHUtNw5xs
s8Nj6OxNPv6rROE-kevhL2wB9cqgdIscbvDhras39c
wfs",
"alg": "HS256"
}
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Signed OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1โ€จ
Host: api.superbiz.ioโ€จ
Authorization: Signature keyId=โ€œorange-1234", algorithm="hmac-sha256",
headers="content-length host date (request-target)โ€,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="
Bearer:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5h
bWUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3VwZXJiaXouY29t
L2
9hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQyO
DA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdY
O1GMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaEl
xc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNoโ€จ
Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*โ€จ
Content-Type: application/jsonโ€จ
Content-Length: 46โ€จ
โ€จ
{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG OAuth 2 + JWT + Signatures
Tokens+Signatures Sent
3000 TPS
(HTTP safe)
0.55 TPS
(refresh token checks)
Password Sent
1000/daily
(HTTP+TLS)
OAuth 2
(LDAP)
4 hops
12000 TPS
backend
3000 TPS
(signature veri๏ฌcation)
12000 TPS
(signature veri๏ฌcation)
#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG
https://tools.ietf.org/html/draft-ietf-oauth-pop-key-distribution
Speci๏ฌcation Reference
@dblevins @tomitribe#RESTSecurity @dblevins @tomitribetribestream.io/denverjug2018
DenverJUG Observations
โ€ข HTTP Signatures the only HTTP friendly approach
โ€ข Signatures does not solve the โ€œIdentity Loadโ€ problem
โ€ข OAuth 2 with JWT signi๏ฌcantly improves IDP load
โ€ข Plain OAuth 2
โ€ข HTTP Session-like implications
โ€ข OAuth 2 with JWT
โ€ข Signed cookie
โ€ข Signing key to the future
Thank You
Slides & Gateway Sign-up
https://tribestream.io/boulderjug2018
#RESTSecurity
Boulder JUG

More Related Content

PDF
2018 Boulder JUG Deconstructing and Evolving REST Security
PDF
2018 jPrime Deconstructing and Evolving REST Security
PDF
2017 dev nexus_deconstructing_rest_security
PDF
2016 JavaOne Deconstructing REST Security
PDF
2017 Devoxx MA Deconstructing and Evolving REST Security
PDF
2018 SDJUG Deconstructing and Evolving REST Security
PDF
2018 JavaLand Deconstructing and Evolving REST Security
PDF
Deconstructing and Evolving REST security
2018 Boulder JUG Deconstructing and Evolving REST Security
2018 jPrime Deconstructing and Evolving REST Security
2017 dev nexus_deconstructing_rest_security
2016 JavaOne Deconstructing REST Security
2017 Devoxx MA Deconstructing and Evolving REST Security
2018 SDJUG Deconstructing and Evolving REST Security
2018 JavaLand Deconstructing and Evolving REST Security
Deconstructing and Evolving REST security

What's hot (20)

PDF
2018 colombia deconstruyendo y evolucionando la seguridad en servicios rest
PDF
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
PDF
Side-Channels on the Web: Attacks and Defenses
PDF
Con Foo 2017 - Don't Loose Sleep - Secure Your REST
PDF
Deconstructing and Evolving REST Security
PPTX
Understanding gRPC Authentication Methods
PDF
RESTful Web API and MongoDB go for a pic nic
PDF
Stateless Microservice Security via JWT and MicroProfile - Mexico
PDF
Stateless Microservice Security via JWT and MicroProfile - ES
PDF
Stateless Microservice Security via JWT and MicroProfile - Guatemala
PDF
Don't Loose Sleep - Secure Your Rest - php[tek] 2017
PPTX
Locking the Doors -7 Pernicious Pitfalls to avoid with Java
PPTX
Build your own Blockchain with the right tool for your application
PDF
Build your business on top of Open Source
PPT
Incorporating Web Services in Mobile Applications - Web 2.0 San Fran 2009
ย 
PPTX
BrightonSEO Sep 2015 - HTTPS | Mark Thomas
PDF
REST Web API with MongoDB
ย 
PDF
Building APIs in an easy way using API Platform
PPTX
Elegant Rest Design Webinar
PPTX
Dirty Little Secrets They Didn't Teach You In Pentest Class v2
2018 colombia deconstruyendo y evolucionando la seguridad en servicios rest
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
Side-Channels on the Web: Attacks and Defenses
Con Foo 2017 - Don't Loose Sleep - Secure Your REST
Deconstructing and Evolving REST Security
Understanding gRPC Authentication Methods
RESTful Web API and MongoDB go for a pic nic
Stateless Microservice Security via JWT and MicroProfile - Mexico
Stateless Microservice Security via JWT and MicroProfile - ES
Stateless Microservice Security via JWT and MicroProfile - Guatemala
Don't Loose Sleep - Secure Your Rest - php[tek] 2017
Locking the Doors -7 Pernicious Pitfalls to avoid with Java
Build your own Blockchain with the right tool for your application
Build your business on top of Open Source
Incorporating Web Services in Mobile Applications - Web 2.0 San Fran 2009
ย 
BrightonSEO Sep 2015 - HTTPS | Mark Thomas
REST Web API with MongoDB
ย 
Building APIs in an easy way using API Platform
Elegant Rest Design Webinar
Dirty Little Secrets They Didn't Teach You In Pentest Class v2
Ad

Similar to 2018 Denver JUG Deconstructing and Evolving REST Security (20)

PDF
2018 IterateConf Deconstructing and Evolving REST Security
PDF
Dublin JUG Stateless Microservice Security via JWT, TomEE and MicroProfile
PDF
2018 Madrid JUG Deconstructing REST Security
PDF
2019 ITkonekt Stateless REST Security with MicroProfile JWT
PDF
2017 JavaOne Deconstructing and Evolving REST Security
PDF
Secured REST Microservices with Spring Cloud
PDF
How to Implement Token Authentication Using the Django REST Framework
PDF
Rest api titouan benoit
PDF
Are You Properly Using JWTs?
PDF
Seguridad en microservicios via micro profile jwt
PPT
Securing RESTful API
PDF
I Don't Care About Security (And Neither Should You)
PDF
JavaOne 2014 - Securing RESTful Resources with OAuth2
PPTX
Restful api
PDF
What the Heck is OAuth and OpenID Connect - DOSUG 2018
PDF
JDD2015: Security in the era of modern applications and services - Bolesล‚aw D...
ย 
PDF
I Don't Care About Security (And Neither Should You)
PPTX
Microservice security with spring security 5.1,Oauth 2.0 and open id connect
PDF
What the Heck is OAuth and Open ID Connect? - UberConf 2017
PDF
[4developers2016] - Security in the era of modern applications and services (...
ย 
2018 IterateConf Deconstructing and Evolving REST Security
Dublin JUG Stateless Microservice Security via JWT, TomEE and MicroProfile
2018 Madrid JUG Deconstructing REST Security
2019 ITkonekt Stateless REST Security with MicroProfile JWT
2017 JavaOne Deconstructing and Evolving REST Security
Secured REST Microservices with Spring Cloud
How to Implement Token Authentication Using the Django REST Framework
Rest api titouan benoit
Are You Properly Using JWTs?
Seguridad en microservicios via micro profile jwt
Securing RESTful API
I Don't Care About Security (And Neither Should You)
JavaOne 2014 - Securing RESTful Resources with OAuth2
Restful api
What the Heck is OAuth and OpenID Connect - DOSUG 2018
JDD2015: Security in the era of modern applications and services - Bolesล‚aw D...
ย 
I Don't Care About Security (And Neither Should You)
Microservice security with spring security 5.1,Oauth 2.0 and open id connect
What the Heck is OAuth and Open ID Connect? - UberConf 2017
[4developers2016] - Security in the era of modern applications and services (...
ย 
Ad

More from David Blevins (8)

PDF
DevNexus 2020 - Jakarta Messaging 3.x, Redefining JMS
PDF
2019 JJUG CCC Stateless Microservice Security with MicroProfile JWT
PDF
2017 JCP EC: Configuration JSR
PDF
2015 JavaOne EJB/CDI Alignment
PDF
JavaOne 2013 - Apache TomEE, Java EE Web Profile {and more} on Tomcat
PDF
2011 JavaOne EJB with Meta Annotations
PDF
2011 JavaOne Apache TomEE Java EE 6 Web Profile
PDF
2011 JavaOne Fun with EJB 3.1 and OpenEJB
DevNexus 2020 - Jakarta Messaging 3.x, Redefining JMS
2019 JJUG CCC Stateless Microservice Security with MicroProfile JWT
2017 JCP EC: Configuration JSR
2015 JavaOne EJB/CDI Alignment
JavaOne 2013 - Apache TomEE, Java EE Web Profile {and more} on Tomcat
2011 JavaOne EJB with Meta Annotations
2011 JavaOne Apache TomEE Java EE 6 Web Profile
2011 JavaOne Fun with EJB 3.1 and OpenEJB

Recently uploaded (20)

PDF
Cloud-Scale Log Monitoring _ Datadog.pdf
PPTX
Introduction to Information and Communication Technology
PPTX
presentation_pfe-universite-molay-seltan.pptx
PPTX
CHE NAA, , b,mn,mblblblbljb jb jlb ,j , ,C PPT.pptx
PPT
tcp ip networks nd ip layering assotred slides
PPTX
Introuction about ICD -10 and ICD-11 PPT.pptx
PPTX
Digital Literacy And Online Safety on internet
DOCX
Unit-3 cyber security network security of internet system
PPTX
Job_Card_System_Styled_lorem_ipsum_.pptx
PDF
Unit-1 introduction to cyber security discuss about how to secure a system
PPTX
Funds Management Learning Material for Beg
PDF
๐Ÿ’ฐ ๐”๐Š๐“๐ˆ ๐Š๐„๐Œ๐„๐๐€๐๐†๐€๐ ๐Š๐ˆ๐๐„๐‘๐Ÿ’๐ƒ ๐‡๐€๐‘๐ˆ ๐ˆ๐๐ˆ ๐Ÿ๐ŸŽ๐Ÿ๐Ÿ“ ๐Ÿ’ฐ
ย 
PDF
An introduction to the IFRS (ISSB) Stndards.pdf
PDF
SASE Traffic Flow - ZTNA Connector-1.pdf
PPTX
Introuction about WHO-FIC in ICD-10.pptx
PPTX
innovation process that make everything different.pptx
PPTX
PptxGenJS_Demo_Chart_20250317130215833.pptx
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PDF
The New Creative Director: How AI Tools for Social Media Content Creation Are...
PPTX
Internet___Basics___Styled_ presentation
Cloud-Scale Log Monitoring _ Datadog.pdf
Introduction to Information and Communication Technology
presentation_pfe-universite-molay-seltan.pptx
CHE NAA, , b,mn,mblblblbljb jb jlb ,j , ,C PPT.pptx
tcp ip networks nd ip layering assotred slides
Introuction about ICD -10 and ICD-11 PPT.pptx
Digital Literacy And Online Safety on internet
Unit-3 cyber security network security of internet system
Job_Card_System_Styled_lorem_ipsum_.pptx
Unit-1 introduction to cyber security discuss about how to secure a system
Funds Management Learning Material for Beg
๐Ÿ’ฐ ๐”๐Š๐“๐ˆ ๐Š๐„๐Œ๐„๐๐€๐๐†๐€๐ ๐Š๐ˆ๐๐„๐‘๐Ÿ’๐ƒ ๐‡๐€๐‘๐ˆ ๐ˆ๐๐ˆ ๐Ÿ๐ŸŽ๐Ÿ๐Ÿ“ ๐Ÿ’ฐ
ย 
An introduction to the IFRS (ISSB) Stndards.pdf
SASE Traffic Flow - ZTNA Connector-1.pdf
Introuction about WHO-FIC in ICD-10.pptx
innovation process that make everything different.pptx
PptxGenJS_Demo_Chart_20250317130215833.pptx
Tenda Login Guide: Access Your Router in 5 Easy Steps
The New Creative Director: How AI Tools for Social Media Content Creation Are...
Internet___Basics___Styled_ presentation

2018 Denver JUG Deconstructing and Evolving REST Security