Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URI in Profile triggers CORS Unsafe Request Header Byte rule #436

Open
azaroth42 opened this issue Jun 24, 2024 · 4 comments
Open

URI in Profile triggers CORS Unsafe Request Header Byte rule #436

azaroth42 opened this issue Jun 24, 2024 · 4 comments
Labels
needs discussion spec:w3c tag-needs-resolution Issue the Technical Architecture Group has raised and looks for a response on.

Comments

@azaroth42
Copy link
Contributor

In the IANA registration [1], we define a media type parameter called 'profile'. Its value is a space separated list of URIs, for which we registered six initial values. These can be composed together, and new values can be added for other "constraints or conventions".

The IIIF specifications use this functionality, for example to define the specific structure of the response in an API [2] as part of the media type. Similarly in Linked Art, we do the same [3].

However, in the WHATWG specification for fetch [4], it says that the value for the Accept header is NOT CORS safe, if it has more than 128 bytes (which multiple URIs might easily cause) or (more importantly) if the value contains an unsafe header byte. The unsafe header bytes include the character ":" ... which prevents any URI or CURIE with a namespace prefix separate by : from being CORS safe.

This means that we cannot use the JSON-LD media type as registered for content negotiation via the accept header according to the fetch specification, which was much of the rationale for the profile parameter.

To resolve this, either WHATWG would need to change fetch, or W3C/IANA would need to change the definition of the media type and give some registration function for possible profile values, then all downstream specifications would need to register a safe profile value to use.

