Subject: Fwd: Does no-store in request imply no-cache?

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 10:53:56 +1100

Thoughts re: the below?

My inclination is to clarify "any response to it" so that a cache can use the same cached response to serve multiple requests with no-store in them (or not). 

Cheers,

Begin forwarded message:

> From: Alex Rousskov <[email-masked]>
> Date: 23 September 2010 9:47:57 AM AEST
> To: Mark Nottingham <[email-masked]>
> Cc: Squid Developers <[email-masked]>
> Subject: Re: Does no-store in request imply no-cache?
> 
> On 09/22/2010 05:05 PM, Mark Nottingham wrote:
> 
>> Strictly, as a request directive it means "you can't store the
>> response to this request" -- it says nothing about whether or not you
>> can satisfy the request from a cache.
> 
> Hi Mark,
> 
>    Let's assume the above is correct and Squid satisfied the no-store 
> request from the cache. Should Squid purge the cached response afterwards?
> 
> If Squid does not purge, the next regular request will get the same 
> cached response as the no-store request got, kind of violating the "MUST 
> NOT store any response to it" no-store requirement.
> 
> If Squid purges, it is kind of silly because earlier requests could have 
> gotten the same "sensitive" information before the no-store request came 
> and declared the already cached information "sensitive".
> 
> Thank you,
> 
> Alex.
> 
> 
>> See also:
>>  http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-11#section-3.2.1
>> 
>> 
>> On 23/09/2010, at 4:27 AM, Alex Rousskov wrote:
>> 
>>> Hello,
>>> 
>>>    One interpretation of RFC 2616 allows the proxy to serve hits when
>>> the request contains "Cache-Control: no-store". Do you think such an
>>> interpretation is valid?
>>> 
>>>  no-store
>>>      The purpose of the no-store directive is to prevent the
>>>      inadvertent release or retention of sensitive information (for
>>>      example, on backup tapes). The no-store directive applies to the
>>>      entire message, and MAY be sent either in a response or in a
>>>      request. If sent in a request, a cache MUST NOT store any part of
>>>      either this request or any response to it.
>>> 
>>> Thank you,
>>> 
>>> Alex.

--
Mark Nottingham   http://www.mnot.net/

---

From: David Morris <[email-masked]>
Date: Sun, 17 Oct 2010 17:05:53 -0700 (PDT)

I interpret NOSTORE as a stricter restriction than NOCACHE.
If it can't be stored, it can't be used in a subsequent
response.

If I recall the discussion from 10 years ago correctly, the
intent was to reduce the posibility that private information
could leak via even temporary storage.

Dave Morris

On Mon, 18 Oct 2010, Mark Nottingham wrote:

> Thoughts re: the below?
> 
> My inclination is to clarify "any response to it" so that a cache can
> use the same cached response to serve multiple requests with no-store in
> them (or not).
> 
> Cheers,
> 
> 
> Begin forwarded message:
>

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 11:09:01 +1100

Right, but that's largely orthogonal to the question below; whether no-store in a request implies that a previously stored response needs to be invalidated.

Cheers,

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 18:17:17 -0600

Mark Nottingham wrote:
> use the same cached response to serve multiple requests with no-store
> in them (or not). 
> 

That doesn't make sense to me.  My understanding is that no-store has
the RFC 2068 meaning of no-cache, which allows the RFC 2616 meaning of
no-cache to be synonymous with must-revalidate while allowing specific
headers to be excluded.  Your suggestion for no-store would result in
the RFC 2068 semantics of no-cache being discontinued, as there would
be no way to prevent the response being written to nonvolatile storage,
a need which isn't met by the private directive (which allows user-
agents to store).

-Eric

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 11:19:08 +1100

In a request?

---

From: David Morris <[email-masked]>
Date: Sun, 17 Oct 2010 17:22:08 -0700 (PDT)

I don't see it as orthogonal ... no-store means no-store ... my reading
is still that it can't be satisfied from the cache (i'm assuming that
the cache entry was stored as the result of a request w/o no-store).

If you can't cache the result, you can't use the cache to provide the
result. It may be that the data being protected is the association
between this request and the response. Or what ever. I think the
cache should be ignored for a no-store request and of course if the
no-store first appears on the response, the new response would not
be cached, even if it would logically invalidate existing content.

On Mon, 18 Oct 2010, Mark Nottingham wrote:

> Right, but that's largely orthogonal to the question below; whether
> no-store in a request implies that a previously stored response needs to
> be invalidated.
> 
> Cheers,
> 
>

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 11:26:46 +1100

I'm not disputing that a response to a request with 'no-store' can't be used to satisfy subsequent requests; the spec is pretty clear about that.

The question at hand is whether a request containing 'no-store', when received by a cache, can be served from cache, or whether it implies 'no-cache.' I.e., it's not whether the response can be used in a subsequent response; it's whether a previous response can be used to satisfy it.

Using a cached response to satisfy a request with 'no-store' in it doesn't result in leakage of information, all other things being equal. 

