0

Apart from the fact that TLS doesn't have "connection context" variables, is there any reason why this couldn't be technically built into the standard for something like JWT?

Why it is needed

When a browser sends multiple requests to the same API server, it resends the JWT in the header multiple times. This means additional data overhead, and each time, the server needs to verify the JWT.

I would like to see the TLS standard include "connection bound context variables" so that JWTs can be sent once and used across multiple HTTP REQUESTS over that TLS connection.

How it could work

1) The client connects to the server, and a TLS encrypted session is established.

2) The client send the JWT to the server-side - there are two options for this:

A) The client can send connection variables directly on the TLS layer. The client sets the variable on the client side, and TLS sends the data to the server side. The variable name from the client is always prefixed with "CLIENT-".

B) The client sends a HTTP request over the TLS session to a specific endpoint dedicated for use to set a TLS variable /api/setJWT. The client sends the JWT as a POST. The server reads the JWT, verifies it, and then sets it to the TLS connection context.

[B] would work best, because client software would be harder to change (browsers).

3)

On the serverside, the encapsulating TLS object's ITLSConnectionContext interface is made available from HTTP REQUEST handlers. The ITLSConnectionContext has three functions, string[] ListVariables(), string GetVariable(name), SetVariable(name, string).

Assuming 2B is used, when GetVariable("JWT") is successful, it can be assumed that it's valid.

How it could work without changing TLS standard

If a particular TLS connection between the server and the client has a secure identity, then the application-layer can link that to a simple dictionary lookup. Perhaps this could be a GUID (as well as the client-side IPAddress-Port tuple). This GUID approach would mean each language framework can natively implement the lookup, and that makes other benefits possible, where native memory objects can also be linked, not just platform-independent strings.

Other benefits

Furthermore, the server might variables on the context for other purposes:

1) A database PK for the Person behind the JWT, PersonID. It might be a stream interface 2) A particular stream (TCP connection) to another resource 3) A file lock to a user-related logging file

The web would be better.


But am I wrong? Am I missing something that would make this unworkable and insecure?


My rebuttal to Steffen Ullrich answer:

Thanks for your answer. A comment was going to be too small for me to fit my response to your answer.

I can see no obvious security issues apart from a potential attack of exhausting memory in the peers TLS stack this way

i) With [2B] only the server-side can add a variable to the connection state, so the client would not be able to attack the server by filling memory. Maximums for POST size and other security features would still apply.

ii) Relative to sending a JWT (say 2KB) as part of every HTTP request, I don't see much of a difference in memory usage. The peak memory usage would be 2KB for example for both the connection and the HTTP requests. In the case of individual HTTP requests, the memory is possibly stackallocated (or at least temporary).

The web application layer is fully independent of the actual transport. Two requests might share the same TLS connection and/or the same TLS session or they might be not. There is no way for the web application to find out or influence this, which means binding such storage to the TLS connection/session is unusable with the current application model.

You might be right, my idea isn't comprehensive, I was more interested in the security aspects. But if I ever built it, I would need to overcome this engineering challenge. (Communication between protocol encapsulation layers isn't a new thing)

What you propose can already be implemented at the HTTP level by associating such a storage with the session cookie. And it is actually more usable at this level since the application is already aware of the user session (but not of the TLS session).

