[2018 oracle code one] JWT’s suck

JWTs Suck
Speaker: Randall Degges
@rdegges

For more blog posts, see The Oracle Code One table of contents


JWT (JSON Web Token)

  • pronounced “jot”
  • JSON data
  • cryptographically signed
  • Not encrypted most of the time
  • Prove that some JSON data can be trusted
  • Common use case: Website generates JWT after validating credentials. Website then sends JWT to browser and browser stores in localStorage. Then browser sends to website for subsequent requests.
  • There are stateless and stateful JWT. The later maps to a session id. People don’t use stateful JWTs.
  • 2012 – Spec came out
  • 2014 – began gaining adoption/marketing
  • seven of the first 10 hits on jwt are marketing pitches

Cookies

  • JWT stores session id as JSON blob. In cookie, just a string.
  • Session cookies are underappreciated
  • Use HttpOnly flag
  • Use SameSite-strict flag
  • Use secure flag
  • Browser sends cookie header to website

HTML Local Storage

  • JavaScript only accessible
  • Store key value pairs in browser

Myths about JWTs

  • JWTs are easier to use – JWTs require additional tools, libraries and knowledge to function. Developer effort. Vs session cookies which are built into all web frameworks.
  • JWTs are more flexible – Cookies can store one piece of data per cookie or serialize into a cookie. JWT has claims which are certain pieces of data that always included – ex: when token created/expires. Cookie actually expires at expiration times. Tokens don’t disappear automatically
  • JWTs are more secure – Cryptographically signed and can be encrypted. However, actually using the encryption feature is rare. The spec is complicated and libraries vary in support. Also multiple vulnerabilities in past two years.
  • JWTs prevent CSRF – Cookies are susceptible to CSRF because sent to server automatically. Local storage is safe from CSRF because developer needs to write JavaScript to send the data. However, you are now vulnerable to XSS which is worse. CSRF is far easier to fix than XSS because most websites link to Google Analytics, third party jquery, etc. OWASP recommends not storing any sensitive information in local storage.
  • JWTs are better for cross domain authentication – Good when create temporary token that lasts for 10 seconds. It is used between the login service and your app.
  • JWTs are more efficient than cookies – 179 bytes. If just sign the id part, is 64 bytes. Difference even greater when add data.
  • JWTS are easy to revoke – Could change signing key of application, but that also logs out the other users. Alternatively, use the revocation list pattern so can invalidate one. But now you’ve introduced state/database/cache.

Better use cases for JWT

  • Short duration (one minute or less) for one time use
  • ex: downloading a file, reseting a password

My take: I hadn’t heard of JWTs. So I learned a lot! It was fun hearing the audience questions/comments/statements was fun. That said, I need to read up on the topic to see the other point of view.

two factor and google voice

I’ve been using two factor authentication for a number of years.  I like when services offer a choice of two factor options. Or the common Google Authenticator app. Less of a fan of SMS required two factor. If I lose my phone or number, I can’t two factor authenticate to a few services. The most recent being Venmo. Ironically, Venmo wouldn’t let me change.

One of my friends has used Google Voice for phone for years. I decided to switch to a Google Voice number. This gives me a few advantages:

  • phone rings on multiple devices
  • texts get turned into email which means I can view them on multiple devices (nice for two factor)
  • I’m decoupled from my cell phone number for two factor

Today I’m switching over a bunch of services to use a different phone number for two factor. This table shows the services I can think of where I use two factor.

Interestingly, having possession of the original phone number was not necessary for any of the services. So I could have done this even if I had lost my phone. I had enough other options set up for two factor. Also ironically, I couldn’t switch Venmo which motivated all this. I can close the account though so if this ever becomes a problem…

Service Two Factor Options How Switching Went
Google

(original blog post)

Authenticator, SMS, phone, codes, key, Google prompt Google knew my number in my profile, but I still had to verify to set in profile. And again when wetting as my two factor option. Emailed that changed number.
Amazon

(original blog post)

Authenticator, phone, SMS Under my account added a mobile number. Confirmed with SMS text verification.
Twitter

(original blog post)

Authenticator, SMS, security key, backup code Went to mobile and clicked edit to change number. I didn’t enable SMS, but now it has the right number in case I need it as a one off. Confirmed with SMS text verification.
Facebook Authenticator, SMS, codes, key Went to security and use two factor. Added Google voice and backup. Emailed that added number.

(Only allowed SMS last I looked. Good improvement).

Venmo Just SMS Won’t accept my Google voice number and gave an error that it needs a mobile number. 
GitHub (original blog post) Choice of authenticator, SMS, security keys, recovery tokens (other site), and recovery codes (strings) Clear existing number. Set new Google voice number. Enter code texted to new number. GitHub also emailed me that I added and removed a SMS number.
PayPal

(original blog post)

SMS, phone Confirming my landline number, it had me type a code when they called instead of supplying a code read to me. This seems more secure. Good! The new number was added as unconfirmed. I clicked confirm to get a text to confirm it.
LinkedIn

(original blog post)

SMS I couldn’t find the two factor page without a direct link. I scrolled up and added a phone number. After confirming the verification code, it automatically made the new phone number primary. I couldn’t delete the original since it is used for two factor. So I went to the two factor section and changed the number. it sent me a code again. Then I finally went back and deleted the original number. And for every one of those operations, I had to enter my linked in password. This felt excessive.
DropBox

(original blog post)

Authenticator, SMS, codes, physical device Went to settings and changed my number. I had to enter my authenticator code but not verify possession of the phone number. Emailed that changed two factor settings.
Yahoo

(original blog post)

Email, phone, text Went to account to try to change number. Got an error that it can’t accept a VOIP number. I was able to change it my land line. I use Yahoo almost never so it doesn’t matter whether this is convenient. Emailed that removed and added number.
Slack Authenticator Added my phone number. No verification required.
Apple

(original blog post)

Various Added a trusted phone number and confirmed code. Verified with my computer as well as the code. Removed original number. Emailed that number changed

good security – warnings in project

Cloudbees puts out security alerts frequently for Jenkins. We didn’t patch at CodeRanch for a while and then it got overwhelming. I wanted to get the latest JUnit plugin today. After upgrading to the latest Jenkins core, I went to manage Jenkins and saw this.

I was pleased. The product itself reminded me that we should check our security settings. It also reminded of all the security alerts that we missed.

We are now up to date (as of this moment) and it took less than hour. If I wasn’t counting the Jenkins core install and test, it would have been even less.