Re: [OAUTH-WG] client certs and TLS Terminating Reverse Proxies (was Re: I-D Action: draft-ietf-oauth-jwt-introspection-response-08.txt)

Neil Madden <neil.madden@forgerock.com> Wed, 30 October 2019 07:43 UTC

Return-Path: <neil.madden@forgerock.com>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id A46DF120878 for <oauth@ietfa.amsl.com>; Wed, 30 Oct 2019 00:43:58 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.987
X-Spam-Level:
X-Spam-Status: No, score=-1.987 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MIME_QP_LONG_LINE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_KAM_HTML_FONT_INVALID=0.01, URIBL_BLOCKED=0.001] autolearn=unavailable autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=forgerock.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NthdAWfuc2Qs for <oauth@ietfa.amsl.com>; Wed, 30 Oct 2019 00:43:55 -0700 (PDT)
Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id EFD26120088 for <oauth@ietf.org>; Wed, 30 Oct 2019 00:43:54 -0700 (PDT)
Received: by mail-wr1-x444.google.com with SMTP id t16so1112691wrr.1 for <oauth@ietf.org>; Wed, 30 Oct 2019 00:43:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=forgerock.com; s=google; h=content-transfer-encoding:from:mime-version:subject:date:message-id :references:cc:in-reply-to:to; bh=JPbpBcvKrmn5eZTH0zsKjaUUKXnktXq5/u1gbM0R9TU=; b=J01xHTLp2WRN52FleVPVZMMaixnrVR80KHdNDzecPQZZeWKfX2/avMw/394U7qHwYV dX6gV0pRE0QqtM7UoGT2wrU2k2kipaO7qKZesPCzJDmTm7OZ94aZzBl6RovaXyUZNj+t Yac+LKHjZeStztRCQvPDMpKcOAuBV9T9SNPjA=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:content-transfer-encoding:from:mime-version :subject:date:message-id:references:cc:in-reply-to:to; bh=JPbpBcvKrmn5eZTH0zsKjaUUKXnktXq5/u1gbM0R9TU=; b=m/5NYtN3Z7F1sC102C9vWYzKW731CMjSEOTgGrUNp3nHaoQxiGM6K6ngKK7vJ+P4be 41jk4l4BHzKGs9VausVvks0IbSjBoow+WICAAd5dJZ7wxXfdI2nuid4UtUjSZREdlt2n sE4upuY8UEU29os+D9dxiaTFjxZYj6lUXlL46VyDLrvS9y/p/P/s6UyxLgHkiMwrluDv M2FK+vnx7b3SGJnsdpXvCiP7ncZcOuGnui+7Ru+nXRN/PFQkhYzH/yDqvcE63unaTuQt OfyBjiQz0ulzAN3zyfQFvFHwTxCnHxNFE4cLmNyejNKJRX4Y4oi5K48W4KcrqzyrRcRp zcpQ==
X-Gm-Message-State: APjAAAVPZwN1z30nuTEB6SJRarjBM+WKBcA5Xu0ePXxFPqs0nNqIO/Rh rWZQYENUkUNTLHETlOVSiGj3cA==
X-Google-Smtp-Source: APXvYqyzhreSpw7z6XpzIv7mIWszxTmRwbCTDkvatsxwovZ/lsdY7j0Sp4mder9NqW4rAS2jLfXCJg==
X-Received: by 2002:a5d:4208:: with SMTP id n8mr785680wrq.136.1572421433116; Wed, 30 Oct 2019 00:43:53 -0700 (PDT)
Received: from ?IPv6:2a01:4c8:1e:73aa:79ca:a0ea:5919:c17b? ([2a01:4c8:1e:73aa:79ca:a0ea:5919:c17b]) by smtp.gmail.com with ESMTPSA id q15sm1494319wrr.82.2019.10.30.00.43.51 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 30 Oct 2019 00:43:51 -0700 (PDT)
Content-Type: multipart/alternative; boundary=Apple-Mail-0F24FA45-F540-4269-9891-07ADD36CA4DC
Content-Transfer-Encoding: 7bit
From: Neil Madden <neil.madden@forgerock.com>
Mime-Version: 1.0 (1.0)
Date: Wed, 30 Oct 2019 07:43:50 +0000
Message-Id: <E58B4EB0-7E59-4A0C-B43F-263CEF0B955D@forgerock.com>
References: <2B2ACEE8-7B48-4E2D-94DA-AF3DA86DE809@mit.edu>
Cc: Brian Campbell <bcampbell=40pingidentity.com@dmarc.ietf.org>, oauth <oauth@ietf.org>
In-Reply-To: <2B2ACEE8-7B48-4E2D-94DA-AF3DA86DE809@mit.edu>
To: Justin Richer <jricher@mit.edu>
X-Mailer: iPhone Mail (17A878)
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/pFOqzX4U2U41NdYNUVWYzroGw1I>
Subject: Re: [OAUTH-WG] client certs and TLS Terminating Reverse Proxies (was Re: I-D Action: draft-ietf-oauth-jwt-introspection-response-08.txt)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 30 Oct 2019 07:43:59 -0000

