JSON Web Tokens should be avoided - <AUTHOR> https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid <comment><USER2> The criticisms of JWT seem to fall into two categories:

(1) Criticizing vulnerabilities in particular JWT libraries, as in this article.

(2) Generally criticizing the practice of using any "stateless" client tokens. Because there's no great way to revoke them early while remaining stateless, etc.

The problem is that both of these groups only criticize, neither of them can ever seem to actually recommend any _alternatives_.

I could care less about JWT _per se_. I'm happy to implement a similar pattern with something else (e.g. store a secure cookie post-auth, skip all the refresh business and just let it expire when it expires, and employ an ugly revocation strategy only if absolutely necessary). I don't need JWT for this.

If I'm providing a REST API, then I'd prefer a token string that I could pass as a header value rather than forcing the use of cookies. Although I suppose you could argue that a cookie is just another header value.

Either way, if you're serving up a REST API to a JavaScript UI... what's NOT a good option is server-side session state (e.g. Java servlet sessions). That requires you to either: configure your load balancer for sticky-sessions, or employ a solution to share session state across all your server-side instances (which never works very reliably). Moreover, relying on a session isn't a very RESTful auth strategy in the first place.

So if I'm writing a SPA in 2017, then I'm definitely taking a client-side approach and running afoul of the #2 critics. And since JWT is so widely implemented (e.g. if I use a "Login with Google" option then I'm using JWT), I'm probably running afoul of the #1 critics too.

These criticism are fine, I guess. There's no faster route to blog clicks, book sales, speaker invites, and consulting dollars than: (1) telling everyone to jump on this year's hype train, or (2) telling everyone that last year's hype train sucks. What the world really needs is a bit more actual prescriptive recommendations of what to do _instead_.

<comment><USER3> I don't care if you want to use stateless client tokens. They're fine. You should understand the operational limitations (they may keep you up late on a Friday scrambling to deploy a token blacklist), but, we're all adults here, and you can make your own decisions about that.

The issue with JWT in particular is that it doesn't bring anything to the table, but comes with a whole lot of terrifying complexity. Worse, you as a developer won't see that complexity: JWT looks like a simple token with a magic cryptographically-protected bag-of-attributes interface. The problems are all behind the scenes.

For most applications, the technical problems JWT solves are not especially complicated. Parseable bearer tokens are something Rails has been able to generate for close to a decade using ActiveSupport::MessageEncryptor. AS::ME is _substantially_ safer than JWT, but people are swapping it out of applications in favor of JWT.

Someone needs to write the blog post about how to provide bag-of-attributes secure bearer tokens in all the major programming environments. Someone else needs to get to work standardizing one of those formats as an alternative to JWT so that there's a simple answer to "if not JWT then what?" that rebuts the (I think sort of silly) presumption that whatever an app uses needs to be RFC standardized.

But there's a reason crypto people hate the JWT/JOSE/JWE standards. You should avoid them. They're in the news again because someone noticed that one of the public key constructions (ECDHE-ES) is terribly insecure. I think it's literally the case that no cryptographer bothered to point this out before because they all assumed people knew JWT was a tire fire.

<comment><USER4> > they may keep you up late on a Friday scrambling to deploy a token blacklist

Because every token has an iat datetime, you don't need a token blacklist to invalidate tokens. You just need some sort of tokens_invalid_if_issued_before_datetime setting that gets checked whenever you validate the signature of a token.

The alternative is to store a UUID for each user, and just rotate those whenever they log out, change or reset their password, or there is some sort of security event. These are then stored in the payload and used as a secret. The one advantage over just using dates is that with the former, there can be weird bugs if you have multiple servers with clocks that are out of sync.

But you shouldn't ever need to blacklist specific tokens, at least not unless you have some highly specialized use case.

<comment><USER5> Agreed. Revoking all user sessions instead of a specific token is the common case. The only usage I see for revoking a specific token is when the user is deactivating a specific client.

<comment><USER6> Also when a user changes his password, no ?

</comment></comment></comment></comment></comment><comment><USER7> I don't see any valid arguments in the post. The issues raised are either mis- implementation or misuse of JWT. All I am getting is "JWT can be misused in such such way that makes your application vulnerable. And neither its standards nor libraries prevent that, so it sucks".

But when is the last time we see any technology successfully prevented people from being silly?

<comment><USER8> I agree. I've read the whole article and still wonder why I should stop using JWT.

<comment><USER9> You shouldn't. Simply check that the hash algorithm specified by the client is the one you used when issuing the token. In a side project, I simply hard code the algorithm [1].