Cheers,

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 18:31:31 -0600

Mark Nottingham wrote:
> no-store in a request implies that a previously stored response needs
> to be invalidated.
> 

Whoops, I made the same mistake in my response.

> 
> >>> If Squid does not purge, the next regular request will get the
> >>> same cached response as the no-store request got, kind of
> >>> violating the "MUST NOT store any response to it" no-store
> >>> requirement.
>

I don't think it violates anything -- no-store says nothing about not
caching *previous* responses, only the current response.  The important
thing is that no other caches between the user-agent and the responding
cache, or the user-agent cache, stores the current response.  If I want
a response from the origin server, not a cache, I'd combine no-store
with max-age=0.  If I want to invalidate, I'd combine no-store with
must-revalidate, basically erasing previously-cached responses.

> use the same cached response to serve multiple requests with no-store

So I give this an on-second-thought +1, rather sheepishly...

-Eric

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 18:43:47 -0600

> 
> If I want to invalidate, I'd combine no-store with must-revalidate,
> basically erasing previously-cached responses.
> 

Errm, invalidate, not erase.  I really need to stop working weekends...

-Eric

---

From: David Morris <[email-masked]>
Date: Sun, 17 Oct 2010 17:50:11 -0700 (PDT)

On Mon, 18 Oct 2010, Mark Nottingham wrote:

> I'm not disputing that a response to a request with 'no-store' can't be
> used to satisfy subsequent requests; the spec is pretty clear about
> that.
> 
> The question at hand is whether a request containing 'no-store', when
> received by a cache, can be served from cache, or whether it implies
> 'no-cache.' I.e., it's not whether the response can be used in a
> subsequent response; it's whether a previous response can be used to
> satisfy it.

NO IT SHOULD NOT BE USED ... to my way of thinking, the best privacy
is achieved by *no_use_of_storage* to handle the request. I'm not sure
how I'd include no-store in a client request originating from a browser.
But if the application author went to the trouble of making such a
request, then we should err on the side of privacy and preclude any use
of storage for the request or response.

> Using a cached response to satisfy a request with 'no-store' in it
> doesn't result in leakage of information, all other things being equal.

I'd argue that to not be true. NO-STORE is a privacy oriented directive
and I don't think we have the ability to discern all the small leaks
that might occur given the clever black hats that abound. The safe path is
no use of storage.

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 18:49:45 -0600

> Errm, invalidate, not erase.  I really need to stop working

Gaaaah.  On third thought, the presence of no-store in a request should
preclude caches from invalidating under any circumstances.

-Eric

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 19:12:16 -0600

David Morris wrote:
>
> But if the application author went to the trouble of making
> such a request, then we should err on the side of privacy and
> preclude any use of storage for the request or response.
> 

Why are you assuming it's the application author making the request?

> 
> I'd argue that to not be true. NO-STORE is a privacy oriented
> directive and I don't think we have the ability to discern all the
> small leaks that might occur given the clever black hats that abound.
> The safe path is no use of storage.
> 

But in this case, the sender intent explicitly allows caching.  If the
application author wants to change a representation to never be stored,
then the server configuration needs changed, which isn't the intent of
no-store in a request.  In fact, I think the clever black-hats might
find it useful to know that a DDoS can get around cached responses by
just invalidating them in the initial requests.

-Eric

---

From: Adrien de Croy <[email-masked]>
Date: Mon, 18 Oct 2010 14:28:15 +1300

surely only server responses can invalidate a cache entry.  whether that 
server response is

a) a successful response to a request which should invalidate (such as 
DELETE etc)
b) a successful response to GET or HEAD which indicates a stored 
representation is no longer valid
c) a 404 to something that's in cache
d) doubtless something else I can't put my finger on

to allow a request to invalidate a cache entry is an open door to DOS.

As for no-store meaning no-cache.  I think people misunderstand 
no-cache.  The word "cache" and derivatives are used in several 
different contexts.

e.g.

whether something is storable for the purpose of satisfying subsequent 
requests
whether something is usable without revalidating with an O-S
whether something is usable after revalidation

no-cache to my reading implies revalidation is required, not that under 
no circumstances may a stored response be used.
no-store simply means the result cannot be stored in non-volatile 
storage (as per 
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p6-cache/)

Adrien

---

From: David Morris <[email-masked]>
Date: Sun, 17 Oct 2010 18:34:52 -0700 (PDT)

> Why are you assuming it's the application author making the request?

Because that is the only likely source of such a header on a
request. No reason for a browser to add this flag on its own. A tool
such as wget or curl might add the header flag as a consequence of
human direction. The pure definition is no use of storage. I see
no reason to contaminate that definition.

> just invalidating them in the initial requests.

No, there is no invalidation of a cache here ... the cache should be 
ignored ... no use of storage (aka no-store) is just that, this request
is processed without reference to the current content of the cache.
So the only DoS is w.r.t. the current request.

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 19:46:29 -0600

Adrien de Croy wrote:
> 
> surely only server responses can invalidate a cache entry.
>