Replies below.

> On 29 Oct 2019, at 19:13, Justin Richer <jricher@mit.edu>; wrote:
> 
> I would argue that making this standard would actually increase the likelihood of developers getting this right, as now instead of following some copy-pasted recipe for NGINX or Apache that they found on the web, they could turn on a standard setting that would take care of both stripping out incoming headers and injecting the appropriate values. And all of that can be covered in the security considerations with a bunch of normative text on top to make sure inbound headers are stripped. What you’re describing below is clever, but ultimately it’s just a small bit of obscurity more than anything real. 

Not really. If the header is cryptographically unguessable (eg includes a 128-bit base32-encoded string) then it provides a real security improvement. The header name becomes a bearer token effectively. There are many ways that a reverse proxy can be misconfigured in a way that compromises the security of trusted headers:

1. There is the simple misconfiguration where you fail to strip trusted headers from incoming requests. For example in HAProxy this is the difference between set-header and add-header directives (and the add-header docs list passing a client cert to the backend as an example use case [1] despite this being insecure). Naive functional testing will still pass, but fairly basic adversarial tests would catch this. A standard header/config option might help with this simple case. 

2. Scoping issues cause rules to not be applied where you expect them to. For example, nginx has multiple levels of scope that you can define header rules (http, server, location). But if you define *any* proxy_set_header directive at the location level (for example) it will ignore *all* such directives at the server or http levels, which can cause header-stripping rules to be silently disabled. 

3. More advanced attacks exploit differences in how individual reverse proxies and application servers parse headers to smuggle headers or even whole requests past the RP [2]. 

Using unguessable header names for transmitting security-critical information between the RP and the app server provides an effective defense in depth against all of these attacks. (They are all forms of confused deputy attack and the unguessable header acts in the same way as an anti-CSRF token to prevent these systematically). 

(I had thought the random header name pattern was widely known, as I’ve heard it mentioned in conversations several times. But now I come to look for a definitive reference to it I can only find it mentioned in our own docs [3] and connect2id’s [4]). 

[1]: http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4.2-http-request%20add-header
[2]: https://portswigger.net/web-security/request-smuggling
[3]: https://backstage.forgerock.com/docs/am/6.5/oauth2-guide/#provide-mtls-certs
[4]: https://connect2id.com/products/server/docs/guides/tls-proxy 

> 
> The way things are today, you’ve got to not only pick a header and figure out its format, but also do the injection protection step yourself. Since all of these are disconnected, there are a lot more places that it could fall over. Even a typo where you throw out incoming “CLIENT_CERT” but inject “CLIENT_CERTS” or something like that would be disastrous. 

Most load balancers and reverse proxies support some way of setting headers that also strips the incoming header in one directive. Unless the standard gets rid of all the other ways they support to configure this (and removes all the old Stack Overflow recipes) then it won’t necessarily improve things. 

A standard that provides an explicit field for including a secret (heck, we could even call it an access token :-) that SHOULD be used might provide a significant improvement in security. 

> 
> All in all, I am in favor of this being defined in one standard way, in addition to secure communication between proxies and backends being standardized — but this latter bit really seems like a separate problem.

I agree that that is a separate issue. 

