GWS II discussion topics - Security

Russ Allbery eagle at eyrie.org
Tue May 23 18:28:35 CEST 2023


Paul Harrison <paul.harrison at manchester.ac.uk> writes:

> We we encouraged not to discuss the specifics of
> https://sqr-063.lsst.io/ at the interop, but there was one general topic
> that should have been discussed, because as a result of that note there
> is a perception that the “VO is insecure” - this is a dangerous
> reputational message to be circulating that I believe is based on an
> incorrect analysis and is only true in the sense that “the Internet is
> insecure”.

Hi Paul,

Thank you very much for the discussion here!  Let me provide a bit of
background that may be helpful in understanding SQR-063 in context, and
then I'll explain where I'm coming from with the points that you discussed
in more depth below.

The reason why we wanted to focus on the broader topic rather than the
specifics of SQR-063 at the interop was because the broader directional
questions seemed like a more important and useful use of rare in-person
time.  Discussing specifics seems better done on the mailing list and
eventually with draft language.  I am very happy to discuss SQR-063 here
and dig into the specifics of where it may be useful feedback for future
iterations of the standards.

I want to be very clear what SQR-063 is: it's a collection of informal
notes from someone (me) new to the IVOA protocols of things I noticed
while writing an implementation.  It's not anything more than that, and in
particular it was never intended to be a formal security analysis.  The
heading in SQR-063 is "Security concerns" quite intentionally; these are
just things I was concerned about over a year ago when I wrote a SODA
implementation.  Concerns are not vulnerabilities and may not even be
correct (as indeed one was not).

I am in absolutely no way asserting that "VO is insecure" or anything like
that.  I have serious professional objections as a security person to that
sort of statement about any protocol.  (I have a whole rant about the poor
way security teams often communicate with others that I will save for
another time.)  Security is not a binary; protocols are not "secure" or
"insecure."  Security is always and forever a context-specific trade-off,
where things appropriate for one environment may not work in a different
environment.  Sometimes people (myself included) use terms like "secure"
or "insecure" informally about specific things as shorthand, but it's
sloppy, and not useful in any sort of real security analysis.

Rather, the point of the security section of SQR-063 is only "here are
some things I noticed and want to look at in more depth."  Which we're now
doing, and that's great.

You quite rightfully point out that the Internet is insecure by default.
Part of my job is to try to decrease the degree to which that's true.
What I'm looking for in a protocol is not some sort of objective security
level, which doesn't exist.  Rather, what I'm looking for is the
mechanisms within the protocol to add security controls where that's
appropriate, without breaking the protocol.

In other words, I'm not coming to this from the perspective of "this
should have been done differently."  I'm coming from the perspective of "I
want to disallow cross-site requests; how do I do that in a way that
doesn't break interoperability with protocol clients?"  An IVOA standard
is not in any sense "insecure" or morally wrong or whatever because it
doesn't have such a facility built in.  That just means I may have a use
case that isn't yet handled.  Or perhaps it is handled, and I just didn't
know where to look; that's always the best-case scenario.

> * Secondly the whole point of the VO was to make data interoperable in a
>   public way.

A quick aside on this, since Rubin has a couple of constraints here.  My
background isn't in astronomy, so I don't know how unusual they are.

* The US taxpayers via the US government have decided that our data can't
  be public for some time after it's gathered.  I have my own opinions
  about the merits of that decision, but no one who made that decision
  cares what I think.  We still believe it's useful to use IVOA standards
  wherever possible for our Science Platform for many reasons, including
  that the data will eventually become public and that we're writing a ton
  of software as part of our mission and hopefully some of that software
  will be useful to the broader community.

* For a variety of reasons related to the facilities we're providing to
  our users and various funding stream decisions that I only
  half-understand, the Rubin Science Platform is being deployed in an
  environment that pays closer attention to security than I think is
  typical for most astronomical archives.  We have a limited amount of
  institutional capital to spend on security exceptions, and I'm trying to
  save it all for things that astronomers really need to get work done,
  not for things like cross-site requests.  To the extent that I can make
  the security properties of most of our system boring, predictable, and
  "normal" to security reviewers, we preserve maneuvering space for
  astronomy-specific places where we need to do things differently.

> 3.1 - This whole argument is made from a very 'browser client only'
> perspective. As stated above in the second general principle of course
> VO protocols can be called from anywhere, so they will be inherently
> susceptible to “CSRF attacks” - that is normal usage. Of course it would
> be a bit surprising if when clicking on a picture of a cute cat an
> astronomer ran a TAP query, but when using Topcat they do want to be
> able to query multiple servers in different locations.