Actually, unsafe request methods MUST invalidate the cache; since the
response may not follow the same path as the request, there's no way
for a cache to know whether the request was successful or not -- better
safe than sorry.

http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-11#section-2.5

-Eric

---

From: Adrien de Croy <[email-masked]>
Date: Mon, 18 Oct 2010 14:54:53 +1300

> for a cache to know whether the request was successful or not -- better

I thought this was discussed a while back, and it was decided this would 
only apply if the request "succeeded".

I don't see how on a TCP connection a response message can go via a 
different path than the request message.  That would break everything.

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 20:14:33 -0600

David Morris wrote:
>
> The pure definition is no use of storage. I see no reason to
> contaminate that definition.
> 

I don't know where you're getting that.  The semantics are don't write
to storage, not don't read from storage -- that's what max-age=0 does,
which may be combined with no-store, if that's the sender intent (of
the request).  I don't think it's required to make no-store have the
same semantics as 'no-store, max-age=0'.  If that couldn't be otherwise
expressed, then I'd likely agree with your position.

-Eric

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 20:44:48 -0600

> different path than the request message.  That would break everything.

IP is connectionless.  Asymmetrical routing is quite common on the
Internet, don't make me post a traceroute...  TCP is what keeps
everything from breaking.

-Eric

---

From: Adrien de Croy <[email-masked]>
Date: Mon, 18 Oct 2010 16:24:08 +1300

in reference to your statement

"Actually, unsafe request methods MUST invalidate the cache; since the
response may not follow the same path as the request, there's no way
for a cache to know whether the request was successful or not -- better
safe than sorry."

The "path" I'm talking about is a chain of TCP-based HTTP agents not 
about IP hosts (irrelevant in this discussion).

talking about IP and tracerts is a complete red herring.  These agents 
are the parties in TCP connections.  Sure, the IP packets may go via 
different routers between the endpoints, but the endpoints are the 
endpoints.

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 15:07:51 +1100

Now #249:
  http://trac.tools.ietf.org/wg/httpbis/trac/ticket/249

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 22:24:19 -0600

Adrien de Croy wrote:
> 
> talking about IP and tracerts is a complete red herring.  These
> agents are the parties in TCP connections.  Sure, the IP packets may
> go via different routers between the endpoints, but the endpoints are
> the endpoints.
> 

Exactly, which is why this is no red herring...

A = user-agent
B = origin server
C = cache

The route from A to B passes through C, the route from B to A passes
through D.  User-agent A sends a GET request to the origin server B.
The request is a hit on cache C, so the response goes from C to A.

In the event of a cache miss it is not A, but C, making the request to
B -- but only for safe methods, otherwise C is not an endpoint.

The user at A changes the representation and makes a PUT request to B.
Cache C intercepts this request, and *routes* it to B.  B then sends a
200 OK response to A, which does not pass through C.

This is because caches are stand-ins for origin servers, not user-agent
proxies.  B knows nothing of C, because A made the PUT request.

So, C only knows the status of the response to the PUT if the route
from B to A is the same as the route from A to B.  When dealing with
unsafe request methods, intermediaries are not participants, only the
user-agent and origin server are endpoints.

-Eric

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 18 Oct 2010 15:30:27 +1100

It looks like we're getting off-track here; can we focus on the issue at hand, please?

---

From: "Eric J. Bowman" <[email-masked]>
Date: Sun, 17 Oct 2010 23:51:43 -0600

> It looks like we're getting off-track here; can we focus on the issue

Sure.  I'd just like to say that my example was embarrasingly wrong, and
thank Willy for setting me straight off-list...

-Eric

---

From: Adrien de Croy <[email-masked]>
Date: Mon, 18 Oct 2010 18:52:09 +1300

This is easily solved then if this particular type of (mutant?) 
cache/router does not choose to do this.

It's still in the position to proxy the non-safe request, and get the 
result the same way it got the original content to be cached.  If it 
chooses not to, it may make sense for it to invalidate on request.

But I wouldn't extend that to a MUST-level requirement for all 
intermediaries in the spec.  Especially not one that would introduce a 
cache-denial attack surface.

There have been comments made in this list in the past about the 
suitability for consideration of intercepting proxies into the spec, and 
I understood the consensus was that such devices were aberrent enough 
not to warrant pollution of the spec.

There are further scenarios.

For instance reverse proxy through a cache farm.  the reverse proxy 
could make method-specific decisions about whether to pipe a request 
through an up-stream cache, or connect direct to O-S.  In this case, the 
cache wouldn't even see the non-safe request let alone the response.

I think these fall under the mantle of bad engineering decisions. At the 
very least understanding the full consequences of such decisions in 
relation to caching and cache invalidation is vital for it to work.

@Mark - sorry, this isn't OT - we're discussing key reasoning behind a 
suggested MUST-level requirement for cache invalidation on request 
(rather than response).

Regards

Adrien

-- 
Adrien de Croy - WinGate Proxy Server - http://www.wingate.com