[1]: [https://github.com/teotwaki/grace- calendar/blob/develop/app/...](https://github.com/teotwaki/grace- calendar/blob/develop/app/helpers/jwt.rb)

Edit: DYAC.

</comment></comment></comment><comment><USER10> I use stateful JWTs for session management, storing them in localStorage. If someone can exfiltrate the token, they will get a week long authorization, as well as some identifiable information (username, name and role).

Probably I can achieve the same overall system with cryptographically secure session cookies, that are persisted in a database, or other store that is accessible across multiple servers. I guess it would amount to the same thing.

Originally I implemented it because:

* My systems are SPA's. Totally JS dependent from the word go.

* I felt like there would be some advantages to being able to establish certain claims without verification. Say for display purposes prior to server comms (show a list of multiple available sessions for example)...In practise this hasn't really been true. Generally I find in the end I am always checking and verifying anyway - without any huge overhead.

* I've always had a sort of fuzz of uncertainty about Cookies. They always felt a bit out of my hands. Thinking it about rigorously of course, people can switch off JS. They can switch off persistence.

* All my user's local data can be persisted in one place, rather than having to store a reference in the Cookie and then lookup in localStorage. In reality though the code for this is pretty trivial...

So overall while I don't know how right he is, I feel like maybe he has a point. Why not just use cookies?

Maybe it's just because as a JS dev, I want everything to stay within a JS universe...and for some reason Cookies have always felt outside of that to me.

<comment><USER11> If I can offer some advice in the other direction, don't use cookies.

I tried to do the right thing, use HTTP-only cookies set over an HTTPS endpoint only to find that it's stupidly complicated and has a lot of annoying edge cases. Turns out iOS's webviews don't like them, iOS in general doesn't like them to be on api.hostname.com if the app is on app.hostname.com, you can't validate if you are logged in or not without doing a web request (which is annoying as hell if you are trying to keep a "logged in" state in something like a react app), you need to deal with a bunch of stupid flags to get the damn browser to even let them go across domains, and a hell of a lot of other annoyances that I can't remember right now.

We are most likely moving to something like JWTs (stored in localstorage or indexeddb) soon because of these issues.

<comment><USER12> Wouldn't you need to assign your cookies to the TLD for them to be accessible to both subdomains?

<comment><USER13> It would also send them to the CDN if it's hosted on a cdn. subdomain.

<comment><USER12> Definitely, there's a whole host of potential pitfalls from assigning cookies to the TLD. From the OP's post though it sounded like their issue was one subdomain being unable to access cookies of another subdomain.

<comment><USER11> It's more issues with "3rd party" cookies.

"app.hostname.tld" doesn't need to actually access the cookies at all, it just needs to make requests to "api.hostname.tld" which sets the cookies and then later validates them.

Unfortunately safari blocks this use case unless you have also been to "api.hostname.tld" directly and there doesn't seen to be any easy way around it (outside of allowing all 3rd party cookies...)

And while iOS safari now handles this (i think they allow *.hostname.tld to use 3rd party cookies for any other subdomains as long as hostname isn't a common provider or something?) it doesn't seem to work consistently for UIWebView or WKWebView hybrid applications. And the "allow 3rd party cookies" setting doesn't seem to apply to the web views either.

<comment><USER12> Ahh... yes I'm familiar. I've worked on a couple apps where Apple/Mozilla 3rd Party Cookie polices were a pain point. One option we used was an interstitial page that the user visited briefly hosted on the API layer. Another was switching from cookies to Bearer Tokens which is a whole other bag of worms.

</comment></comment></comment></comment></comment></comment></comment><comment><USER14> A lot of people are talking about the "none" algorithm issue, but the more recent vulnerability[0] is more telling: The report to the working group mailing list[1] led to the point that the standard had a "security considerations" section in the RFC, and this particular issue was never covered.

And now there are difficulties around the fact they cannot update an RFC which people will refer to for years.

It's not a vulnerability in one or two libraries - it looks like just about every made the same mistake, which points to something much more broken.

[0] [https://auth0.com/blog/critical-vulnerability-in-json-web- en...](https://auth0.com/blog/critical-vulnerability-in-json-web-encryption) [1] [https://www.ietf.org/mail- archive/web/jose/current/msg05613....](https://www.ietf.org/mail- archive/web/jose/current/msg05613.html)

</comment><comment><USER15> The "none" algorithm set in header is a well known problem and, for example, nodejs most used library automatically uses asymmetric keys when one is given, ignoring the header ([https://github.com/auth0/node- jsonwebtoken/blob/master/verif...](https://github.com/auth0/node- jsonwebtoken/blob/master/verify.js#L72))

As long as the problem is known to the developers and the key is specified, I think the biggest issue of JWT is the lack of session invalidation (that is, if you log out your already emitted tokens are still valid until their expiration), but it's a good tradeoff for not having server sessions.

<comment><USER16> Session invalidation is possible though, by maintaining a (short) blacklist of tokens on the server. JSON Web Tokens can be given an ID (via the _jti_ claim), and server-side these IDs can be matched against this blacklist. When you log out, you send a request to the service that your current token be blacklisted.

Because JSON Web Tokens are short-lived, the blacklist need only contain tokens valid for _validity period_ plus a few seconds and remains very small (often empty).

If you use JWT to allow authorization on several server, then you do need to distribute this blacklist, so it is not a completely trivial solution. In the simplest scenario you might suffice with only maintaining a blacklist on the server that can refresh tokens (this means that when the token expires, a new one cannot be automatically acquired).

<comment><USER17> Yeah, and that's kinda sad because now you have to check a signature AND query a database!

<comment><USER18> s/database/in-memory-map/g should be fine - and suddenly it's pretty lightweight (subtracting service restarts and a highly available message bus of course :)

<comment><USER19> s/in-memory-map/cache-server/g if you happen to have a load balancer without sticky session.

<comment><USER13> In both cases there is a DB somewhere storing the list. The difference is that with the blacklist the server can keep an in-memory cache because it's so small. Sessions don't need to be invalidated atomically so the blacklist can be refreshed every couple of seconds.

</comment></comment></comment></comment></comment></comment><comment><USER20> Oh my god! Outrage! Superlatives!

Come on. By all means, criticize flawed implementations containing bugs and security holes, but drop the attention-seeking behavior of screaming loudly about how an entire standard is [insert string of superlatives here related to "worthless" and "broken"]. If you're going to make such incredibly strong claims, your arguments had better be up to snuff.

With good implementations (plenty of which exist), and careful usage (via good coding and design habits), JWT is a fine standard and it can save a solid amount of time when constructing the security portions of a system.

Shouting about how something is 100% flawed and should be cast into the flames may get you plenty of views and outrage cred, but (thankfully) it doesn't say much about the veracity of your analysis.

</comment><comment><USER21> This article is slightly misleading. One should ALWAYS be suspect of any article that states X is always bad and should be avoided. Google, Facebook, Microsoft and hundreds of other companies are using JWT in security critical software. If you've ever logged into an app with Google, you've used JWT.

All I see here is the author complaining about poorly implemented JWT libraries. It's not a problem with the spec, it's a problem with the implementation. XML-DSIG suffered from a number of similar issues and was arguably less secure than JWT because of the massive attack surface provided by all the specifications layered on top of each other.

Here's how you can use JWT Safely:

1\. Standardize on what's allowed in the alg header and validate it, don't rely on the JWT library you're using to do it for you.

2\. Make sure you're using a high quality JWT library, jwt.io keeps a list of JWT implementations and highlights gaps.

3\. Understand that bugs in code related to token generation and verification can and lead to compromise of your application and potentially your user's data. Treat such code with great care.

</comment><comment><USER22> It would really help encourage the uptake of better alternatives like libsodium if it were standardized. Just referencing some random library can scare decision makers; whereas referencing an IETF official document or ISO standard makes them just take it as given.

The same problem exists with serialization formats - you have XML and JSON, both of which are standardized and have an "official face", although JSON was not born that way. Google protocol buffers are quite superior in many ways, yet as they are just some product of some company and not an actual standard, decision makers are scared of them.

Technology experts do not get to make all the technical decisions, so standardization matters, even if for the stakeholder feelgood factor!

<comment><USER23> ... yes, but... sidenote, JSON is almost _unreasonably_ easy to grok, and translates well into every web-abstracted language, making it the clear-and- away winner.

At the end of the day, tech doesn't win. Developer experience wins. By the time companies have the resources to fight for every iota of performance, they've already won because they shipped product faster than everyone else --- why? Their developers could move and iterate quickly.

</comment></comment><comment><USER24> "Send a header that specifies the "none" algorithm be used"

Why would an issuer ever let a client decide what algo to use?

"Send a header that specifies the "HS256" algorithm when the application normally signs messages with an RSA public key."

Again, under what circumstances would a header be used by the client to ask for a specific implementation?

What about encrypted client side cookies - would you let the client "send a header" to specify which key to use???

The only problems you highlighted are serious input validation issues and a naive, broken trust model.

<comment><USER25> > _The only problems you highlighted are serious input validation issues and a > naive, broken trust model._

If these things are suggested in the standard and promptly followed by major implementations, then the standard isn't very good.

<comment><USER26> But they aren't. Nobody is suggesting to anybody to use NONE as the algorithm.

<comment><USER25> EDIT: the secondary spec describing the algorithms is at least clear on the use of none, I missed that at first: _Implementations that support Unsecured JWSs MUST NOT accept such objects as valid unless the application specifies that it is acceptable for a specific object to not be integrity protected. Implementations MUST NOT accept Unsecured JWSs by default._

[https://www.rfc-editor.org/rfc/rfc7518.txt](https://www.rfc- editor.org/rfc/rfc7518.txt)

Still, my point about it missing from RFC7115 stands.

\---- Original comment </comment></comment></comment></comment><comment>---

The standard says you should support NONE as the algorithm and that you should use the algorithm the client sends you, all the while completely failing to mention the issues with that, both in its Security Considerations section (which mentions even more "obvious" things like "use keys with high entropy") and in the description of the algorithm to decode a token (which initial implementers probably relied upon to get to a "correct" implementation). Sorry, that is a failure of the spec as well in my book.

If you spec something with risks, at least mark the critical parts clearly with "point away from foot".

A better standard IMHO would have suggested the API for the decode functions, making it clear that the algorithm used should be whiteli

<comment><USER24> I don't think the spec meant to read that you must allow the client to be able to forge tokens by accepting tokens issued by it without an algo or signature.

If you issue tokens with none, then you will have to accept them when clients send them back. This is obviously a very bad idea, but that's all th spec says. If the issuer chooses to be insecure, that is a valid choice.

If you issue tokens with a specific algo, and clients send them back with a different or none header, you _know_ they have been forged.

The spec allows issuers to decide whether to use none, it doesn't say you must trust none tokens if you know you didn't issue them.

<comment><USER25> And the spec doesn't spell it out, and initial libraries implementations thus forgot to include things like "let the user specify which algos to accept". And if common libraries provide simple APIs, users expect that these APIs still provide good security.

A standard promoted as "the standard for secure tokens" should not aim for "You can use the pieces to build a correctly behaving system" or "the spec allows secure implementations", it should aim for "if you use this and follow some spelled-out basic rules you get fool-proof secure tokens" and make wrong usage as hard has possible.

</comment></comment></comment><comment><USER27> I'm really confused by this post, a signed JWT is issued by the identity provider (or API end point) and is then validated again by the API end point when part of an API call, usually as a bearer token in the header. The validation of the signed JWT is done via the API.

The approach I use is to have a 'use once' refresh token (long timeout) and a security token (short time out) and JTIs to hold a list of logged out/invalid (refresh token used twice) security token IDs.

<comment><USER28> > The approach I use is to have a 'use once' refresh token (long timeout) and > a security token (short time out) and JTIs to hold a list of logged > out/invalid (refresh token used twice) security token IDs.

Here's what I've never understood about this approach: the browser can send many requests at the same time, over the same (HTTP/2) or different (HTTP/1.1) connections. If, say, six requests hit your backend at the same time, all with the same refresh and security tokens, with four more queued up on the user- agent, and the security token is expired, how do you know:

1\. that all ten requests are valid,

2\. to revoke the security token once,

3\. to generate one new security token,

4\. to mark the refresh token as used,

5\. to generate one new refresh token?

Is it as simple as granting some leeway on how long the tokens can be used after they expire/are revoked? Do you have some way of serializing requests on the client to prevent this from happening? Or do you assign all ten requests the same "batch" ID and tie them together on the backend somehow? Do you do a preflight request to refresh the security token if it's expired?

</comment></comment><comment><USER29> Complaining about OAEP when RSA-OAEP is perfectly safe seems needlessly straw- grasping, the other complaints (should) stand perfectly well on their own.

I've used JWT in three languages and the API has always sucked, really badly. I always end up with a verbose heap of gunk - and in some cases, like jwt-go, there is not even a complete example of use in the README + docs. mfw. It should not take multiple steps to sign or verify a signature.

<comment><USER3> I agree. The OAEP thing was weird.

<comment><USER30> In fact, JWE and JWS are not as flawed as JWT is, right? ACME uses JWS.

</comment></comment></comment><comment><USER31> The author of [http://blog.intothesymmetry.com/2017/03/critical- vulnerabili...](http://blog.intothesymmetry.com/2017/03/critical- vulnerability-in-json-web.html) here FWIW. Personally I would not be so drastic. JOSE per se is not too bad (at least the idea is cool). Some crypto choices though have been really arguable...

<comment><USER3> That post is great work. Thanks again. But I think you're wrong about JWT.

The problem with JWT/JOSE is that it's too complicated for what it does. It's a meta-standard capturing basically all of cryptography which, as you've ably observed (along with Matthew Green), was not written by or with cryptographers. Crypto vulnerabilities usually occur in the joinery of a protocol. JWT was written to maximize the amount of joinery.

Good modern crypto constructions don't do complicated negotiation or algorithm selection. Look at Trevor Perrin's Noise protocol, which is the transport for Signal. Noise is instantiated statically with specific algorithms. If you're talking to a Chapoly Noise implementation, you cannot with a header convince it to switch to AES-GCM, let alone "alg:none". The ability to negotiate different ciphers dynamically is an own-goal. The ability to negotiate to _no crypto_ , or (almost worse) to inferior crypto, is disqualifying.

A good security protocol has good defaults. But JWT doesn't even get non- replayability right; it's implicit, and there's more than one way to do it. Application data is mixed with metadata (any attribute not in the JOSE header is in the same namespace as the application's data). Anything that can possibly go wrong, JWT wants to make sure will go wrong.

It's 2017 and they still managed to drag all of X.509 into the thing, and they indirect through URLs. Some day some serverside library will implement JWK URL indirection, and we'll have managed to reconstitute an old inexplicably bad XML attack.

For that matter, something crypto people understand that I don't think the JWT people do: public key crypto isn't better than symmetric key crypto. It's certainly not a good default: if you don't absolutely need public key constructions, you shouldn't use them. They're multiplicatively more complex and dangerous than symmetric key constructions. But just in this thread someone pointed out a library --- auth0's --- that apparently defaults to public key JWT. That's because JWT practically begs you to find an excuse to use public key crypto.

These words occur in a JWT tutorial (I think, but am not sure, it's auth0's):

"For this reason encrypted JWTs are sometimes nested: an encrypted JWT serves as the container for a signed JWT. This way you get the benefits of both."

There are implementations that default to compressed.

There's a reason crypto people table flip instead of writing detailed critiques of this protocol. It's a bad protocol. You look at this and think, for what? To avoid the effort of encrypting a JSON blob with libsodium and base64ing the output? Burn it with fire.

<comment><USER32> What should I use instead? I pass around JWTs attached to HTTP requests that represent an authenticated user, and contain things such as a user's email, groups, scopes etc. I've tried to keep it simple (RSA, SHA256, nothing interesting), and use the subset of JWT that seems sane (basically the bits I see Google using in their JWT based OAuth flow)

I used JWTs because

1\. I like the statelessness of JWTs (though I've learnt that there are many trade offs related to this)

2\. OAuth uses JWTs, Google uses OAuth, and Google usually know what they're doing

3\. I can attach custom claims

4\. I don't know of any alternatives, other than x509, which I have less confidence on me being able to validate correctly than JWTs.

What would you suggest? An opaque token which I then look up against a central database/api?

<comment><USER33> SPKI (RFCs 2692 & 2693) offers a well-developed, well-thought-out framework which meets all your needs: SPKI certificates can contain state, and thus support server statelessness; SPKI certificates can be used as OAuth tokens; SPKI certificates support custom claims (and in fact go so far as to define a well-formed claim calculus which can be implemented easily, and which supports just about anything one would wish to do); and SPKI certificates are far, far simpler than X.509.

Take a look: [https://tools.ietf.org/html/rfc2692](https://tools.ietf.org/html/rfc2692) & [https://tools.ietf.org/html/rfc2693](https://tools.ietf.org/html/rfc2693)

</comment></comment></comment></comment><comment><USER34> For my current use-case, one of the appealing things about JWT is there are libraries for just about every language, which makes it easy for 3rd party developers to integrate with my service.

Are there any better alternatives to JWT that have implementations in many languages?

If not, elsewhere in this thread tptacek and others have suggested essentially `base64_encode(crypto_auth(json_encode(object)))` would be sufficient... is there any reason not to just slap a name on that "standard" and publish a bunch of libraries?

<comment><USER35> I was confused about libsodium/NaCl APIs, specifically crypto_sign vs crypto_auth. The difference:

1\. `crypto_auth` is for secret-key signatures (auth): [https://download.libsodium.org/doc/secret- key_cryptography/s...](https://download.libsodium.org/doc/secret- key_cryptography/secret-key_authentication.html)

2\. `crypto_sign` is for public-key signatures: [https://download.libsodium.org/doc/public- key_cryptography/p...](https://download.libsodium.org/doc/public- key_cryptography/public-key_signatures.html)

And tptacek is arguing secret (symmetric) key is preferable: [https://news.ycombinator.com/item?id=13866983](https://news.ycombinator.com/item?id=13866983)

<comment><USER5> Symmetric signature is simpler, leaner (in message size overhead), faster and more secure (by virtue of it being simpler).

But there are still cases where you would choose asymmetric signatures over symmetric signature, due to the very essence of it being _asymmetric_.

The rule of thumb is that when you want to produce a cryptographic token that will be consumed by parties which you don't trust, you should use an asymmetric signature. Realistically speaking, the untrusted party could (and very often should) be almost any other service inside your own company. If you let symmetric keys spread around, you should treat them as good as if they've been leaked.

There is an alternative that if you're able to (and willing to) manage shared secrets through a safe out-of-band channel (e.g. deriving from client secrets).

</comment></comment></comment><comment><USER36> So JWT is bad because there are bad implementations and there are dumb people who shoot their feet^W^W^Wdon't force alg. Seems like doing software development for 13 years leads to serious problems with logic. There is also confusion between sessions and session storage. Meh..

</comment><comment><USER37> This post says "it's insecure if you do it wrong".

Well.....

<comment><USER23> I hear where you're coming from... but this is also the bane of developer existence. We all have to accept that, every year, tens of thousands of new developers looking for jobs enter the market. There's such a demand for developers that these people _get jobs._ So footguns, as much as we like to play high-and-mighty and say, "well, duh, don't shoot yourself in the foot" are a real, existential risk to a lot of companies.

<comment><USER38> I was under the impression that newly minted developers would use existing libraries and frameworks, which have already take security into account.

<comment><USER39> The article points out that many popular libraries have vulnerabilities and unsafe defaults.

<comment><USER40> Which to me says that relying on there not being any footguns is wishful thinking. The better recourse, to my mind, is to stress the need for mentorship, so people learn to proactively look out for traps.

</comment></comment></comment></comment></comment><comment><USER41> One advantage I think not mentioned by some of the linked articles is that the JWT's claims are readable on the client.

It's a pretty good plus, for me: no additional round-trips to the server to grab key user details, which can be put into claims, or check access levels (via roles, permissions, or other types of claim).

This doesn't discount the disadvantages, of course.. I think as with everything it's a case of the right tool for the job. "Depends on the use case".

<comment><USER42> Out of interest, do you check the authenticity and integrity of the JWT on the client side?

<comment><USER41> We provide an endpoint to check validity with the server, but haven't used it too often. Anything "reasonably sensitive" (or more) doesn't depend on anything like this client-side security.

But, if you're just hiding an additional Delete button on a page based on claims, this comes in handy.

(Edit: in one case, we've used asymmetric keys, i.e. public key so everyone can check integrity. This was a very different use-case to most web apps, though. Overall I'd say if you're carefully checking integrity of something in client-side JS to do something, I think that's probably the wrong approach)

<comment><USER16> That's exactly what is useful for. Of course access to a resource is determined server-side; JWT simply allows you to adjust the UI to the permissions the user has without any additional calls. If the user changes the JWT he has client-side, he will just get a broken delete button (the server will reject a JWT that has been tampered with).

</comment></comment></comment></comment><comment><USER43> Is using none a bit like using http instead of https? The standards support it, but it's 2017 so we shouldn't do it.

What I like about JWT's concept is it's completely distributed authorisation: there's no call to a central identity provider. Thus a SPA can pull initial security info from its server, and then fire out requests to different APIs. As long as the API endpoints have the SPA server's public key, they can verify everything without calling it or another central server.

Having said that, I'm not able to discern whether it's secure enough to be workable, so I only know to mandate a list of good algorithms on the API endpoints and to use SSL :) I'll have to read about this session stuff.

EDIT: I wonder if in bigger projects, a message bus or in-memory cache could signal a token blacklist once the user logs/times out of the original server? Or as some others have said, just have short expiry times and ping the SPA server for new tokens every couple of minutes.

</comment><comment><USER44> I use JWT in a couple of projects and it never once occurred to me to let the client decide the algorithm. I am not sure what use-case would necessitate something like that.

<comment><USER45> Guess that shouldn't be in the spec then.

</comment></comment><comment><USER46> Can anyone think of some criticism for simply storing an API key and secret in localstorage for a web client? It's 50% bridging the gap between using cookies and a normal API and 50% simplifying frontends. The scheme I'm currently using on a project goes like this:

1\. Web client ("offline-first" SPA app) hits HTTPS backend in with username and password

2\. Web client receives a a generated API key and secret, which expires in a week/month/whatever.

3\. That API key and secret gets stored in localstorage on the client-side by the web app for future use (as long as they're logged in)

4\. Web client includes the API key and header in requests to the HTTPS backend of the app.

Of course, there are more specifics that could be added like device fingerprinting, invaliding old web-created tokens when a new one is created, and classifying api keys/secrets to certain devices, but I think those things are ancillary.

This is obviously very very close to what a cookie would be, and the only way I could see it going catastrophically wrong is the browser being compromised (whether the vector is XSS, or some other leaky surface on the user's computer). Regular cookies and JWT have the same issues.

I can't think of a failure mode that's any worse than HTTPS cookies or JWT, and it is dead simple. I've really been trying to find some flaws in that plan lately but I can't.

<comment><USER47> Perhaps I am missing something but I really don't see the point of storing it in localStorage or sessionStorage over cookies what so ever.

1\. You have to write code to provide the authentication values in all requests.

2\. The GET request for the initial page render can't possibly be authenticated.

Why not cookies? Other than that I agree. I really don't see the point of following the JWT spec or using an implementation of it when it has been shown that these implementations are poor (problems with none algorithm & asymmetric keys).

Fundamentally, what we are talking about is simply a claimed identity, verified and signed by your backend. This is a sound principle. Just implement that and your attack surface is considerably smaller.

<comment><USER46> The reason I wanted to try this scheme was to finally remove the little difference in authentication method between web frontend and commandline/mobile API client...

OWASP says not to do it ([https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#L...](https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Local_Storage_.28a.k.a._Offline_Storage.2C_Web_Storage.29)) but the stated reasons are kind of vague/I'm not sure the reasoning is sound.

If someone has physical access to the machine, all bets are off, and if a XSS vuln happens, pretty sure people can get whatever information they're looking for (including the cookie) anyway. The only real objection was the inability to restrict to HTTPS (path based, everything is just based on same origin regardless of scheme I think), however same origin policy still applies like normal.

I wasn't trying to recommend localstorage over cookies, more like just trying to see if there's any huge blindspot I was missing, everywhere I look says not to do this, but the reasons were never very satisfying.

</comment></comment></comment><comment><USER33> I think that JSON Web Tokens (like most things involving JSON) are ill- thought-out, and they can definitely be a bit of a foot-gun, but they are also useful.

I do take issue with the idea that they're not good for stateless authentication: I think they're great when used as short-lived authentication tokens (which don't require serve state) with accompanying long-lived refresh tokens (which do require server state). E.g. a system in which auth tokens are good for an hour and refresh tokens are good for longer (and a refresh token can be refreshed) offer a pleasing user experience (in the normal case, one need never log back on) while also preserving security (revocation takes at most an hour to come into effect). The business gets to make the economic decision about the tradeoffs between risk and cost, deciding whether auth tokens should last for a day, an hour, a minute or a second. I don't think this is 'congratulations, you've reinvented stateful sessions'; rather, it's a well-designed system.

I do wish that JWTs had been better designed, and I wish that folks didn't have to be so careful using the libraries which support them.

</comment><comment><USER26> >> A lot of developers try to use JWT to avoid server-side storage for sessions.

This is based on what? Sounds like he just made it up. His other claims does not look sound to much more either. I would like to see a more in-depth analysis on the subject, this all looks very hand-wavy to me.

<comment><USER48> > This is based on what?

Based on the entire reason JWT is even a thing? Developers love to believe every app they build is going to run at the scale of Facebook to the power of Google times Twitter, and thus needs to run on 10,000 Docker instances spread across 15 data centres around the globe (and soon, one on the moon!).

Relying on server-side sessions is "terrible" because you have to talk to the backend, and you need to keep the data synchronised in a manner that all 10,000 Docker instances can read/write to it instantly. So instead, a new concept was devised, whereby you use these stateless tokens that don't rely on the same server after issuing.

Of course, it's impossible to invalidate them individually, and they're either insecure (available to JS) or stored in a cookie, and thus sent with every request, which means, due to their larger size than regular session cookies, _more_ data on each request.

So.. that. That is what it's based on.

Edit: added missed word "same".

<comment><USER43> I wouldn't say it's impossible to invalidate them individually. It's certainly more effort, and it's probably better to have short-lived session tokens and refreshing, but I think it can be done.

E.g. what about a message bus that publishes an invalid token message that is subscribed to by the API-providing systems, so they can maintain a prematurely-expired tokens list?

On the keeping info in Javascript vs keeping it in a cookie issue, I don't understand that so well. If you made the token a private member of an object that was responsible for the calls, would that help? Then no code could access it?

<comment><USER48> > I wouldn't say it's impossible to invalidate them individually

It's impossible to invalidate individual "stateless" JWT's.

If you have a server-side "blacklist", guess what: you're not stateless any more, because you still need to keep data in sync, and now you're tempted to allow some otherwise unacceptable delay for sync, giving a potential attacker _more_ time with a stolen JWT. Plus, you know, defeating the whole purpose of using JWTs (being stateless).

> On the keeping info in Javascript vs keeping it in a cookie issue, I don't > understand that so well.

Cookies can be set HTTP only. They're sent to the browser, and it will send them back when making requests as per usual, but they're not exposed to JavaScript, at all. There is 0 way for malicious (or non malicious) client side code to see these cookies, thus 0 way for malicious javascript to steal one used as a session cookie.

> If you made the token a private member of an object

If the data can be read from the network by _your_ JavaScript, it can be read from the network by _their_ JavaScript.

<comment><USER43> (Feel free to bail on this at any time if my questions/suggestions become tiresome :))

> If you have a server-side "blacklist", guess what: you're not stateless any > more, because you still need to keep data in sync, and now you're tempted to > allow some otherwise unacceptable delay for sync, giving a potential > attacker more time with a stolen JWT. Plus, you know, defeating the whole > purpose of using JWTs (being stateless).

While I agree that it's no longer stateless, JWT's still really useful in terms of not needing a centralised auth/auth provider that everyone has to hit to see if I am who I say I am and whether I'm allowed to call an API. And a message bus is a pretty good compromise between the extremes of big wide systems that share state and microservices that don't talk to anything else.

> Cookies can be set HTTP only ... session cookie. Thanks - I get what you're > saying.

> If the data can be read from the network by your JavaScript, it can be read > from the network by their JavaScript. Yeah. I think I see what you mean. > Assuming you don't mean literally "reading data from the network", as I > assume the problem isn't the network access but the access to the security > info, are you saying that hostile Javascript on the page can read everything > and call everything that legitimate Javascript can?

If so, I can't tell the difference between that and - say - a CSRF token, which presumably can also be read by "their" Javascript? How does anything work if you have that mentality?

<comment><USER48> > not needing a centralised auth/auth provider

The vast majority of people don't need the scale that is difficult to achieve with regular server-side sessions, and that JWT claims to "solve". They add complexity to solve a problem most people don't have.

> I can't tell the difference between that and - say - a CSRF token, which > presumably can also be read by "their" Javascript

CSRF is about e.g. making a user's browser make a form submission that results in a request which is malicious in some way. CSRF Tokens are embedded in each legitimate form to ensure that the submission received came from a form you control.

If the attacker has JavaScript access to your page, CSRF is not your problem, so CSRF tokens can't help you.

<comment><USER43> > The vast majority of people don't need the scale that is difficult to > achieve with regular server-side sessions, and that JWT claims to "solve". > They add complexity to solve a problem most people don't have.

Not really talking about sessions, but I think I see what you're saying.

> If the attacker has JavaScript access to your page, CSRF is not your > problem, so CSRF tokens can't help you.

I agree. I'm trying to understand what you were saying about whatever your Javascript has access to, their Javascript does as well. Why should this be a criticism of JWT and not CSRF?

<comment><USER48> > Not really talking about sessions

Well, mostly a JWT lets you know the user that is signed in.

A server-side session generally does the same thing, but _can_ be used to store larger amounts of data.

> I'm trying to understand what you were saying about whatever your Javascript > has access to, their Javascript does as well. Why should this be a criticism > of JWT and not CSRF?

They're unrelated attack vectors.

CSRF is about bad actors producing links and/or forms on a _different_ site to your own, that a legitimate user clicks/submits (either through social engineering or some kind of javascript in _their_ page) causing them to make a request to _your_ server. A CSRF token prevents this because it ensures that form submission requests have come from a form hosted on your server.

In the situation where we're worried about what someone else's JavaScript has access to, it means their javascript is already loaded into your page: a vulnerability with poorly escaped user content, a rogue browser extension, a malicious or compromised CDN, etc.

In that situation, CSRF is irrelevant. The CS in CSRF is "Cross Site" \- this is no longer cross site, as the script is running in the context of your own page.

So in this situation nothing we do can prevent them from making requests within the current user session.

But what we _can_ prevent them from doing, is stealing a user identifying token: e.g. a session cookie, by marking it HTTP Only, so the JS environment doesn't see it.

JWT's accessed over XHR/etc and stored in local storage are available to any malicious scripts running, meaning they can grab the user's JWT and send it off to their own server, allowing them to make requests as the user.

If you send JWT's as cookies and mark them as HTTP only, you've defeated the "don't send session cookies with every request" goal of JWT, _and_ the cookie will be bigger than most session cookies.

<comment><USER43> > Well, mostly a JWT lets you know the user that is signed in. In my case I'm > happy to use non-JWT methods to hold a user's session information (e.g. an > HTTP-only cookie) and just want JWT to authenticate with other systems' APIs > without needing to centralise auth/auth.

> They're unrelated attack vectors. Good point. I guess I more just meant that > what can malicious Javascript do with endpoints protected by JWT that it > can't do with endpoints protected another way.

> JWT's accessed over XHR/etc and stored in local storage are available to any > malicious scripts running, meaning they can grab the user's JWT and send it > off to their own server, allowing them to make requests as the user.

I guess this answers the above question: the difference isn't in what can be executed in the browser, but what can be shipped to a different server to be used in attacks from there.

To mitigate that, then, how's this setup:

1) User's session is maintained in HTTP-only cookies. 2) Browser can use (1) to request a JWT token (and a refresh key) to hit a 3rd-party API endpoint. The token is valid for 5 minutes. 3) Browser can use the refresh key from (2) to request another JWT token.

Does that pretty much bring it up to parity with using cookies everywhere, while keeping the goal of noncentral auth/auth?

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER49> If you are interested in a Ruby library for signing and verifying a token containing a simple payload, take a look at our Slosilo library:

[https://github.com/conjurinc/slosilo#signing](https://github.com/conjurinc/slosilo#signing)

We use this library to store a signed username. Nothing more than that, just a username in a signed, expiring token. No `alg` field or any other options.

The Slosilo code has been subjected to a professional crytographic audit, so it's safe for you to use. Unfortunately, without an NDA, we can't show you the audit report, that's just how these things work. The only audit finding was a recommendation that we switch to `AES-256-GCM`, which we did in Slosilo 2.0, November 2014.

</comment><comment><USER50> JWT is to HTTP Basic what OAuth2 is to logging in.

Auth doesn't have to be complicated to be effective.

Developers know/care very little about information security and a lot about following "standards" and "best practices."

Google and Facebook have learned over the years to take advantage of this.

<comment><USER51> > Google and Facebook have learned over the years to take advantage of this.

In what way?

<comment><USER50> If authentication is too complicated for the average developer to understand, other businesses will become more willing to use Goog & FB as identity providers.

There's also generally a lot of FUD around authentication because most web developers don't understand information security well enough to weigh the pros and cons, so technical discussions usually devolve into, "Google uses it, so it must be solid."

</comment></comment></comment><comment><USER52> Should we use Hawk + Oz[1]?

[1] [https://hueniverse.com/2015/09/19/auth-to-see-the-wizard- or-...](https://hueniverse.com/2015/09/19/auth-to-see-the-wizard-or-i-wrote- an-oauth-replacement/)

</comment><comment><USER53> Well how about that; I had no idea there was a specific standard for this type of thing nor did I realize the client could specifically request a _type_ of algorithm to be used. That seems incredibly short sighted; why wouldn't you let the server handle that and make the algorithm completely transparent?

> Just use cookies over HTTPS.

Maybe it's because of my experience working in environments where cookies were disabled but I just try to avoid them where possible nowadays for my authentication handling. Instead of storing the equivalent of a session / token id in a cookie I just store it in sessionStorage and include that in requests.

<comment><USER54> Yes, this prevents CSRF without tokens too.

<comment><USER55> ... and causes another security issue in the process, namely the ability to steal session credentials after an XSS attack.

Trading in one security issue for another makes no sense. Just implement the _correct_ mitigation against CSRF attacks; namely, CSRF tokens.

<comment><USER54> Yes but you can now concentrate make yourself XSS proof right; with an XSS you can still get someones cookies... unless you are talking HttpOnly. But we are probably talking single page webapps here anyway.

<comment><AUTHOR> > unless you are talking HttpOnly

Which is precisely what the blog post that was hyperlinked in the sentence you were responding to was advocating.

<comment><USER54> If there are no XSS attacks against ReactJS then both ways protect me from both CSRF and XSS right?

If you can show ReactJS XSS then I may need to reconsider.

</comment></comment></comment></comment></comment></comment><comment><USER56> This article jumps straight from introduction to conclusion. Like, "there have been big issues in the past and the available algorithms are questionable because [missing part] so don't use it".

It hasn't quite convinced me.

</comment><comment><USER57> so if JWTs are supposed to be avoided, what's a better alternative? cookies? (does that not open another can of worms?)

</comment><comment><USER58> Personally, I've hand-written a few JWT implementations, and usually avoid even using a few of the "standards" often avoiding even reading the header. This is because usually I've used them for internal systems calling other systems.

If you avoid reading the header, and have standard policy on signatures, combined with very short lived tokens (max 1m) combined with https, there is minimal risk.

Yes, the standard is flawed, that doesn't mean the structure is inherently bad, or that using said design is bad by itself.

</comment><comment><USER59> Can anyone comment if TLS Token Binding [0] does solve some subset of problems usually solved with JWT?

It seems to be scheduled for implementation in several clients [1].

[0]: [https://tools.ietf.org/html/draft-ietf-tokbind- protocol-13](https://tools.ietf.org/html/draft-ietf-tokbind-protocol-13)

[1]: [https://www.chromestatus.com/feature/5097603234529280](https://www.chromestatus.com/feature/5097603234529280)

</comment><comment><USER60> OT but I need a wake-up call here. Upon login I'm sending back a generated UUID tied to the account and saves it as a cookie in the client. What's wrong with this approach?

<comment><USER61> That approach is generally how many web platforms do their server-side session management. As with anything that is more or less home-grown (vs using that platform session implementation), you'll want to ask yourself: 1) how easy can my UUID be spoofed? 2) can i revoke/invalidate/logout my UUID session

</comment></comment><comment><USER62> Except for the fact that JWT's are fairly ubiquitous at this point. Depending on the needs of an API, the timeout is the big point. Banking apps generally timeout pretty quickly...as in 30-60 seconds. Mobile apps vary in how long a token stays valid, but many keep it short.

Given that tokens are signed and you can't really unwrap them on the client side without having "more information", I'd say this article is long on scare- tactics and short on real-life usage scenarios.

</comment><comment><USER17> "Just use cookies over HTTPS [instead of JWT]" is weird advice. I mean, JWT goes… inside… things like cookies. (or the Authorization header in APIs, of course)

<comment><USER28> This drives me nuts. To expand on your point, there are a number of separate, debatable design decisions that seem to get conflated all the time:

* Transport: how the session ID or token is shipped between clients and servers (authorization header, cookie headers, or payload).

* Storage: how the session ID or token is stored on clients (cookies, localStorage, sessionStorage, or in memory).

* Statefulness: whether to use a stateless token (with or without a revocation list) or a stateful, server-side session.

* Encryption and/or signing

* Structure/standardization

Examples:

* JWT generates structured, stateless tokens that are signed—and optionally encrypted (JWE)—with the implementor's choice of algorithm. The tokens can be transported and stored by any mechanisms.

* Rack::Session::Cookie (in Ruby) generates unstructured, stateless tokens that are signed—not encrypted—with HMAC. The tokens are transported and stored as cookies.

* Rack::Session::Pool (also in Ruby) maintains an in-memory store of unstructured, stateful sessions. Unsigned and unencrypted session IDs are transported and stored as cookies.

The point being that you can really mix and match. You can even send a session ID in a header and store it as a non-HttpOnly-cookie on the client. Anything goes!

</comment></comment><comment><USER63> What I've gathered from this post is that the tech community ought to spend more time promoting JWT best practices because misuse can lead to bad times

</comment><comment><USER64> No they shouldn't, and stop spreading FUD. First of all, the headline has a blanket statement that they should be avoided, whereas the article says don't use them for sessions (which I agree with). There are many other uses for JWT that aren't sessions. The vulnerabilities the article brings up were quickly patched in all major libraries quite a while ago.

</comment><comment><USER65> This is my opinion about the article:

1\. Yes looks like the author is criticizing some implementations libraries: The solution is look carefully to choose your lib. And the advice for every library is to not allow weak encryption algos and off course "none" as an option. This is the kind of problem of services still using md5 to store passwords.

2\. The JWT standard is simple and like the other standards has pitfalls but still usable: I think the author comes along with the use instead in some way of promoting libsodium crypto lib, well fine but the thing is to explain the alternatives in the particular case. So sessions are good for webapps the kind of Rails, Laravel etc, but what is the path when you need independent services? Then you have OAuth1, OAuth2 and JWT, which again every case has it's own purposes. Someone said that JWT are difficult. Really? I don't think so, in OAuth you need to understand very well the grant types to choose the appropriate. Also the reference of "Stop using JWT for sessions" is bad I think. First everybody knows that blacklists are bad is preferable to use simple whitelist, then problem with your server, hey no matter what implementation you use if your server is down you service is down.

So to abbreviate the problem itself is about the libs and the lack of implementation information on the spec, but I don't think is that bad standard.

</comment><comment><USER16> I would have expected a more in-depth analysis of JWT compared to other techniques. As much as I appreciate the effort to warn people away from bad security practices, JWT is not as a technique fundementally broken.

> JSON Web Signatures Makes Forgery Trivial

> 1\. Send a header that specifies the "none" algorithm be used

Most JWT libraries require you to explicitly allow the _none_ algorithm. I had to set a very explicit system property to even get the library I am using to accept none! Even so, anyone implementing JWT should make sure that only the algorithms actually used are accepted.

> 2\. Send a header that specifies the "HS256" algorithm when the application > normally signs messages with an RSA public key.

Being able to use the public RSA key used to sign an RS256 JWT as the key for a (forged) HS256 token requires the server to accept both RS256 and HS256, and (critically) to be able to use a key configured for RSA assymetric signing to validate HMAC SHA256 signatures. I have not been able to reproduce this latter bug with the library I am using, but even if it did, I still check the algorithm field beforehand: if a token claims it is HS256 signed, I use the (private) key configured for that (if HMAC SHA256 signing is allowed in my application); if it is RS256 signed, I use the (public) key configured for that. The library I use doesn't even get a choice in this; it either receives a JWT that claims to be RS256 together with a RSA 2048 public key, or it gets a JWT that claims to be HS256 together with a private signing key exlcusively used for HS256.

The code preforming those checks between the REST-call receiving the JWT and the JWT library is trivial.

This is all _assuming_ that you would place a service configured to accept both HS256 and RS256 tokens at the same time in production.

As with any security standard: don't use crap libraries; do your research; test your service for common vulnarabilities; follow recommendations made by experts; and don't deploy techniques you don't quite grasp in production software.

> JSON Web Encryption is a Foot-Gun

So is TLS, or hashing passwords. Security is hard and requires a lot of reading and grokking (but it is not too hard for any moderately experienced software engineer).

> TL;DR

Really? 'Too long; didn't read' for a handful of paragraphs? I'll grant the author this much; anyone who can't muster the attention span to read that much text without groping around for a single sentence summary shouldn't be implementing (any!) security standards.

JSON Web Token is a well-documented accessible security standard with a lot of comprehensive information available. As with any technique, there are caveats, but these caveats do not discredit the technique as a whole.

</comment><comment><USER54> Lock the encryption to RS512 and the standard is fine. I do a test against that and I also include a key relevant to and content I send with the token. This make the signature per request and considerably more difficult to forge. Maybe using JWTs for sessions is bad, using them for APIs is awesome with the specific caveats.

</comment><comment><USER66> Title misleading: JSON Web tokens should be avoided <FOR PASSING TO THE USER AS A SESSION KEY>

</comment><comment><USER67> So, what should one should use then? However, It's insecure with a _bad_ client, right? Beacuse I was going to use http+JWT for microservices communication an internal network, would that be a problem? any tips on what to switch?

<comment><USER16> JWT is fine. Just lock down the library you chose as much as possible (only accept one algorithm for instance).

</comment></comment><comment><USER68> I suspect there are developers out there who haven't kept their secret as secret as it ought to be.

The leak of a JWT secret allows for easier and more severe attacks than the leak of many other secrets.

</comment><comment><USER69> Token invalidation being an issue depends on the app.

Checking against a blacklist / some secondary measure may only be required for important actions such as changing password, checking out, etc.

</comment><comment><USER70> When creating Universal JS apps, I usually store a user token as a cookie vs. local storage. I don't think you can server-side render content if you're using local storage.

</comment><comment><USER71> It depends on the security model, but in the long term I think sessions are the way to go. It becomes much easier to differentiate the different clients that connects to the API

</comment><comment><USER72> Their suggestion to use secret_box is dangerous. It neglects to mention you still need to MAC the content, lest you leave open malleability attacks.

</comment><comment><USER73> JWT is bad, signed tokens are fine. Session cookies suck and don't scale. Just copy code of MessageVerifier from Rails, it's simple.

<comment><USER28> * MessageVerifier defaults to SHA1. That hasn't been a good default for a few years now.

* It doesn't support expiry as a claim; you have to check it against the current time manually, and factor in leeway if you want that. Because no one ever screwed up a timestamp check.

* It doesn't support any other verifiable claims, for that matter, so if you want to add e.g. issuer and issued-at, you'll have to do so manually.

* If you're not writing a Rails app, you have to pull in ActiveSupport... or copy code, as you suggest, which seems bad for other reasons. Surely maintaining your own crypto fork is almost as bad as writing your own crypto in the first place?

* To the best of my knowledge, ruby-jwt has not suffered either of the two JWT vulnerabilities discussed in this thread.

Finally, why is this "simple":

        @verifier = ActiveSupport::MessageVerifier.new('s3Krit', digest: 'SHA256')

        cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])

But this is "bad":

        payload = { sub: @user.id, exp: Time.now.to_i + 1_209_600 }

        cookies[:remember_me] = JWT.encode(payload, 's3Krit', 'HS256')

They seem fairly equivalent to me?

<comment><USER73> 1\. [https://github.com/rails/rails/blob/master/activesupport/lib...](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/message_verifier.rb) feel free to change the default, if you find enough reasons for rails team (beware: it's hard).

2\. it doesn't, internal session class does and IMO most apps do not need expire claim.

3\. Just put issuer/issued_at/whatever in your object

4\. I suggest to look at messageverifier and do your own (and use sha256 hmac). Why? Lets consider 50 lines of code not "maintaining your crypto fork" but merely helpers.

5\. JWT has more LOC inside, say header payload is just useless. I believe having OpenSSL::HMAC helpers is better and simple enough to not do it wrong

<comment><USER28> Thanks for your response.

> 2\. it doesn't, internal session class does and IMO most apps do not need > expire claim.

If you're generating a token to send to an SPA or native app, you can't rely on any other expiration mechanism. It needs to be embedded in the token or stored server-side in a database-backed session or what have you.

> 3\. Just put issuer/issued_at/whatever in your object

You're missing the point that these features would require additional SLOC to verify the "claims."

> 4\. I suggest to look at messageverifier and do your own (and use sha256 > hmac). Why? Lets consider 50 lines of code not "maintaining your crypto > fork" but merely helpers.

By this logic, ruby-jwt isn't crypto, just helpers. It seems to be frowned upon simply because it includes additional features some people may not need, and those features and alternative signing methods require more SLOC than your presumed "optimal" implementation. Do you see no value in a flexible, reusable library?

> 5\. JWT has more LOC inside, say header payload is just useless. I believe > having OpenSSL::HMAC helpers is better and simple enough to not do it wrong

How can critics justify the position that people should write their own OpenSSL::HMAC helpers because they can't correctly call the JWT helpers?

</comment></comment></comment></comment><comment><USER74> This article has little substance. The arguments don't apply to JWT, it just mentions badly done implementations and an insecure option that obviously nobody would turn on.

What else are we going to use? JWT is basically the simplest token protocol possible that maintains antiforgery properties. It's great that somebody standardized something that most API's were using anyways. If you give anyone that knows crypto the task of making a simple token protocol they will come up with JWT over and over.

</comment><comment><USER75> feels like a troll piece

</comment><comment><USER76> JWT can help make a system look more secure, for example you store userid, email some token in session store and a customer goes poking around and tells everyone that he can see that inside the inspector (his data), if you obfuscate it with JWT you eliminate false positives but it doesn't make it anymore secure.</comment>


Email based PGP encrypted chat - <AUTHOR> http://delta.chat <comment><USER2> While this does seem interesting (minus all the issues with PGP-encypted email), I did find this odd claim about PFS[1]:

> No, OpenPGP doesn't support Perfect Forward Secrecy. Perfect Forward Secrecy > works session-oriented, but E-Mail is asynchronous by nature and often used > from multiple devices independently.

Yes, OpenPGP doesn't support PFS. But it's untrue that you need a session- based protocol to use PFS. The Signal protocol (and entire Noise family of protocols including things like WireGuard) beg to disagree.

No, the reason OpenPGP doesn't support PFS is that the design is fundamentally based around long-term keys -- even with separate short-lived subkeys you couldn't practially emulate PFS with PGP.

[1]: [https://delta.chat/en/help#does-delta-chat-support- perfect-f...](https://delta.chat/en/help#does-delta-chat-support-perfect- forward-secrecy)

<comment><USER3> There is [https://tools.ietf.org/html/draft-brown-pgp- pfs-03](https://tools.ietf.org/html/draft-brown-pgp-pfs-03) but I do not think that anyone implements it. Regardless I think that not having PFS is not necessarily a drawback.

> The Signal protocol (and entire Noise family of protocols including things > like WireGuard) beg to disagree.

These use a dedicated key per device rather than per season.

<comment><USER2> The proposal you linked is effectively a more formal version of the subkey PFS scheme I alluded to, though it looks like it tries to solve some of the issue with subkeys that make them not a good fit for PFS (though one issue I've had is that subkeys appear to be referenced by their index rather than their keyid, so deleting and replacing them can give you confusing messages on decryption).

> These use a dedicated key per device rather than per season.

For identity, not for encryption (in the PGP world this is the difference between the root key and subkeys -- though the root key cannot be used for encryption in this analogy).

The keys used for encryption are rotated incredibly regularly (for each message in the Signal case, and every two minutes for WireGuard). That is what PFS looks like in asynchronous protocols.

</comment></comment></comment><comment><USER4> If you care about metadata encryption or being selected for targeted attacks this is horrible. The nsa and other actors that inspect email traffic for non- legal reasons love PGP [1]. You can't encrypt metadata with it, it doesn't matter what you do, the MTA's and other mail servers add header fields tha not only uniquely identify sender and recipient but details about the conversation and attachments.

Email was insecure, but ovet decades features were piled onto it. Then people started trying to secure it. Now it's a dangerous protocol, that leaves users with a false sense of security. There is no way to properly secure email, you can improve email security but you should never use it in place of something modern.

I am routinely shocked about how modern tech companies treat email. One finance related tech company was shocked when I refused to send PII to authenticate myself in order to make account changes over unencrypted email. At least this chat thing uses PGP.

I am at a point where I am thinking of conspiracy theories about all the chat protocols these days. Either they have a small but critical flaw in the confidentiality property or they have non-obvious metadata collection that can be used to identify targets for additional targeted attacks against their device. I still haven't found a chat app/protocol I can trust.

[1] [https://www.theregister.co.uk/2016/01/27/nsa_loves_it_when_y...](https://www.theregister.co.uk/2016/01/27/nsa_loves_it_when_you_use_pgp/)

<comment><USER5> > MTA's and other mail servers add header fields tha not only uniquely > identify sender and recipient but details about the conversation and > attachments.

That really depends on how the server is configured. If the servers used are under the participants' control, then other than Received headers, nothing else should be exposed if the client does not include or encrypts the headers in addition to the body.

So, if the sender were to send an email using the following SMTP session:

      EHLO random_string
      MAIL FROM: <random.email@addr>
      RCPT TO: <email@example.com>
      DATA
      <PGP BLOCK>
      .

then other than the received headers that are added by the MTAs, it wouldn't expose much information at all.

<comment><AUTHOR> it should be less than that, if the servers are controlled by competent admins - everything after STARTTLS should be garbage to beholder.

<comment><USER4> The MTAs are hostile,they are the threat. Email can traverse multiple servers that have nothing to do with the sender or recipient.

Competency won't prevent them from allowing backdoor access or sniffing and selling metadata.

<comment><AUTHOR> MTAs, if configured correctly, do not talk to anything outside your network that is not specified by MX DNS records. Unless we are talking about emails traversing internal networks and even then competent admins do not transmit data in cleartext, so sniffing is out of question. Of course, some metadata is always leaked, but that is the reality of most internet protocols, HTTPs notwithstanding. Now if we're talking about backdoors, it's a game over in any scenario.

</comment></comment></comment></comment></comment><comment><USER6> I love the general idea of this. It is a way of introducing a chat application that is not controlled by some single behemoth. It can take advantage of other people's servers (via email), so there's no real cost associated with it like there would be trying to stand up a server for handling nearly any other protocol. I'm just not sold on PGP. I don't see a point of this as long as metadata leaks.

I wonder if you could do the same, but use usenet. Most usenet providers allow encrypted connections to their servers... But then people would have to have a subscription to usenet.

<comment><USER7> An alternative for this is Matrix.

See: [https://matrix.org](https://matrix.org)

</comment></comment><comment><USER8> I really like the idea of this. For _some_ applications it would be very useful assuming the implementation is up to it. Unfortunately, just reading the FAQ a see a few red flags. It doesn't allow importing encrypted keys. This is an automatic "nope" for me. Authentication is as big an issue as encryption, so I need to generate my own keys. But I'm not about to upload an unencrypted key to my phone.

Also, they kind of avoid talking about the _very_ important issue that who you are talking to is not secret. Like I said, IMHO for some applications it's not a big deal. But for some applications it is a _huge_ deal and it's pretty important to warn people up front.

This is not a _replacement_ for Signal. Possibly with some work it could be useful in limited contexts. However it is important to understand that it _can 't_ be a replacement for Signal in general.

<comment><USER9> > Also, they kind of avoid talking about the very important issue that who you > are talking to is not secret.

Which chat apps fix this? I'm sure the people operating signal know who you talk to.

<comment><USER2> For Signal, sealed sender _in theory_ makes some progress towards fixing this problem[1] but given the service fundamentally uses a central server, you could pretty easily figure out who is messaging who.

There was an experimental chat application called Ricochet[2] which used Tor hidden services to anonymise users' social graphs, but unfortunately that project is no longer developed for quite a while. Pond[3] was also a similar system (though it was designed to solve the email problem and also aimed to solve some of the timing attacks against Tor by being a delayed-message protocol).

I personally use Matrix[4] on my own homesever which appears to be the most privacy-preserving choice these days -- only the homeservers involved in a conversation ever see the messages. Unfortunately a lot of people use matrix.org as their homeserver (meaning they in theory have everyone's social graph) but for chats with most of my family and friends that isn't a problem (they are either on my homeserver or on their own).

[1]: [https://signal.org/blog/sealed-sender/](https://signal.org/blog/sealed- sender/) [2]: [https://ricochet.im/](https://ricochet.im/) [3]: [https://github.com/agl/pond](https://github.com/agl/pond) [4]: [https://matrix.org/](https://matrix.org/)

<comment><USER10> > but given the service fundamentally uses a central server, you could pretty > easily figure out who is messaging who.

How?

In Signal's design nobody ends up knowing this except the sender and recipient.

As a Matrix enthusiast with their own "Homeserver" what you're doing is basically like dressing in head-to-foot desert camouflage gear to stand in Times Square. I guess it does do something, but maybe not what you think it does.

<comment><USER9> >In Signal's design nobody ends up knowing this except the sender and recipient.

I'd like to see an explanation for that, it sounds magical.

<comment><USER10> Signal can't avoid learning who a message is for (the recipient) in order to deliver it but they can easily avoid learning the sender by not asking. The recipient will learn the sender by decrypting the message, in which the sender proved who they actually are.

The remaining problem for Signal was enabling this without spam. To do that recipients choose whether to tell everybody, or nobody or just people they know (the default) a key. Proving knowledge of this key is enough to send messages to that recipient. If you get messages you don't want, just block that sender, your key is rotated and they won't know the new key.

[https://signal.org/blog/sealed-sender/](https://signal.org/blog/sealed- sender/)

</comment></comment></comment></comment></comment></comment><comment><USER11> This is an interesting proposal. However, there is still a small flaw to privacy, in respects to you making an account with an email attached. Many of us here will know how to make an anonymous email, but for new people and/or people who need to talk in suppressive regimes (that would be able to track back the account to the email it was created with), wouldn't be such a great idea. Although they will not be able to read the contents of the conversation because of the PGP encryption, in many countries, having suspicion of this can lead to torture.

Therefore, I still believe that Briar is the strongest in this. Each individual message has a different key, so if one key is compromised the whole conversation isn't exposed. Furthermore, the signup process us just a username and password - no need for email or phone number. Thus, making it far harder for regimes to track back to the source, especially if they are using Tor when creating the account and when using the account.

This is not to say that Delta isn't a good idea, I just think that it is very similar to Signal (the main difference being the email signup instead of phone number).

</comment><comment><USER12> I wish push notifications worked better. It's so hard for open source projects. Ideally, a client should be able to, in a standard way, tell a server where to send notifications, maybe provide a key as well, and that's it. No need to register at each individual phone manufacturer etc.

<comment><USER13> Yeah, push notifications are an absolute shitshow.

A standardised push notifications API where you could swap out providers would be such a breath of fresh air.

That being said, the two applications I run that are doing long-polling sockets (Conversations and K-9 Mail) don't really use a lot of power, according to the battery settings screen on my Lineage device

</comment></comment><comment><USER14> I tried this about 2 years ago on an Android and it worked just fine, the problem was I could only use a single email account at a time.

This meant that I could not use work accounts to chat with wlperdonal folks and vice versa via the official work email.

since I don't want to pollute my personal emails with work stuff, that somewhat limited what I could do.

once they fix that, I would be glad to use this quite a bit more.

Edit : looks like they added multiple account Support after all... I will definitely be trying it again today.

</comment><comment><USER15> This is cool! It's simple and clean. I'm wondering how does the initial key exchange work. That seems to be the biggest problem with PGP.

I would recommend giving it a more different look than WhatsApp.

<comment><USER16> Apparently there is a protocol, they name it in the FAQ:

[https://autocrypt.org/](https://autocrypt.org/)

After the second message, if that user is also using an app based on autocrypt, it should be encrypted.

If I understood right it's just a way to asymmetrically exchange keys. Just instead of you manually sending a pubkey or pulling it from a registry like in PGP they do it for you.

<comment><USER15> It seems after installing the app

1\. It logs into email via SMTP / OAuth

2\. It creates a folder called delta chat

3\. The first message sent to the another user is not PGP encrypted but when both users use delta chat the messages are encrypted

If only gmail/yahoo/... supported autocrypt you can communicate with every email user safely, but why would they ? It's a conflict of interest.

Decrypted messages are stored on the client and you can export the keys. Creating a random email address would be an easier way to ensure more privacy I suppose.

Over all the App supports everything WhatsApp does sans VOIP. I wonder how difficult that is ?

<comment><USER16> GMails business model is basically based on scanning your mail.

It should be possible if they can work out how to put WebRTC with transformable streams in there.

It's the most feature complete messenger. Maybe it's possible to hook it up to ProtonMail

</comment></comment></comment></comment><comment><USER17> I expected this to be easy to setup since it's just email. Yet using the exact same credentials my mail client uses fails to connect.

<comment><USER18> Same here - it got stuck at 96% (whatever that means), but it worked when I hit "Log in" the second time.

Strangely, the setup screen doesn't seem to differentiate between "automatic" (i.e. "simple") and "advanced" setup and filling out the fields is necessary for both when using the advanced setup mode.

</comment></comment><comment><USER19> delta chat is nice idea but it is very difficult to make chat like experience as every email provider handles replies and quoting original messages differently

</comment><comment><USER20> Does provides any sort of forward secrecy?

<comment><USER2> No, as mentioned in the FAQ[1]. Though to be fair, this is because of the design of OpenPGP (it's almost anti-PFS by design).

[1]: [https://delta.chat/en/help#does-delta-chat-support- perfect-f...](https://delta.chat/en/help#does-delta-chat-support-perfect- forward-secrecy)

</comment></comment><comment><USER21> Isn't email insecure by design?

<comment><USER22> PGP doesn't hide the fact that you are communicating with someone, but it will keep the content of your conversation pretty private.</comment></comment>


Show HN: Hotcold Typing – Learning Touch Typing Smartly - <AUTHOR> http://hotcoldtyping.com/ <comment><USER2> No Dvorak support? I am disappointed.

<comment><AUTHOR> We will be supporting it in future versions.</comment></comment>


Linear Logic and Linear Algebra (2013) [pdf] - <AUTHOR> http://www.cs.bham.ac.uk/~drg/bll/steve.pdf <comment><USER2> I understand about three out of four of these symbols - which isn't enough to follow this with any rigor. Frustratingly, different texts use different symbols. Please direct me to a glossary of these symbols.</comment>


SEC Moves Ahead With 'Crowdfunding' Proposal - <AUTHOR> http://online.wsj.com/news/articles/SB10001424052702303615304579153463087785476?mod=WSJ_hpp_LEFTTopStories

<comment><AUTHOR> The most interesting bit is: "Wednesday's proposal doesn't require companies to verify that individuals meet income thresholds set by the law, officials said. Instead, the SEC asks for comment on whether verification steps are needed." Potentially receiving funding from a non-accredited investor has been one of the remaining sources of risk to a startup taking crowdfunding.</comment>


Study About IP On The Human Genome Shows That Patents Hindered Innovation - <AUTHOR> http://techdirt.com/articles/20100727/03224210373.shtml <comment><USER2> I guess that's not surprising. It's more surprising to me that anyone allowed patenting of the human genome in the first place. How someone could equate "sequencing" with "inventing" boggles my mind. There are billions of examples of prior art walking around among us, for crying out loud! It's as if whoever "rediscovered" cuneiform writing should have been able to patent it...

<comment><USER3> The patents are for the use of these molecules as drugs in order to treat a disease. That is a very non-obvious and inventive process to figure out which of the 25000 genes in the human body will be useful as a drug - and what the exact composition of that drug should be and how to make it, administer it, etc.

<comment><USER4> I don't believe genome patents require you to show how you've invented a process to use the genome- only the string of letters on a piece of ticker tape.

</comment></comment></comment><comment><USER3> I haven't read the actual study - just the presentation in this link.

However, I would be REALLY hesitant to conclude anything from this other than Celera chose uninteresting things to make patent applications on. The "outcome" for innovation in this study was whether or not a gene test exists, and that is not what Celera was trying to get IP on. They were trying to find drugs or drug targets - and that is a difficult process.

The fraction of good drug targets in the human genome compared to the total number of genes is very, very small.

<comment><USER5> The fraction of good drug targets in the human genome compared to the total number of genes is probably astronomical, but to think that a single gene is going to give you much information is laughable. The number of proteins involved in any given disorder or disease is far too large.

Which, incidentally, is why you shouldn't be able to patent testing for single genes, since that is the most rudimentary example of what genetic testing has to offer.</comment></comment>


Wikileaks Website, Pummeled by Attacks, Loses Home - <AUTHOR> http://www.msnbc.msn.com/id/40455720

<comment><USER2> They're now sitting on bahnhof.net in Stockholm. If they were really getting 10Gb/s inboud DOS on AWS perhaps they just grew tired of paying the AWS fees - 0.10/GB - so $450/hr just in inbound traffic. Maybe now that the biggest media exposure is over they figure they can live with a little worse performance.

</comment><comment><USER3> That is truly a godawful AP article.

Here's the prior discussion: <http://news.ycombinator.com/item?id=1956981>

</comment><comment><USER4> Senators calling hosting companies to have websites shut down? Um, wasn't there something called the rule of law?

<comment><USER5> Don't hyperventilate. Anybody, from a Senator to a high school janitor, can "call a hosting company to have a website shut down". Nobody made Amazon comply.

<comment><USER4> It would be great if you could keep the debate civil. Mr. Lieberman is not just anybody. He is an official of the state with the power to hurt Amazon's business interests in many ways that are not available to a school janitor. But instead of using the great legal and legislative powers and resources he has, he chose to use his personal influence to suppress information he doesn't like.

<comment><USER5> That's my point. Exactly which "legal" or "legislative" powers has Lieberman wielded against Amazon? None. As far as I can tell, he's just bloviating. Senators don't lose the right to bloviate when they're elected.

Rupert Murdoch can harm Amazon's business interests in far worse ways than Joe Lieberman, and with far less accountability.

<comment><USER4> Use the courts or the legislative process is exactly what he should have tried to do. In that case, all the safeguards put in place by the constitution would have been properly applied. People would have looked into whether or not shutting down a media outlet that is critical of the government violates the first ammendment. That's how it should work.

Things should not happen on the personal say so of populist politicians, much less things like shutting down critics of the government. That undermines the rule of law and the separation of powers.

That's my opinion, but judging by the votes you get here, Russia style politics is rather popular in the US as well.

<comment><USER5> You think that it's better for Lieberman to have tried to _legislate away hosting of Wikileaks_ \--- legislation that very well might have passed in this climate --- than for him to have used his "influence" as one of America's least-beloved Senators to shame a multi-billion dollar company that probably planned to jettison Wikileaks anyways?

</comment></comment></comment></comment></comment></comment><comment><USER6> Pardon my ignorance but is there really nothing that can be done to escape DDOS attacks other than simply buying more bandwidth? What stops a criminal entity or government with enough resources from upping the size of the attack even more and prolonging it for months or even years?

<comment><USER7> Nothing... that I can think off. DDOS attacks are horrible for exactly this reason, if you can find the source and kill it as close to home as possible than you have a chance but other than that, wikileaks is in a really bad position right now.

</comment></comment><comment><USER8> You gotta hand it to Wikileaks, they've got balls. But I'm afraid it's all going to be for naught. Nobody likes to be told, let alone admit, their government/banks/military is corrupt. No good will come from any of this because the average person really doesn't give a damn.

<comment><USER9> _Nobody likes to be told, let alone admit, their government/banks/military is corrupt. No good will come from any of this because the average person really doesn't give a damn._

Then....why is this wikileaks business a front-page headlining story pretty much _everywhere_? Doesn't that completely counter your claim?

Further, the only reason people might not want to be told is that they already long knew it. Wikileaks hopefully has something pretty salacious to keep the interest, because thus far the response has been "Wow....is that it? I suspected much worse."

<comment><USER8> _Then....why is this wikileaks business a front-page headlining story pretty much everywhere? Doesn't that completely counter your claim?_

Just because "its on the news" doesn't prove that anybody gives damn. I don't see citizens rallying in favor of Wikileaks and calling for the overthrow of the US government.

<comment><USER9> The news prints what people want to read about. It's a supply/demand industry.

However what in the leaks demand that people call for the overthrow of the US government? Thus far it has been entirely predictable, tame, boring cables from individual offices and subjective interpretations. BFD. Seriously, BFD. It's like reading a diary, and that's what's interesting, but there has been nothing that is unexpected.

<comment><USER10> Except when the world reads _this_ diary, spies will be discovered, people will die and other countries will refuse to cooperate with the United States.

</comment></comment></comment></comment></comment><comment><USER11> Companies like Arbor Networks have products like Peakflow[1] that are supposed to mitigate DDoS attacks by filtering the traffic. How are they not using tools such as those?

[1] [http://www.arbornetworks.com/en/delivering-in-cloud-ddos- pro...](http://www.arbornetworks.com/en/delivering-in-cloud-ddos-protection- services.html)

Disclaimer: I will be interning at Arbor this summer.

<comment><USER12> Most of them can't handle really large attacks. Wikileaks was supposedly getting hit with more than 10Gbps, which is right around the maximum Peakflow can handle.

When an attack this big targets a small business, they usually just null route the servers, essentially sending all data into a blackhole. The downside is that their website will be inaccessible by legitimate users. The upside is that they don't have to pay for the used bandwidth, which is pricey at 10Gbps.

</comment></comment><comment><USER13> Hmz, there are a lot of reasons why Amazon could have given them the boot (hitting usage limits due to DoS, payment problems, attacks on the whole Amazon infrastructure). I'd like to hear their story.

</comment><comment><USER14> Seems like hosting with a US company was a bad idea to begin with as any informant on the US would worry about Amazon being subpoenaed.

<comment><USER7> I don't think that wikileaks really worries about someone taking their servers at Amazon. The data on them isn't secret at all.

They have copies of the data and gave copies away as encrypted volumes on bittorent.

<comment><USER14> The identity of informants would be pretty secret. (Still waiting for wikileaksleaks.org).

<comment><USER7> I'd be surprised if this was held on the server hosting the data.</comment></comment></comment></comment>


Facebook survives Q4 with slowing 1.4B daily users but record $12.97B revenue - <AUTHOR> https://techcrunch.com/2018/01/31/facebook-q4-2017-earnings/ <comment><USER2> Interesting numbers:

Facebook spends more then 1/3 of it's money on R&D. YoY increase of Daily users by 14%. Facebook paid an effective tax rate of 23% in 2017.

Most important quote: "2017 was a strong year for Facebook, but it was also a hard one," said Mark Zuckerberg, Facebook founder and CEO. "In 2018, we're focused on making sure Facebook isn't just fun to use, but also good for people's well-being and for society. We're doing this by encouraging meaningful connections between people rather than passive consumption of content. Already last quarter, we made changes to show fewer viral videos to make sure people's time is well spent. In total, we made changes that reduced time spent on Facebook by roughly 50 million hours every day. By focusing on meaningful connections, our community and business will be stronger over the long term."

Direct link to the earnings report, instead of the tech crunch article.

[https://investor.fb.com/investor-news/press-release- details/...](https://investor.fb.com/investor-news/press-release- details/2018/Facebook-Reports-Fourth-Quarter-and-Full- Year-2017-Results/default.aspx)</comment>


Why Only An Idiot Would Get Rid of Verizon - <AUTHOR>

Have you ever used AT&T for any service? They suck. I had AT&T DSL for years and had nothing but problems, run-around, at times they sold me faster speeds that they then couldn't deliver in my neighborhood. I've had billing issues where they charged me more than they were supposed to.
If your DSL goes out, get ready to talk to an Indian dude for about an hour, only to have the call dropped and then you have to call back and explain everything all over again, "What OS do you use?"
AT&T has worst customer service I've ever experienced.
Verizon? Awesome. No billing issues, no signal issues, I never even call them.
So if you want to switch your phone to AT&T, have fun with that =) <comment><USER2> okay it's true AT&T does suck sometimes, but you'll hear stories of how every single company sucks somewhere because it all depends on your location. Verizon internet isn't all that fun to deal with either. Before I moved I was using Charter, and they're awesome, $70 for 30mbps, but at my parents' Time Warner Cable was selling 15 mbps for $80, and then at my friends' house Verizons' max speed was 8mbps and that sold for $80. I also use Uverse (AT&T) 6mbps for the business package and I've never had it die on me.

So my point is that for internet and wireless phone service it's really a hit or miss depending on where you are. Except that AT&T's wireless service really does suck when compared to the other big gsm service, Tmobile, which is almost on par with Verizon in most populated areas. My friends and I would speedtest whenever we go different areas, he uses verizon, and I use tmobile. Sometimes I win, sometimes he wins. Then there was always this poor guy with AT&T wireless with his S3 and he would always cry about how much it sucked.</comment>


Ask HN: Which tool do you use to take math-heavy notes? - <AUTHOR> For context: I'm looking for the best tool that I could utilize to write my college notes. I've read about TiddlyWiki, Notable, Typora (and other markdown editors)... But can't decide which would be the best and don't have enough time to try them all. <comment><USER2> I took most math heavy notes in markdown with LaTeX. Sometimes, I used google sheets. Lately I've been using Observable[1].

[1] [https://beta.observablehq.com/](https://beta.observablehq.com/)

</comment><comment><USER3> I can be quite quick in Tex, and a modern surface or ipad is very good but to be completely honest paper is still king.

</comment><comment><USER4> Math Notepad is quite nice: [http://mathnotepad.com/](http://mathnotepad.com/)

</comment><comment> a-saleh a) paper and pencil

b) once I had enough skill in typesetting in LaTeX, I was often just typing Tex in vim directly.

</comment><comment><USER5> LaTeX, with TikZ for diagrams.</comment>


Japanese-Style Entrepreneurship: Interview with Softbank's Masayoshi Son (1992) - <AUTHOR> https://hbr.org/1992/01/japanese-style-entrepreneurship-an-interview-with-softbanks-ceo-masayoshi-son <comment><USER2> Choosing someone who is a cultural (wrt business) and ethnic outlier and outsider and making him representative of a greater theme is tenuous.</comment>


The Self Winding Smartphone - <AUTHOR> http://www.thegrumpyprogrammer.com/2016/03/the-self-winding-smart-phone.html <comment><USER2> [http://www.wired.com/2014/08/could-you-charge-a- smartwatch-b...](http://www.wired.com/2014/08/could-you-charge-a-smartwatch- by-shaking-it/)

This guy did some napkin calculations which show this kind of energy generation can barely keep up with the energy needs of a smart watch, let alone any kind of phone.

</comment><comment><USER3> Energy Density [https://en.wikipedia.org/wiki/Energy_density_Extended_Refere...](https://en.wikipedia.org/wiki/Energy_density_Extended_Reference_Table)

Compare Spring power to Lithium-ion (typical in rechargeable electronics, watches, laptops, phones etc)

</comment><comment><USER4> > several individuals and groups have developed methods for adapting self > winding gear tech

Anyone know where I can find out about this?</comment>


How can a rubber duck help a programmer? - <AUTHOR> http://developer.qt.nokia.com/duck

<comment><USER2> I have a hand sculpted human skull I use for this purpose. It makes me feel all cool and evil. But seriously, the act of formulating a thorough explanation of a problem often leads to its solution. Try it, if inanimate objects are not your thing, get a patient significant other or friend (or maybe another programmer if you are lucky) who will let you half explain a problem until you have that epiphany and run off to fix it.

</comment><comment><USER3> I've found the most effective way to work through a problem is to have to explain it to my wife (who has no programming background). It works wonderfully.

</comment><comment><USER4> I'm torn. Sharing this with coworkers would help them boost productivity, but I'd have to hear them talk to themselves all the time.</comment>


European Banking Authority's risks of Bitcoin - <AUTHOR> http://ftalphaville.ft.com/files/2014/07/EBA_VCrisks.png

<comment><USER2> Here's the formal report from the EBA.

[http://www.eba.europa.eu/documents/10180/657547/EBA- Op-2014-...](http://www.eba.europa.eu/documents/10180/657547/EBA- Op-2014-08+Opinion+on+Virtual+Currencies.pdf)

The risk table submitted is on page 22 of this report.</comment>