kentonv / ssjekyll

"Hacker-CMS" Sandstorm App mashing up Jekyll, Ace Editor, and jsTree
Other
67 stars 18 forks source link

feature request: webmention receiving (and display of comments, likes, reposts) support #3

Open tantek opened 9 years ago

tantek commented 9 years ago

I just "liked" this post https://blog.sandstorm.io/news/2014-07-21-open-source-web-apps-require-federated-hosting.html from my own website here: http://tantek.dev/2015/018/f1

If Hacker CMS supported receiving webmentions http://indiewebcamp.com/webmention, then I could send a webmention from my site to blog.sandstorm.io's webmention endpoint to notify it of my "like".

By adding display of received webmentions, e.g. comments, likes, reposts, then peer to peer likes, reposts, and replies could show up on Hacker CMS blogs.

One "quick fix" would be to support receiving webmentions using https://webmention.herokuapp.com/ which others using static file based systems like Jekyll have been using to both receive them, and show comments, likes, reposts via a JS embed.

kentonv commented 9 years ago

Hi Tantek,

I'd love to support webmention.

Right now, a Sandstorm app can export a public HTTP API, but there is a particular requirement that I don't think webmention clients will satisfy: requests to the API must have an Authorization header of the form Authorization: bearer <secret-token>. By convention, we write URLs to such APIs as https://<host>/<path>#<secret-token>. This is also known as a webkey.

Do you think it would be reasonable to extend the webmention protocol to support webkeys? The logic would simply be "if the endpoint URL contains a # character, split on that character and send the text after it as an Authorization token" -- pretty simple.

I know that webmention initially feels like something that shouldn't need authorization, but I think there are some decent reasons to want it. One can imagine a private community or corporate network in which people want to webmention each other.

For background, there are a couple important reasons for our funny way of doing APIs:

  1. It prevents an app from using an API to serve web content directly into a browser window, because a regular browser window will never sent an authorization request in the appropriate format. This is important to us because as soon as content is displayed in a browser window, all kinds of web security concerns kick in. On the other hand, when the API is only accessed via XMLHttpRequest (which can set the necessary Authorization header), these security concerns are avoided.

    (Note that when apps are displayed inside the Sandstorm UI, they are served off a random per-session hostname, which helps mitigate many security concerns, but this doesn't work for APIs because they obviously need a stable endpoint URL. And apps like ssjekyll, Wordpress, or Ghost, which serve a public site under an arbitrary domain, do so as static content, which also mitigates most security problems, but again obviously doesn't work for APIs.)

  2. We actually host all APIs for the server at the same endpoint and use the authorization token itself to route the request. This trivially proves that there is no way to bypass an API's access control: if you have the token, you can access it, and if you don't, then you cannot even express a request to it. This is a fundamental property of capability-based security, on which Sandstorm is based.
funwhilelost commented 8 years ago

I'm curious what the state of this is. It sounds like the SPK will define an endpoint and Sandstorm will inventory these and issue tokens for access (after a user authorizes it?). This opt-in method of exposing endpoints make a lot of sense. For Jekyll to publish the endpoint it would need to be aware of the URL that was created (following the convention noted above). The static HTML would be rendered to advertise the webmention URL:

The example URL would be transformed from:

<link href="http://alice.host/webmention-endpoint" rel="webmention" />

To:

<link href="http://sandstorm.alice.host/arbitrary#token" rel="webmention" />

I guess the big gap is in making Jekyll aware that it's endpoint is actually transformed to something else. Is this something that will be built into Cap'n Proto?

kentonv commented 8 years ago

@infamouse So, HackerCMS hands off raw HTML to Sandstorm to serve. But an app is not allowed to generate a token to itself, because if it can do that, it then potentially can leak that capability over any bit stream (including covert channels, e.g. by CPU timing fluctuations to another process on the same machine but in a different sandbox). We consider it an important security feature that capabilities can only be transmitted across other capabilities, not bit streams, as this is necessary to claim any kind of confinement. Of course, confinement is hardly important for something like HackerCMS, but we can't automatically determine whether the user is expecting any particular app to be confined.

Some possible solutions: 1) The user can always manually generate a webkey via the Sandstorm UI and then paste it back into HackerCMS. I imagine this makes a lot of sense for HackerCMS where the user is typically editing the raw HTML anyway. 2) We could add a feature where Sandstorm can automatically insert webkeys into static HTML by search-and-replacing for some string.

edrex commented 7 years ago

@kentonv

The recommendation to user agents to include the Referer header for non-HTTPS cross-origin requests in rfc 2616 15.1.3 is.. unfortunate.

Changing webmention so senders are required to implement web-key would be a hard sell, since senders aren't required to be authenticated. The mention itself is authenticated by fetching the allegedly-mentioning resource (maybe HTTPS-only, depending on the receiver) and scanning it.

I understand that you don't want to allow Sandstorm Apps to declare a URL as not requiring auth because you don't want them to leave the barn door open. What about introducing an API which allows the app to request a single-purpose receiver URL from the system, which it could then embed in static documents as a webmention endpoint?

If we do fall back to hosting the webmention collector on an external domain such as https://brid.gy/ or https://webmention.herokuapp.com/, can Sandboxed apps request a capability to make requests to a known URL? If so then the collected mentions could be pulled in at site build time rather than by the browser at render time.

btw, I found this issue while researching whether anyone had tried packaging Known for Sandstorm. I think Known could be a killer social app for Sandstorm, but I feel like it might not be supported by Known devs, in which case I wouldn't advocate for it. @benwerd.