mnutt / davros

Personal file storage server
Apache License 2.0
298 stars 35 forks source link

Wishlist: Preview PDFs #28

Closed ocdtrekkie closed 8 years ago

ocdtrekkie commented 8 years ago

I was kinda sad when I uploaded two PDFs I often share to people to a Davros grain that they weren't previewable. I could probably link them using web publishing, I suppose, but I found it odd to get "No Preview" for PDF format in the Davros UI.

mnutt commented 8 years ago

I seem to remember that I was having lots of trouble embedding a PDF in the preview. I try not to serve any files directly from WebDAV without Content-Disposition: attachment, to prevent XSS attacks, so for previews I end up using iframes and XHR. I tried a lot of ways to download the PDF as a binary blob via XHR then write it into the iframe, without much success. One method I'd like to explore more is if I could identify browsers that support CSP I could serve them content directly with CSP enabled.

ocdtrekkie commented 8 years ago

I don't know if this is helpful or not of a thought, but I wouldn't mind if it even maybe put it in a new tab as an option or something for now. Because being forced to save a PDF file to then open it to view it is an experience I haven't had with a desktop web browser since... a long time.

kentonv commented 8 years ago

Hmm, can PDFs contain script? Is there actually any XSS risk?

FWIW we got some feedback today from a user at a law firm who really just wants PDFs to open with the browser native PDF renderer, and was disappointed that Davros didn't provide this.

kentonv commented 8 years ago

Also, what if you open the document in a sandboxed iframe? Then you should be able to direct the browser directly to the file, but cause it to be opened in a different origin.

We should perhaps also support content-security-policy in WebSession...

mnutt commented 8 years ago

The challenge I've had up to this point is that I only have one origin to work with. (the one that is displaying the Davros UI) With some formats it's possible for me to create an iframe without a src and then inject content into it, but I haven't had any luck doing that with PDF.

Right now there's a pretty clean separation: the UI is just a client-side ember app, which is served at the root. A webdav server is mounted at /remote.php/webdav, which is protected from XSS by setting a Content-Disposition: attachment header for all requests. Davros does previews by either using xhr to fetch content from the webdav server, or using <img>, <video>, or <audio> to display inline. These particular tags don't care about the Content-Disposition header, whereas anything you add as the src of an <iframe> will.

If I had a separate origin to work with, I could freely serve GET requests from it and forego the Content-Disposition header.

mnutt commented 8 years ago

One issue I saw with CSP header was that I don't believe browsers advertise their support for it on request, so it's impossible to know whether the client will be able to honor it. I can check for support for the iframe property, but haven't figured out a way to figure out from an HTTP request that it's destined for an iframe.

If I could enumerate all of the content-types that could potentially serve html / something that executes js, I could just force those into Content-Disposition: attachment. I just don't know if some browsers will try to render an html page if you serve it without a content-type.

kentonv commented 8 years ago

Hmm, maybe you could specifically serve PDFs without Content-Disposition -- assuming it's really true that they can't contain scripts, which I'm not 100% confident about, but it can probably be googled.

Regarding whether browsers will infer content types based on content, I suppose we should set X-Content-Type-Options: nosniff on all responses to prevent this.

mnutt commented 8 years ago

This is coming in v0.16.0, released in the next few days.

mnutt commented 8 years ago

This is live in v0.16!