I'm not sure that I successfully communicated the point of this section if
you're thinking of Topcat requests as cross-site requests.  The discussion
is about browsers because cross-site requests are a concept specific to
web browsers.  They don't normally apply to non-browser clients; no Topcat
request would be a cross-site request in the normal HTTP sense, at least
unless I'm wildly wrong about how Topcat works.

The background here for both 3.1 and 3.2 is that we plan to enable, via
IVOA protocols or extensions that are faithful to the protocols, various
operations that may be quite expensive (eight-hour TAP queries, large
batch image processing) or destructive (user table deletion).  I don't
want it to be possible to trigger such actions via cross-site requests,
mostly because of the risk of denial of service attacks.  Those don't have
to be malicious and in fact often aren't; think of, for instance, web
crawlers that don't honor robots.txt (sadly more common than any of us
would like), or some JavaScript-triggered request that gets into a refresh
loop and spams requests.

The most common way that web services disallow cross-site requests in
these situations is that the protocol uses PUT, PATCH, or DELETE, which
inherently force a JavaScript single-origin policy, or uses POST with body
content type that isn't one of the white-listed simple request types.
However, the IVOA protocols use GET or POST with
application/x-www-form-urlencoded, both of which are classified as simple
requests, so that method of preventing cross-site requests isn't
available.

The next most common way to disallow cross-site requests is to require
that all such requests contain some random token in both the form body and
a cookie.  (OWASP calls this the "double submit cookie" technique, which I
am not fond of as a name, but standard terminology is good.)  This works
great for things intended to be used via a browser, but as you point out
IVOA protocols mostly aren't, so naively using this would break Topcat and
similar clients that wouldn't know how to set the cookie (nor should
they).  Similarly, the "synchronizer token pattern" requires reading a
token from the server and reflecting it in the form submission, but the
IVOA UWS protocol has no way to tell a client that's happening and
existing clients don't know how to do it.

The variant that's often used for protocols where most requests are
expected to be from non-browser clients is the custom request header
approach, where all state-changing requests are required to include a
header containing a token that was obtained from an earlier API call.
However, this requires the client understand this protocol well enough to
include that header, so again, we're concerned about breaking existing
clients.

One simple variation of the custom request header approach that we could
use here is to require every request contain an Authorization header.
This forces single-origin policy and thus prevents CSRF in exactly the
same way the custom header approach does, and it works fine with Topcat,
which already knows how to send Authorization headers and will be sending
them in the normal case for Rubin during the period where we have to
require authentication for data access.  However, the drawback of this
approach is that it prohibits using simple forms to make UWS requests; you
*have* to use a client like Topcat (or at least curl).  This makes it
harder to make ad hoc UIs, although that may be an acceptable price to
pay.

I'm not sure the best way to tackle this, but I can think of a few
possibilities.  Some of these conflict with each other, so we'd also need
a way to clearly communicate (presumably via the registry) which is in
use.

* Obviously protocols using bodies in any format other than text/plain,
  multipart/form-data, or application/x-www-form-urlencoded force the
  JavaScript single-origin policy and avoid nearly all CSRF problems as
  long as one enforces, on the server, the presence of a correct
  Content-Type header in the request.  But of course that's a significant
  protocol change, and while it may have merits for other reasons, I
  wouldn't advocate a change of request serialization protocol solely for
  CSRF protection.  (This also prohibits using simple forms.)

* In many cases, it may make sense for a service to require an
  Authorization header and not allow cookie-authenticated browser access
  at all.  I believe this case may already be covered by IVOA SSO
  protocols, and the only thing preventing us from using that approach was
  having an SSO profile for bearer tokens, which I believe is being worked
  on.

* Currently, my understanding is that DALI *requires* a compliant server
  to support both GET and POST.  While both GET and POST requests have the
  same theoretical security properties, in practice GET requests are much
  more likely to produce those unintentional denial of service attacks I'm
  the most worried about, and there are some cases where I don't think we
  will have any obvious need to support GET.  In those cases, it would be
  nice to have a way to say "this service is POST-only" so that clients
  will know to not attempt GET.  (This was the point of 3.2; the entire
  request there is just that servers not be *required* to support GET to
  be standard-compliant.)

