Is it posible to prevent direct PDF file downloading but allow read trought iframe or another method?
Denying file extension on Reques Filtering on IIS 8 will also prevent read the PDF file on an iframe. Is there a way to prevent direct download but allow read?
Taking the question as uncoded NO the format of a PDF is a bitstream of mixed encodings and "relative" decimal addresses, that needs decompiling ONCE it has an "absolute" download filename.
Thus to view the text on a display or paper it needs to be decoded in the device that can render the full file stream contents using a CPU (there are means to dribble a modified 2way transport but not cheap on resources). That can be a print server or printer or a users pdf viewer in or outwith the html editor we call a browser.
Therefor the PORT in PDF means it needs transPORT to the device. In the Public Domain That's done by Hyper TEXT TransPORT. We call that a Download or Upload (depending which end point you are).
Once the data is received in the viewer / editor it can be converted into screen pixels.
Related
I have a web application where user can upload and view files. The user has a link next to the file (s)he has uploaded. Clicking on the link will open the file in the browser (if possible) or show the download dialog (of the browser). Meaning that, if the user upload an html/pdf/txt file it will be rendered in the browser but if it is a word document, it will be downloaded.
It is identified that rendering the HTML file in the browser could be a vulnerability - Cross Site Scripting.
What is the right solution to this problem? The two options I am currently looking at are:
to put Content-Disposition header in the response to make HTML files downloaded instead viewed in the browser.
to find some html scrubbing/sanitizing library to remove any javascript from the file before I serve it.
Looking at the gmail, they do the second approach (of scrubbing) with having a separate domain for the file download - may be to minimize/distract the attack surface. However in this approach the receiver gets a different file than what was sent. Which is not 'right' in my opinion; may be I am biased. In my case, the first one is easy to fix. But I wonder if that is enough, or is there any thing that I overlook!
What are your thoughts on these approaches? Or do you have any other suggestions?
Based on your description, I can see 3 posible attack types (maybe there are more):
Client side code execution
As you said, your web server may serve a file as HTML and run javascript code on the client. This can be avoided with Content-Disposition but I would go with MIME types control through Content-Type. I would define my known type of files (e.g. pdf, jpeg etc.) and serve them with their respective MIME type (e.g. application/pdf, image/jpeg etc.). Anything else I would serve it as application/octet-stream.
Server side code execution
Althougth I see this as an out of topic attack (since it involves other parts of your application and your server) be sure to avoid executing files on the server (e.g. PHP code through LFI). Your webserver should not access directly the files (e.g. again PHP), better store them somethere not accesible through a URL and retrive them on request.
Think if here you are able to reject files (e.g. reject .exe uploads) and ask the user to zip them first.
Trust issues
Since the files are under the same domain, the files will be accesible from javascript (ajax or load as script) and other programs (or people) may trust your links. This is also related to the previous point, if you don't need unzipped exe files, don't allow them. Using an other domain may mitigate some trust problems.
Other ideas:
Zip all files uploaded
Scan each file with antivirus software
PS: For me sanitization would not work in your case. The risk of missing something is too high.
I would like to know if there is an JavaScript API for Excel to tell the size of an Excel file.
Could anyone help?
No. The browser (including JavaScript) don't access files on the clients computer i.e. Excel file. Upload the file to the back-end, and allow the server to analyse the file, and send result back to client/browser (JavaScript)
I'm trying to download a file from a browser using socket.io-stream. In a basic form, this is actually doable and there is a working example here.
However, that solution:
First streams the file contents to the browser using socket.io-stream.
Assemble the chunks in the client as a blob.
Create a hidden link to the blob location.
This forces the browser to contain the whole blob in memory before it can initiate the download. I'm working with really large blobs, so that is not advisable.
I would prefere to download the stream directly, instead of buffering it in memory in the browser.
Is that possible?
I know this is easy to do just with plain HTTP, but there are some reasons that make this simplest option not available in my case.
I have a web resource which returns json content with Content-Type:application/json. Usually the content is displayed in browser directly but sometimes it's not, instead, a download prompt shows.
I know there's a header Content-Disposition:inline/attachment which can explictly tell browser whether to download or show. But if I don't specify this header, how does browser decide? What's its strategy?
From Mozilla's File types and download actions (emphasis mine):
When you click a link to download a file, the MIME type determines what action is taken. If you see an "Opening " dialog asking if you want to save the file or open it with a specified application, that normally means that your Mozilla application cannot handle the MIME type internally, no plugin is installed and enabled that can handle it and you have not previously selected a download action or helper application to always use for that type of file.
The browser comes preconfigured to handle basic formats like images. Plugins (which may be bundled with the browser) add handling for various common file types like pdfs. There can also be "helper applications", which means the browser downloads and forwards the file automatically to the application (such as a torrent magnet link opening your torrent client)
Everything else, it will ask until a user binds a default action (if the Content-Type is application/octet-stream, you can't set a default action). The other browsers work the same.
What Content-Type is specified in the header? If the browser doesn't know what it is, it probably defaults to application/octet-stream and prompts for download.
Here's a brief blog about it.
There's a very popular PDF.js library on GitHub that lets you upload/view PDF files from the browser.
Demo: http://mozilla.github.com/pdf.js/web/viewer.html
First of all is it possible to stream in real-time my local PDF file to multiple clients that would connect to my website? Secondly, can I do it without modifying the PDF.js source code?
Ideally, all users should see the same page with gray background indicating no PDF is loaded. Then any one user can upload a PDF. When that user upload a pdf file, it should be displayed for all other connected users right away.
What's the simplest brute-force solution to this?
You have to modify at least viewer.js (and viewer.html). Let's take an existing chat program as a base, e.g. http://psitsmike.com/2011/09/node-js-and-socket-io-chat-tutorial/
To keep viewer empty at start, remove: PDFView.open(file, 0); line in webViewerLoad().
Send the pdf data to the chat instead of opening in the viewer immediately: in webViewerChange() replace PDFView.open(uint8Array, 0); with code that will send btoa(bytesToString(uint8Array)) to the "chat". When the open-document-message from the chat is received you can process it the following way: PDFView.open(stringToBytes(atob(data)), 0);
Now navigation: if the viewer is a master, send pdfOpenParams in updateViewarea() to the "chat". On the slaves, execute navigate-message as PDFView.setHash(hash.substring(1));
Hopefully that helps.