Re: [websec] HSTS: max-age=0 interacting with includeSubdomains

Tobias Gondrom <tobias.gondrom@gondrom.org> Tue, 21 August 2012 09:31 UTC

Return-Path: <tobias.gondrom@gondrom.org>
X-Original-To: websec@ietfa.amsl.com
Delivered-To: websec@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D31EE21F86BD for <websec@ietfa.amsl.com>; Tue, 21 Aug 2012 02:31:47 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -96.277
X-Spam-Level:
X-Spam-Status: No, score=-96.277 tagged_above=-999 required=5 tests=[AWL=-1.515, BAYES_00=-2.599, FH_HELO_EQ_D_D_D_D=1.597, FH_HOST_EQ_D_D_D_D=0.765, FM_DDDD_TIMES_2=1.999, HELO_DYNAMIC_IPADDR=2.426, HELO_EQ_DE=0.35, J_CHICKENPOX_33=0.6, RDNS_DYNAMIC=0.1, USER_IN_WHITELIST=-100]
Received: from mail.ietf.org ([64.170.98.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QMZij1Y6JvBW for <websec@ietfa.amsl.com>; Tue, 21 Aug 2012 02:31:47 -0700 (PDT)
Received: from lvps176-28-13-69.dedicated.hosteurope.de (lvps176-28-13-69.dedicated.hosteurope.de [176.28.13.69]) by ietfa.amsl.com (Postfix) with ESMTP id D47E821F86C4 for <websec@ietf.org>; Tue, 21 Aug 2012 02:31:46 -0700 (PDT)
Received: (qmail 1374 invoked from network); 21 Aug 2012 11:31:44 +0200
Received: from 94-194-102-93.zone8.bethere.co.uk (HELO ?192.168.1.65?) (94.194.102.93) by lvps176-28-13-69.dedicated.hosteurope.de with ESMTPSA (DHE-RSA-AES256-SHA encrypted, authenticated); 21 Aug 2012 11:31:44 +0200
Message-ID: <50335580.2040701@gondrom.org>
Date: Tue, 21 Aug 2012 10:31:44 +0100
From: Tobias Gondrom <tobias.gondrom@gondrom.org>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120714 Thunderbird/14.0
MIME-Version: 1.0
To: ietf@adambarth.com, bsmith@mozilla.com
References: <CAJE5ia91-j4avKvvKSUj2P1K_U=EFwGd+feVqMNv8AtkWqSA7Q@mail.gmail.com> <1883526372.2436253.1345507760090.JavaMail.root@mozilla.com> <CAJE5ia_YpQ5WSJBwUWdeNZcc_SGRQQNqZpQnTU0BXK7Yju3yqA@mail.gmail.com>
In-Reply-To: <CAJE5ia_YpQ5WSJBwUWdeNZcc_SGRQQNqZpQnTU0BXK7Yju3yqA@mail.gmail.com>
Content-Type: text/plain; charset="ISO-8859-1"; format="flowed"
Content-Transfer-Encoding: 7bit
Cc: websec@ietf.org
Subject: Re: [websec] HSTS: max-age=0 interacting with includeSubdomains
X-BeenThere: websec@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Web Application Security Minus Authentication and Transport <websec.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/websec>, <mailto:websec-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/websec>
List-Post: <mailto:websec@ietf.org>
List-Help: <mailto:websec-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/websec>, <mailto:websec-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 21 Aug 2012 09:31:48 -0000

On 21/08/12 01:19, Adam Barth wrote:
> On Mon, Aug 20, 2012 at 5:09 PM, Brian Smith <bsmith@mozilla.com> wrote:
>> Adam Barth wrote:
>>> The way the implementation in Chrome works is that max-age=0 only
>>> clears the entry for that particular host name.  If there's another
>>> shorter host name with includeSubdomains, that isn't affected.
>> Let me try to clarify with an example, which I think should be explicitly documented in the spec:
>>
>> 1. We visit https://example.com and receive HSTS with max-age=1234567890 ; includeSubdomains
>> 2. We visit https://sub.example.com and receive HSTS with max-age=0
>>
>> Now, is sub.example.com HSTS (because it inherits the HSTS setting from example.com), or is it non-HSTS (because we received a max-age=0 for that host)?
> It is HSTS.  Visit (2) would have removed any sub.example.com-specific
> entries in the HSTS state table, but there were none, so it didn't
> have any effect on the world.
>
>> When we receive a HSTS header from sub.example.com with max-age > 0, then we will treat the expiration time of sub.example.com to be MAX(expiration(example.com), expiration(sub.example.com)).
> A simpler way to think about it is that you keep state for each host.
> To answer the question of whether a given host is HSTS, you walk the
> list of subdomains and check their unexpired state.
>
>> But, if we receive a HSTS header from sub.example.com with max-age == 0, there are two possibilities:
>>
>> 1. We act consistently with the above case and calculate the HSTS expiration time of sub.example.com to be:
>>
>>         MAX(expiration(example.com), expiration(sub.example.com))
>>      == MAX(expiration(example.com), 0)
>>      == expiration(example.com)
>>
>>     This means that we would effectively be ignoring the max=age == 0 value sent by sub.example.com.
> Correct.
>
>> 2. We honor the max-age=0 directive sent by sub.example.com and turn off HSTS for sub.example.com, but not for example.com. That is, we would treat max-age == 0 from a subdomain as "do not do includeSubdomains inheritance for this subdomain."
> This is not correct.  We do "honor" the max-age directive set by
> sub.example.com by expiring any sub.example.com-specific state.
> However, sub.example.com is HSTS due to state specific to example.com,
> which is not expired.
>
>> Now, it seems to me that the only reasonable choice is #2, but the spec seems to imply that we should do #1.
> Choice #1 seems reasonable to me.
>
>> Here's the problematic scenerio:
>>
>> 1. We visit https://example.com and get the HSTS header with includeSubdomains and an (effectively) infinite expiration time.
> There is no such thing as an infinite expiration time.  Let's proceed
> assuming you mean "one year" rather than infinite.
>
>> 2. The owners of example.com decides to turn of HSTS for whatever reason (perhaps the domain changed owners, or there's a compatibility issue, or whatever), so they start sending out HSTS with max-age=0 for example.com and for all the subdomains.
> That's not a correct way of disabling HSTS after (1).  Instead, they
> need only send out an max-age=0 header for example.com itself.
>
>> 3. We visit https://sub.example.com and get the max-age=0 HSTS header.
>>
>> If we choose choice #2, we do what the owners of example.com intended, by treating https://sub.example.com as non-HSTS right away, without ever needing to visit https://example.com, which we might NEVER do ever again.
> I mean, it's just guesswork as to what they intend.  I can write a
> similar story in which the intent is the reverse.
>
>> If we choose choice #1, we will effectively be making https://sub.example.com HSTS forever, and the domain owner has no way to help us undo it.
> They can simply initiate a request to https://example.com/ (e.g., by
> using an HTTP redirect or an HTML image element) and clear the HSTS
> state for that host name.
>
> Adam

<hat="individual">

Would agree with Adam.

And for Brian, I think there is actually one more use case that you 
haven't considered:
Look at it in reverse order:
1. We visit https://sub.example.com and receive HSTS with max-age=1234567890
2. We visit https://example.com and receive HSTS with max-age=0 ; 
includeSubdomains

as far as I remember that would actually clear HSTS for sub.example.com?
So your mathematical formula above would not reflect this correctly:
"
       MAX(expiration(example.com), expiration(sub.example.com))
     == MAX(expiration(example.com), 0)
     == expiration(example.com)
"

Correct, or am I missing something here?

Best, Tobias




> _______________________________________________
> websec mailing list
> websec@ietf.org
> https://www.ietf.org/mailman/listinfo/websec