Draft CORS guidance for an IVOA JSON protocol (was: x-www-form-urlencoded prohibition)

Markus Demleitner msdemlei at ari.uni-heidelberg.de
Mon May 27 08:49:27 CEST 2024


Hi Russ,

On Thu, May 23, 2024 at 12:18:10PM -0700, Russ Allbery via grid wrote:
> hypothetical future RESTful JSON protocol.  We also need to start drafting
> guidance at some point anyway, so I may as well give it a shot now to make
> this more concrete.

Thanks for writing this up.  I think your proposal sounds both
reasonable and doable.  I have one extra thing to add:

> 1. The service is unauthenticated.  CSRF concerns do not apply and you
>    should use an open CORS policy.  To do this, register an OPTIONS
>    handler for every API route (usually one catch-all OPTIONS handler is
>    sufficient if you don't have different policies per route) that
>    responds with a 204 code and the following headers:
>
>        Access-Control-Allow-Origin: *
>        Access-Control-Allow-Methods: GET, POST, OPTIONS
>
>    You may also want to send Access-Control-Allow-Headers if your web
>    service accepts non-simple-request headers, and
>    Access-Control-Expose-Headers if your service returns extra headers
>    that should be readable by JavaScript.

Since this is, at the moment, by far the most common case, there
is a large installed base, and software exploiting this (in-browser
clients) is going to be written more or less from scratch anyway, I'd
say we can make lives still easier for software that does not handle
credentials at all.

In the Registry, we have always had the securityMethod element on
interfaces; it has always been more a stand-in rather than something
operationally usable;  at the moment, it is represented in RegTAP
like this:

  Hence, RegTAP 1.2 does not attempt to map securityMethod except
  through the authenticated_only column which is required to be 0
  when there is no securityMethod or at least one securityMethod
  without a standardId on an interface, 1 otherwise.

-- which is a bit too restrictive for what we are up to now.  To my
own surprise,

  select count(*) from rr.interface
  where 1=authenticated_only

returns a whopping 46 (of 114622 interfaces in total) at the moment;
I suspect that many of them are spurious, but investigating that is
for another day.

Now, I'd say we can use securityMethod to indicate "this is a
service for which CSRF may be an issue"; basically, we'd have to come
up with a pattern for "auth *may* be in use on this interface" (as
opposed to "*is* in use in this interface", which is the current
interpretation.  This sounds very doable, and I'm happy to
collaborate with anyone trying to do that, both regarding VOResource
and RegTAP changes, which I think I could prototype at a moment's
notice.

I'd expect that would result in a ward_off_csrf column (name TBD:-)
analogous to the current authenticated_only in RegTAP's rr.interface.
Once we have that, we can say

* 'If you handle credentials, register your service with
  <securityMethod wardOffCredentials="True"/> and implement CSRF
  mitigation as per <whatever>' on the one side,

* and 'In-Browser clients MUST perform pre-flight checks and do
  <whatever> when rr.interface.ward_off_csrf is 1.  They MUST NOT
  expect other intervaces to implement CSRF mitigation measures.

I think that's a reasonable compromise between accomodating
(some level of) CSRF protection and keeping things simple for
everyone not bothering with in-browser clients *and* credentials,
which, I do hope for practicality and usability, will still be the
overwhelming majority of services in the VO's future.

Thanks,

           Markus



More information about the grid mailing list