[http-auth] CSRF Prevention

Tim <tim-research@sentinelchicken.org> Fri, 24 June 2011 22:13 UTC

Return-Path: <tim-research@sentinelchicken.org>
X-Original-To: http-auth@ietfa.amsl.com
Delivered-To: http-auth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 874FB11E809E for <http-auth@ietfa.amsl.com>; Fri, 24 Jun 2011 15:13:22 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.265
X-Spam-Level:
X-Spam-Status: No, score=-2.265 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, IP_NOT_FRIENDLY=0.334]
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 YIvisoqcNoNt for <http-auth@ietfa.amsl.com>; Fri, 24 Jun 2011 15:13:21 -0700 (PDT)
Received: from sentinelchicken.org (mail.sentinelchicken.org [69.168.48.72]) by ietfa.amsl.com (Postfix) with ESMTP id 25C8011E808F for <http-auth@ietf.org>; Fri, 24 Jun 2011 15:13:20 -0700 (PDT)
Received: (qmail 30707 invoked from network); 24 Jun 2011 22:13:16 -0000
Received: from unknown (HELO pascal.sentinelchicken.org) (10.81.64.2) by feynman.sentinelchicken.org with ESMTPS (DHE-RSA-AES256-SHA encrypted); 24 Jun 2011 22:13:16 -0000
Received: (qmail 20677 invoked from network); 24 Jun 2011 22:13:30 -0000
Received: from shannon.sentinelchicken.org (10.81.64.4) by pascal.sentinelchicken.org with SMTP; 24 Jun 2011 22:13:30 -0000
Received: (nullmailer pid 23007 invoked by uid 1000); Fri, 24 Jun 2011 22:13:15 -0000
Date: Fri, 24 Jun 2011 15:13:15 -0700
From: Tim <tim-research@sentinelchicken.org>
To: http-auth@ietf.org
Message-ID: <20110624221315.GF1542@sentinelchicken.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
User-Agent: Mutt/1.5.21 (2010-09-15)
Subject: [http-auth] CSRF Prevention
X-BeenThere: http-auth@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: HTTP authentication methods <http-auth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/http-auth>, <mailto:http-auth-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/http-auth>
List-Post: <mailto:http-auth@ietf.org>
List-Help: <mailto:http-auth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/http-auth>, <mailto:http-auth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 24 Jun 2011 22:13:22 -0000

Hi all.  I wanted to float this one by you all, as we may find it
useful to help squash CSRF along with phishing attacks.


I'm sure many of you are familiar with CSRF attacks, so I'm not going
to give too much background.  I'm also sure these have been discussed
on numerous IETF security lists in the past, but let me just quickly
frame them in the context of how I think of them:

To me, CSRF attacks are symptom of a design flaw in the web, or
perhaps more accurately, a symptom of the fact that we currently use
the web in ways it wasn't designed.  CSRF is possible because:

A. There is no inherent (or strict) distinction between HTTP requests
   initiated by content on the same site vs those initiated by content
   on other sites. 

In addition, CSRF is often made easier because:

B. In practice, there is no distinction between requests that make a
   material change to site content vs those that just retrieve content.
   (Often GET and POST requests are treated identically by
   applications, bluring any meaning we might apply to one or the other
   in this way.)


Because of (B) browsers have no hope in directly preventing CSRF
because they can't tell what request types should be allowed cross
domain (such as fetching images) and which should not be (such as
POSTing forms).

An attempt for fixing (A) is simply to have your web application check
the Referer header that comes with a request and make sure it matches
a trusted domain.  However, Referer headers do give some people the
privacy heebee jeebees and therefore they get turned off at times,
which would cause apps that implement this to break.  Also, old
versions of Adobe Flash allowed one to send arbitrary HTTP headers
cross-domain, so in the early days, this mitigation was thrown out
(though in modern times, it may actually be a reasonable solution).

Because of this history, web applications and frameworks have been
forced to implement cryptographic cookie protocols of their own to
validate that requests really did originate from their sites.  They
embed unpredictable tokens in forms and in URLs and then check those
against server-side data in one of several ways.  Having web
developers and framework developers do crypto has not turned out well
in the past, and I presume it will continue to go poorly.

One simple fix (from a technical perspective, not a standards
perspective), would be to introduce a new HTTP request method (let us
call it "ACTION" for the moment), which behaves more or less like
POST, but is explicitly required never to be used cross-domain.  Then
application implementors could just use ACTION in their forms and
browsers could enforce protections against CSRF instead of making
application developers do it upon receiving the request.  In some of
my past reading of proposals on how PUT is supposed to behave, I did
read something about it having similar restrictions, so perhaps it
could be used for this purpose.

Failing that, as a final possibility (and the reason I am posting this
here) is that we could rely on a better HTTP authentication mechanism
to help us enforce CSRF protections.  Since Referer logic is already
baked in to browsers, and any HTTP authentication mechanism would also
need to be baked in to browsers, why not bake something like Referer
into the HTTP authentication mechansim to help application developers
validate the origin of requests?  Essentially, make Referer
information more reliable and more privacy sensitive.

The most obvious approach would be to require an origin domain
parameter in the HTTP authentication mechanism, have it signed, and
then let application developers check that upon receipt.  

However, this has potential privacy problems, just like Referer does.
So, to help protect privacy, one could instead include a simple salted
hash of the origin domain.  Application developers (or more likely,
development frameworks) can still check a white list of trusted
domains against the hash, or even check for black listed domains if
they really wanted to, but it wouldn't immediately reveal what domain
was the origin.  Referer can continue to be used for non-security
(advertisement tracking, whatever) purposes.

I know this idea is half-baked, but I thought I would try to start a
discussion.  Thoughts?

tim