* In cases where the explicit goal is to support POST from a form as a way
  of making a request (I can see some UI cases where that may be useful),
  I would ideally want to have the protocol mention that the browser may
  have to do a GET request to some route that would set a CSRF cookie and
  the server may have to require a CSRF token in a form field match the
  CSRF cookie.  I can see the argument that this may not need to be
  spelled out in the IVOA protocol per se since this additional
  requirement doesn't *conflict* with any IVOA protocol, so it's somewhat
  orthogonal, but it does affect the POST body and therefore in a naive
  implementation the CSRF token would potentially would show up as a job
  parameter, etc., which I don't think is desirable.  It feels like there
  may be some useful guidance here that a standard could provide.

There are probably other options that I'm not thinking of.

> The second part of the argument made in this section is that not being
> able to use CORS is somehow a problem, and there is an implication that
> CORS helps with stopping CSRF attacks.

The confusion here is probably my fault for using the ambiguous term "CORS
preflight request."  (In my defense, this is what MDN calls it.)

The security benefit here is from disallowing cross-origin simple
requests.  The way to do this is to ensure that the request is structured
such that it is not a simple request, and therefore the web browser is
unwilling to send it directly to the cross-origin web server without first
sending an OPTIONS request (in other words, initiating the CORS protocol).
In all of my use cases, the server would then decline to do CORS by
failing the OPTIONS request, thus blocking the request.  This does stop
CSRF attacks.

If the server instead continues the CORS protocol by sending a successful
reply to the OPTIONS request, this may indeed allow even more cross-site
requests than are permitted by the default simple request policy, but that
wasn't the intent here.

> 3.3 - Here there is a general misunderstanding of what the namespace
> reference is, and it being http not https does not change the security
> landscape at all. It was probably design error to have namespace looks
> like they do - W3C certainly regretted it -
> https://www.w3.org/blog/2008/02/w3c_s_excessive_dtd_traffic/

You are of course entirely correct.  For some reason I thought I saw a
DOCTYPE reference somewhere, which would have this concern, but indeed all
of the URIs are namespace identifiers, which are not URLs and are never
retrieved by XML validators.  I'll delete this section to avoid any
further confusion.  Thank you for the correction!

> 4.1 - XML is also singled out for security problems - again, I really do
> not think that this is exceptional - all computing subsystems have
> security issues.

While it is true that all subsystems have security issues, the more
complex a protocol is, the larger its attack surface is.  Unfortunately,
XML is a very complex encoding format, considerably more complex than
JSON, and therefore has a much larger attack surface.  You can see this
reflected in the steady stream of CVEs for XML parsers and XML-based
protocols over the years.

I want to be very clear that this is not, by itself, a reason to change
serialization formats.  Security is always a trade-off; often the
additional complexity that gives rise to a larger attack surface is there
to enable important features.  But pretty much any security person who is
looking at a protocol and finds that it has an XML component is going to
tell you that XML parsing has tricky security properties and you should
exercise special care around untrusted XML when implementing that
protocol.

> I note with some amusement that JSON was designed to transform directly
> into Javascript with no intervening business logic, thus making it
> pretty good vector for injection attacks.

It's of course true that you should never parse JSON in JavaScript with
eval() and instead should always use JSON.parse(), but this is a
JavaScript-specific security problem and, in my opinion, falls under the
general heading of needing developers to use their programming language
and libraries correctly.  This is unavoidable; there's always a way to
introduce security vulnerabilities by ignoring security best practices in
whatever language you're using.  Apart from trying to make the obvious
implementation approach also be a relatively secure approach, there's not
much standards can do to address this.

The concern with XML is a bit different.  There are several features in
the XML protocol that inherently have annoying security properties when
parsing data from untrusted sources (for example, external entities and
recursive entity expansion).  In order to fully protect against XML
attacks, a parser has to either accept only a subset of the protocol and
reject features the protocol specifies (such as external entities) or
apply heuristics to reject otherwise syntactically valid documents (such
as the Billion Laughs attack).  This is not the case for JSON simply
because JSON is a much simpler protocol and doesn't have equivalent
features.

A good XML library will handle most if not all of this for you, but my
prior experience with XML-based protocols is that there's a lot of ad hoc
XML parsing out there and not a lot of understanding of where XML parsing
can be risky.

-- 
Russ Allbery (eagle at eyrie.org)             <https://www.eyrie.org/~eagle/>


More information about the grid mailing list