Very basic question.Here it goes.
The client hits a url in the server.The server can send content in the form of
static files(javascript/html).
xml/json(predominantly the purpose of this file is to return some DATA to the client).
Downloadable file-kinda zip files.For this part the server needs to set the content type property to something to let the client know that it wants this file to download of something.
My question is how does the browser differentiate between the static files and api responses(form of xml/json/string) ??
Thanks,
Gully
HTTP Headers.
There's no such thing as a "file" in HTTP. There are requests and responses, each of which consist of headers and content. The response content may be the contents of what was a "file" on the server, and may be intended to be treated as a "file" on the client (such as downloading a .zip file), but the response itself is not a file. The way that the server indicates to the client that something should be a file is through the HTTP headers.
Specifically the two headers you're talking about are:
Content-Type
Content-Disposition
The first tells the client (browser) what kind of data it's receiving. There are lots of examples, and most browsers understand what to do with most common types. The second can be used to suggest to the client that the content should be saved as a file rather than displayed. For example, the Content-Type might be for an image, and by default a browser will just display an image. But you can add a Content-Disposition header to indicate that the image is an "attachment" and even suggest a file name for it, instructing the browser to save the file (or prompt the user asking to save the file) instead of displaying it.
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.
As shown in the screenshot, I need to download all the XHR files in the network when any call made using python?
First load an URL on the domain you're targeting a file download from. This allows you to perform an AJAX request on that domain, without running into cross site scripting issues.
Next, inject some javascript into the DOM which fires off an AJAX request. Once the AJAX request returns a response, take the response and load it into a FileReader object. From there you can extract the base64 encoded content of the file by calling readAsDataUrl(). Then take the base64 encoded content and appending it to window, a gobally accessible variable.
Finally, because the AJAX request is asynchronous, enter a Python while loop waiting for the content to be appended to the window. Once it's appended, decode the base64 content retrieved from the window and save it to a file.
This solution should work across all modern browsers supported by Selenium, and works whether text or binary, and across all mime types.
I have a nodejs backend and I want to send a file download link to the client such that, the file is directly accessible by the client. The file types are JPEG and PNG. Currently, I am serving these files as data-uri but, due to a change in requirements, I must send a download link in response to the file request and, client can download the file later using that link.
Now the current workflow exposes a path /getAvatar. This path should send a response back to the client with the file link. The file, is stored in /assets/avatars relative to the server root. I know I can express.static middleware to send back static resources. However, the methods I have seen so far, res.send() and res.download() both tries to send the file as attachment rather a link that can be used later to download.
Basically, the behavior is like a regular file sharing site where, once a file is clicked, a link to it is generated which, is used for downloading the file. How can I do this?
I originally created a logic app that would, given a JSON payload, run a stored procedure, transform the results into a CSV table and then email the CSV to a specified email account. Unfortunately requirements changed slightly and instead of emailing the csv they want it to download directly in the browser.
I am unable to get the HTTP response action to tell the browser to download the file using the Content-Disposition header. It looks like this is pulled out of the request by design. Is anyone aware of another action (perhaps a function?) that could be used in place of the HTTP response to get a web browser to download the file rather than returning it as text in the response body?
It does indeed seem to be the case that the Response action doesn't support the Content-Disposition header for some reason. Probably the easiest workround is to proxy the request through a simple HTTP-triggered Azure Function with CORS enabled (or an API on your server) that just fetches the file from the Logic App and then returns it with the Content-Disposition header attached.
NB. Don't rely on <a download="filename"> - most browsers that support the download attribute only respect it for same-origin requests.
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.