I've added the tag-needs-resolution label, as I think that's the level this would need to run up to :(

[1] https://www.w3.org/TR/json-ld11/#iana-considerations
[2] https://iiif.io/api/presentation/3.0/#63-responses
[3] https://linked.art/api/1.0/json-ld/#introduction
[4] https://fetch.spec.whatwg.org/#ref-for-cors-unsafe-request-header-byte

@azaroth42 azaroth42 added spec:w3c needs discussion tag-needs-resolution Issue the Technical Architecture Group has raised and looks for a response on. labels Jun 24, 2024
@davidlehn
Copy link
Contributor

You say "NOT CORS safe", but I think the issue is the header will not be "CORS-safelisted"? When that is the case, a preflight request will be used. If that succeeds, the request should be sent. This doesn't seem like a blocker for using any of these headers, just a bit more server complexity than the "simple requests" CORS case that doesn't do a preflight. You probably need to setup a Access-Control-Allow-Headers to allow Accept, others as needed, and probably want Access-Control-Max-Age to cache preflight requests if appropriate.

@pchampin had a w3id.org issue with CORS and preflights the other day, where I learned more about this topic and safelists and simple requests and redirects. perma-id/w3id.org#4185 and perma-id/w3id.org#4196.

I tried a simple fetch from a browser console, and it does appear to do the above behavior. No profile will skip preflight, adding profile with URL will do one, then send the request. You do need a server setup to handle CORS headers, but then it works.

await fetch(
  "https://example.com/test",
  {headers: {"Accept": "application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded"}}
)

@BigBlueHat
Copy link
Member

Of note: https://www.w3.org/TR/dx-prof-conneg/

@pchampin
Copy link
Contributor

This was discussed during the json-ld meeting on 13 November 2024.

View the transcript

Issue Discussion

bigbluehat: We're working through the project list.

gkellogg: added issues that are class 1-3.

subtopic w3c/json-ld-syntax#436

<gb> Issue 436 URI in Profile triggers CORS Unsafe Request Header Byte rule (by azaroth42) [spec:w3c] [needs discussion] [tag-needs-resolution]

gkellogg: might just create "tokens" for profile paraemters.

gkellogg: tokens not being namespaced is mitigated by the fact that the media-type is the namespace.

bigbluehat: So, it treats the media-type as the namespace.
… Profile parameters not having a colon is wide-reaching

gkellogg: not sure how we update guidance for using profile parameters.

bigbluehat: This would be a breaking change for web annotations.
… That would mean web annotations needs their own media type.

niklasl: dlehn's reply may mean this isn't as horrible as it seems.
… I think the datasets working group has done something with this.

pchampin: This doesn't seem to be a problem where things can't work, but making them work is tricky, due to pre-flight requests.
… If we expect a server to support profile-based content-negotiation, it doesn't come automatically.
… If you want to support this, you'll also need to support pre-flight requests.

<bigbluehat> q|

pchampin: This is difficult to configure and easily forgotten.

<gb> Issue 436 URI in Profile triggers CORS Unsafe Request Header Byte rule (by azaroth42) [spec:w3c] [needs discussion] [tag-needs-resolution]

bigbluehat: There were some suggestions for defining enumerated values (tokens).

<pchampin> I think it wouldn't hurt to define "short names" for the profiles in addition to the currently defined IRIs

bigbluehat: The key is to not make it a breaking change.
… This would affect the media-type registration.

niklasl: Aren't link headers defined similarly, where there are pre-defined tokens and IRIs may also be used.

bigbluehat: Browsers have made decisions which are affecting what we can do.

<bigbluehat> > When processing the "profile" media type parameter, it is important to note that its value contains one or more URIs and not IRIs. In some cases it might therefore be necessary to convert between IRIs and URIs as specified in section 3 Relationship between IRIs and URIs of [RFC3987].

https://www.w3.org/TR/json-ld11/#iana-considerations

<niklasl> application/ld+json;profile="http://iiif.io/api/presentation/3/context.json"

niklasl: I think it would be good to add tokens. Rob's specific problem are more about the other uses of profiles.
… I wonder if our solution would be considered a solution for the issue; maybe parts of the issue can't be solved in the JSON-LD spec. Might recommend IIIF to use profile negotiation.
… But, using pre-flight does work, so that would be on their end.
… It's more that we put forward the design pattern and it has become more tricky.

bigbluehat: The ramifications of this are not just expand/compact/... Rob's point is for other specifications that used the same pattern.
… No we know to avoid it.

<niklasl> See also: https://www.w3.org/TR/dx-prof-conneg/ (and https://profilenegotiation.github.io/I-D-Profile-Negotiation/I-D-Profile-Negotiation.html )

bigbluehat: There's reason to document this in the best-practices document. How this affects other specs would mean that they cannot treat profile as being extensible, and will need a new media type.

gkellogg: we might create a registry to allow other specifications to add their profile parameters without needing a new media-type.

bigbluehat: niklasl shared a document on using the profile parameter for content negotiation.

pchampin: Reaching out the that TAG would be a good idea, as other specs rely on this, and they would be impacted.
… I'd like to see their thoughts and how much we should make the effort to try to change this.
… Regarding the spec, note that this is a working draft which has been inactive for a while. This might not be the strongest argument to take before the TAG. (The dataset exchange WG)
… Part of the reason that spec is stalled is that there are contentious discussions with IETF on where it belongs.

<niklasl> From the dx-prof-conneg draft: During 2018, DXWG members had a longer discussion with the JSON-LD WG at the annual forum TPAC in Lyon, France and it was concluded that the "profile” parameter in the Accept and Content-Type headers should be seen to convey profiles that are specific to the Media Type [such as JSON-LD's expanded .... ]

pchampin: But, is there enough interest in IETF to continue the work?

niklasl: There are aspects of the draft that goes into the profile parameter of the media type is the right way to go.
… The design of IIIF and Activity Streams I appreciate more when not looking at it from an RDF perspective.
… These are more useful at the intersection of JSON and RDF, which makes it easier to create specifications in a distributed way.
… If I believed (from RDF perspective) that format is irrelevant, general content negotiation works well.
… I can see how the TAG might argue from one of these perspectives. Maybe we shouldn't invent media-types on the fly.

<pchampin> https://www.w3.org/TR/vc-data-model-2.0/#media-type-precision

pchampin: Regarding the value of using JSON-LD media-type with parameter vs a new media-type, VC has had to rely on this for a while.
… The current solution is to have a dedicated media-type with additional language to explain the relationship between the two media types.
… We might point other specs to that solution.

<niklasl> +1 to mentioning that "third" point of view (very pertinent IMHO)

bigbluehat: I think we need to move on and come back to this issue.
… It would be great to write some of these things up on the issue so that we have something coherent to bring to the TAG.
… IETF has shifted their approach, and we're stuck in the middle. In the mean time, if we can collect thoughts in the issue.
… I don't think we know enough to lay out the preferred solution.
… If we go the short-name route, we run the risk of turning into a registry.

<bigbluehat> w3c/json-ld-syntax#443

<gb> Issue 443 `@protected` creates unresolvable conflicts when the same term is defined in two contexts top-level (by trwnh) [spec:editorial] [wr:commenter-agreed-partial] [class-2]


@azaroth42
Copy link
Contributor Author

Thanks for discussing it! I think we can close this particular issue -- the pre-flight does indeed solve the issue, and implementation notes in various specs in future versions could head it off completely.

That said, at a conference in Amsterdam this week there were at least 6 organizations wanting a solution for profile negotiation for non JSON-LD serializations where the profile param isn't available, and (sorry Rob, Lars and Nick) not as complicated as https://www.w3.org/TR/dx-prof-conneg/ ... just to update and try to get acceptance for Accept-Profile in the IETF: https://datatracker.ietf.org/doc/html/draft-svensson-profiled-representations-01

(The q values being one driver for this, rather than the link header on the request approach of dx-prof-conneg)

Perhaps there's sufficient convergence to at least have a call or two?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs discussion spec:w3c tag-needs-resolution Issue the Technical Architecture Group has raised and looks for a response on.
Projects
Status: Discuss-Call
Development

No branches or pull requests

4 participants