Yes, in the scope of HTTP, this is effectively a server-side session variable with TLS-connection scope. However, I wasn't going to necessarily limit this to HTTP. Ideally the JWT could be supplied to the TLS protocol on the client side during connection initialisation, but that's a much larger jump than the smaller one I present for security discussion. I chose not to provide a "client certificate" JWT kind of thing. (Update: see below, where I describe how a TLS+JWT protocol is in fact superior to server-side session variable.

Your proposal is specific to "compression" of the HTTP header. This is already transparently implemented in HTTP/2 with HPACK so this specific use case might be no longer needed.

(Update 2020-02-12)

I read more about HPACK (and QPACK), and now I understand that it isn't "compression" but rather a shared dictionary. The JWT token would be a new entry in the dictionary. This is what I am looking for "functionally". I would expect that QUIC will eventually help to distribute QPACK dictionaries in a web farm.

How about reverse-proxies?

After answering Steffen Ullrich, I thought of the following problem:

If there is a load-balancer or reverse-proxy, the web application server only receives the decrypted. The reverse-proxy scenario is very common. CloudFlare is a great example where TLS is provided directly to the user, then another TLS session to the origin server.

As Steffen Ullrich suggested, a server-side session variable overcomes this better, although for a web farm, if the destination node changes, that node won't have the session variable state.

So the ultimate answer might lie within a fully-fledged TLS-protocol enhancement:

  • A JWT that is part of the TLS handshake (but after encryption is available)
  • The ability for reverse-proxies to forward such client-id information to the next TLS connection toward the origin server.
  • If a TLS 0-RTT reconnection is possible, there's no need to resend the JWT. If 0-RTT fails, then a new TLS session is needed, and therefore a new handshake occurs which includes transmission and caching of JWT.

It would seem that TLS-protocol-level enhancement overcomes all functional problems, and even overcomes "cookie" or "server-side session" issues.

  • I'm not sure if SE really is the place for such questions, given that this is more of a proposal or a discussion. It's nonetheless an interesting idea. – MechMK1 Feb 3 at 9:48
  • @MechMK1 Noted. I'm here to discuss the security of this, and so a general description of the idea is also necessary to get there. I'll improve the title to ensure the topic remains more focused on security – Todd Feb 3 at 10:02
  • JWTs are becoming increasingly central to the web, so I think if it's not now, these kinds of questions will be asked in the future. Hopefully, this question helps clear the way for (IETF?) engineers to to standardise JWT-context-binding in the TLS roadmap. – Todd Feb 3 at 10:08
  • Given that you have 13k reputation on SO, it surprizes me that you came here for a discussion. You should know SE is not for discussions. – MechMK1 Feb 3 at 10:18
  • @MechMK1 I didn't come for discussion, my OP is quite clear in intention. The first answer here basically says there is no security issue, but there are some potential functional issues. I addressed those, so there's more clarity for others who might identify a security flaw. Clearly if this was related to SQL, the answer section would be full of people screeming "SQL INJECTION"! The fact that no one can think of a flaw (yet) - is that a problem with my question? Ideally, someone with experience would answer - "there are no security flaws because of X,Y, and Z aspects". – Todd Feb 3 at 10:36
0

When abstracting away from your actual implementation idea my understanding of your proposal is, that:

  • you want to have some (key,value) storage
  • which is associated with a TLS connection or TLS session (not really clear)
  • where one side can store a (key,value) once and the other can retrieve it multiple times
  • with the goal of saving bandwidth

I can see no obvious security issues apart from a potential attack of exhausting memory in the peers TLS stack this way, but I see usability issues:

  • The web application layer is fully independent of the actual transport. Two requests might share the same TLS connection and/or the same TLS session or they might be not. There is no way for the web application to find out or influence this, which means binding such storage to the TLS connection/session is unusable with the current application model.
  • What you propose can already be implemented at the HTTP level by associating such a storage with the session cookie. And it is actually more usable at this level since the application is already aware of the user session (but not of the TLS session).
  • Your proposal is specific to "compression" of the HTTP header. This is already transparently implemented in HTTP/2 with HPACK so this specific use case might be no longer needed.

After the edit of the question with an extended proposal the OP writes:

It would seem that TLS-protocol enhancement overcomes all problems, and even overcomes "cookie" or "server-side session" issues.

I disagree. The new proposal kind of requires (load balancing) reverse proxies to cache these (key,value) mappings so that they can include it when using another backend. At the same time the OP argues that a simple cookie associated (key,value) mapping would have problems with a load balancing setup.

In other words: the OP extends its own protocol to deal with the issue while at the same time denying such work around for the simpler cookie based solution. Apart from that such workaround is not even needed: it is already common that servers share a distributed storage where such things can be handled without inventing something new.

In essence binding a (key,value) to a HTTP cookie and binding to a TLS session could provide the same functionality. Only that the cookie has a longer life time than the TLS session and is already available from the application, i.e. no additional API is needed.

| improve this answer | |
  • Thanks again. Please see my rebuttal in my OP. – Todd Feb 3 at 9:26
  • @Todd: see my rebuttal too in my updated answer. – Steffen Ullrich Feb 3 at 11:07
  • Thanks Steffan. You raise some valid points that I think I will be able to counter later. – Todd Feb 3 at 22:20
  • "The new proposal kind of requires (load balancing) reverse proxies to cache these (key,value) mappings" - perhaps, but if designed correctly this requirement can be removed: i) Upon first-connection with the client-browser, the JWT token will be forwarded without needing caching. ii) If the reverse-proxy to origin-server TLS connection expires (HTTP/3), we could force the client TLS connection to reset to induce the JWT to come through again. -- but personally, I would prefer to keep JWT caching. – Todd Feb 4 at 5:05
  • "Apart from that such workaround is not even needed: it is already common that servers share a distributed storage where such things can be handled without inventing something new." - agreed, that's possible. But the use of load-balancing requires a new mechanism beyond client HTTP Request/Response to maintain session state across web farm nodes. I call that a workaround. What I am proposing is that JWT would be shared across web farm nodes naturally along with client HTTP Request/Response paths. – Todd Feb 4 at 5:07