— Neil

> 
>  — Justin
> 
>>> On Oct 28, 2019, at 12:32 PM, Neil Madden <neil.madden@forgerock.com>; wrote:
>>> 
>>> While there are some benefits to standardizing headers for this kind of communication, there are some significant downsides - particularly when using headers to communicate critical security information like certs. It is *very* easy to misconfigure a reverse proxy to not strip Forwarded (or whatever) headers from incoming requests, allowing a client to simply supply a certificate as a header without authenticating the TLS connection with the corresponding private key. One good practice to prevent this is to pick a random and unguessable header name (configurable per installation) to be used for communicating the certificate, rather than using something fixed and standard. That way even if you misconfigure the proxy an attacker still has to try and guess the correct header name.
>>> 
>>> I suppose the same thing could be accomplished by having an extension for including a shared secret (or HMAC tag) in the header to authenticate it.
>>> 
>>> -- Neil
>>> 
>> 
>>> On 28 Oct 2019, at 15:32, Brian Campbell <bcampbell=40pingidentity.com@dmarc.ietf.org>; wrote:
>>> 
>>> I don't think there's anything beyond defining something to carry the client certificate information (including the format and encoding). And it could well be a new RFC7239 parameter. Or it might just be a new HTTP header on its own.  
>>> 
>>> On Mon, Oct 28, 2019 at 9:05 AM Rifaat Shekh-Yusef <rifaat.ietf@gmail.com>; wrote:
>>>> Thanks Brian,
>>>> 
>>>> I guess my question is: given RFC7239 and the fact that it is straightforward to secure the channel between the terminating reverse proxy and the backend service in a cluster, is there anything, from a standard perspective, that we need to do beyond defining a new parameter to carry the client certificate information?
>>>> You seem suggest that the answer is yes. If so, can you please elaborate on why is that?
>>>> 
>>>> Regards,
>>>>  Rifaat
>>>> 
>>>> 
>>>> 
>>>>> On Mon, Oct 28, 2019 at 8:42 AM Brian Campbell <bcampbell@pingidentity.com>; wrote:
>>>>> 
>>>>> 
>>>>>> On Sat, Oct 26, 2019 at 3:55 PM Rifaat Shekh-Yusef <rifaat.ietf@gmail.com>; wrote:
>>>>>> 
>>>>>>> On Fri, Oct 25, 2019 at 3:47 PM Brian Campbell <bcampbell@pingidentity.com>; wrote:
>>>>>>> 
>>>>>>> I did look at RFC7239 when doing that and it could have been made to work but felt the fit wasn't quite right and would have been more cumbersome to use than not.  
>>>>>>> 
>>>>>> 
>>>>>> Can you elaborate on this?
>>>>>> These days, with the zero trust model in mind, there are orchestration tools, e.g. Istio, that easily allows you to establish an MTLS channel between the reverse proxy/load balancer/API GW and the backend servers.
>>>>>> Why is that not sufficient? 
>>>>>> Which part is cumbersome?
>>>>> 
>>>>> What I meant was only that in the course of writing https://tools.ietf.org/html/draft-ietf-tokbind-ttrp-09, which aims to define HTTP header fields that enable a TLS terminating reverse proxy to convey information to a backend server about the validated Token Binding Message received from a client, it seemed more straightforward and sufficient for the use-case to use new HTTP headers to carry the information rather than to use new fields in the Forwarded header framework from RFC7239.    
>>>>>  
>>>>> 
>>>>> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, distribution or disclosure by others is strictly prohibited.  If you have received this communication in error, please notify the sender immediately by e-mail and delete the message and any file attachments from your computer. Thank you.
>>> 
>>> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, distribution or disclosure by others is strictly prohibited..  If you have received this communication in error, please notify the sender immediately by e-mail and delete the message and any file attachments from your computer. Thank you._______________________________________________
>>> OAuth mailing list
>>> OAuth@ietf.org
>>> https://www.ietf.org/mailman/listinfo/oauth
>> 
>> _______________________________________________
>> OAuth mailing list
>> OAuth@ietf.org
>> https://www.ietf.org/mailman/listinfo/oauth
>