0

TLS is running at Layer 4 on OSI model while JWT runs at Layer 7, hence is an applicative protection of your service.

From security perspective it's always best to have a layered defense or defense on depth.

Now if you put all together, you have potential of single point of failure on your protection.

| improve this answer | |
  • Thanks winnn. I disagree, but this is the kind of answers that I'm looking for. – Todd Feb 3 at 22:17
  • This OSI layer argument is not correct. TLS uses X509 certificates, those are exchanged using a protocol that can be described as Layer-7. JWT is a token format, not even a protocol, they can be exchanged with OAUTH (a Layer-7 protocol). Using JWT with TLS is just like using X509 with TLS. "layered defense or defense on depth" - I agree, but I don't believe this is applicable in this situation. OAuth should and does happen with TLS secrecy and PKI. Thanks again for your answer, if you can think of any other security-issue angles I'm keen to learn more. – Todd Feb 4 at 4:54
0

Perhaps while not addressing all of the "desires" there are Token Binding implementations for OpenID Connect and for OAuth 2.0

There is also JWT Secured Authorization Response Mode for OAuth 2.0 (JARM) Which puts emphasis on the "client obtains the state parameter from the JWT and checks its binding to the user agent".

Microsoft has done some Token binding for LDAP. And of course Token Binding over HTTP

| improve this answer | |
  • This is very useful, thanks – Todd Feb 3 at 22:16
  • From Token Binding over HTTP: "Such bound security tokens are protected from misuse, since the server can generally detect if they are replayed inappropriately, e.g., over other TLS connections.". This is a nice security benefit. – Todd Feb 4 at 4:56
0

No, a security flaw isn't created conceptually. This can be primarily demonstrated with parallels ideas that are already out there. (Of course we have to already assume that implementations are generally imperfect, so we'll sideline that obvious aspect)

  1. This is the same general idea as TLS with client-side certificates. This has been successfully implemented. (So the concept is logically valid being the same, and implementation will still matter of course: Unlike the asymmetric nature of client-certificates a JWT is fully discolsed and could be replayed, so it must not be sent plain-text. The JWT must certainly be transmitted by the client in an encrypted form - public key RSA or after symettric encryption is established.)
  2. TLS client-side certificates are longlived, yet JWTs expire sooner than client-side certificates. This tends to mean that JWTs are "more secure": TLS certificates have issues around revocation and shorter lifetimes is a good strategy (ie. LetsEncrypt are 90 days). Note: I wouldn't say that JWTs can replace client-side certificates: They do overlap, but have different security features, and could be used together (ie. Certificates don't have claims for things like "user roles", and JWTs aren't conclaved in TPMs)
  3. For TLS client-side certificates Public Key Infrastructure (PKI) is hard (TPM, Signing Authority, Revocations, and maybe physical USB distribution); on the contrary with JWTs: web apis are already dealing with JWTs (there's no new infrastructure new to add). While saving on bandwidth and CPU, the TLS layer can gain transport-layer information about client security assertions, particularly in logging. The clients already have JWTs, so there's additional authentication-security of the TLS session without needing to invest in PKI.
  4. It's worth highlighting the potential risk for denial of service (thanks Steffan). Remembering that a denial of service issue for TLS/JWT is already the same risk possible with sending JWTs on every HTTP Request to web api server. Therefore, the same mitigations apply - max HTTP request size, Max JWT header field size, etc..
  5. TLS\JWT might also solve a WebSockets (WSS) problem - see https://en.wikipedia.org/wiki/WebSocket#Security_considerations where it particularly mentions "tokens" over "cookies". Where federated authentication is needed, and it could be supplied by a JWT. TLS is used in HTTPS, and in this case TLS/JWT could also be reused for WSS.

So in conclusion, on the surface, it didn't appear that this kind of TLS/JWT binding concept would "create" a security flaw. Upon deeper analysis we find TLS/JWT actually improves security while also improving bandwidth and performance somewhat (especially for cases where JWTs are quite large, and where Single Page Applications send quite a lot of WebAPI calls per second). Rational deductions of improved security help to strengthen the case that security doesn't go backwards.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.