Skip to main content
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with: Guust Nieuwenhuis
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with: Guust Nieuwenhuis

What Files Should Live In The WwwRoot Folder?

By
Published in Comments (2)

As much as I live, love, and breathe web application development, I almost never start brand new websites. Instead, I spend decades maintaining and evolving existing web properties (think this blog, think InVision). As such, my instinct for what to do on "Day 1" of a new ColdFusion web application is a bit rusty. And, now that I'm on the precipice of taking my BigSexy Poems Angular utility and fleshing-it-out into a legit ColdFusion application, I wanted to take a moment and think about the most fundamental part of a web server: the wwwroot folder.

For the sake of this discussion, let's consider the wwwroot folder to be the root of the publicly-accessible web application. Meaning, if I were to navigate my browser to:

www.example.com/index.htm

... that index.htm file would be stored on the server at this path:

{site}/wwwroot/index.htm

As a junior developer, I just jammed everything into the wwwroot folder! Static files, dynamic files - all of it! It never even occurred to me that files could live outside the web-root. And, for the most part, defaulting to the wwwroot folder gets you pretty far.

However, files placed in the wwwroot folder are publicly accessible. Which means, they expand the attack surface of your website. Remember a decade ago when servers were getting exploited via some WYSIWYG (What You See Is What You Get) editors? This was possible because those editors uploaded attachments to a publicly-accessible folder (inside the wwwroot), allowing malicious actors to upload and then execute arbitrary code files!

We don't want that to happen. So, user-provided uploads definitely go outside the web-root.

ASIDE: The WYSIWYG attack was so clever because the applications were actually renaming the uploads once saved. But, the attackers were using load-testing software to hammer the target sites in order to execute the uploaded code-files in the nano-seconds that the uploads were still available under their original clientFilename. Really clever stuff!

Of course, we don't have to think about this from a piece-meal standpoint. Instead, we can think more generically: files that can / should be accessed directly go inside the wwwroot folder. Everything else goes outside the wwwroot folder.

Static assets, like image, font, SVG, CSS, source map, and JavaScript files are meant to be accessed publicly; so, they clearly go inside the wwwroot folder (and are hopefully delivered via a Content-Delivery Network).

Dynamic assets, like files sitting behind a paywall, are meant to be accessed publicly; but, only under certain circumstances. As such, those need to live outside the wwwroot folder (and are perhaps served-up via the CFContent tag or an S3 pre-signed URL).

ColdFusion code can go either way. Some CFML files - like index.cfm - are meant to be accessed publicly; and, therefore, should live inside the wwwroot folder. Other CFML files - like ColdFusion components, custom tags, and includes - are low-level constructs and should live outside the wwwroot folder.

NOTE: ColdFusion components (CFCs) can technically be accessed publicly if they are remote enabled. But, this is not how I use them. To be clear, this is not a judgement statement - it's just a personal preference. And, I don't like my CFCs being public.

Now, I don't believe that every single request to the ColdFusion application should route through the one index.cfm file in the root of the web-app. Yes, I do route many requests through my index.cfm file; but, only if the request isn't for another legitimate CFML file. This gives me the flexibility to have sub-folders that contain little demos and other explorations. As such, my wwwroot folder will almost certainly contain more than just index.cfm.

SECURITY ASIDE: The more "code" you make publicly available - the more "flexible" you make your application - the more you extend your application's attack surface. As such, there's nothing inherently wrong with wanting to force every single request to go through a unified execution path.

With that said, as I start to break ground on my BigSexy Poems ColdFusion application, I think I'm going to start with this general directory structure:

{site}/.cfconfig.json
{site}/server.json
{site}/Dockerfile
{site}/package.json
{site}/README.md
{site}/.gitignore

{site}/docker/
{site}/node_modules/

{site}/app/content/
{site}/app/lib/
{site}/app/vendor/

{site}/app/wwwroot/Application.cfc
{site}/app/wwwroot/index.cfm

{site}/app/wwwroot/static/css/
{site}/app/wwwroot/static/image/
{site}/app/wwwroot/static/js/

The files in the {site} folder are for all the configuration files relating to the site. In this case, I'll be using CommandBox to run my Dockerized ColdFusion development container.

The {site}/app folder contains all the files for the ColdFusion application runtime. Most of these files are private (ie, live outside the wwwroot folder). Some of them are public (ie, live inside the wwwroot folder).

The content folder is for all my ColdFusion routes / views.

The lib folder is for all my ColdFusion components, custom tags, and includes.

The vendor folder is for any 3rd-party files that I need to include (such as database drivers).

The docker folder contains anything that might be needed by the Dockerfile when building the local development image.

Now, to be clear, this is all just a theoretical work in progress. I haven't actually done anything yet. And, while this application will be powered by ColdFusion, it will also be fronted by Angular (beef cake!). I'm not entirely sure how that will all fit together yet. Meaning, where do the src Angular files go? How do I build the Angular app? How do I tell ColdFusion about the dynamically-generated filename hashes?

All to be figured out in time!

This whole post is really just me thinking out loud about how I am going to structure my site. I am super curious to hear how other people structure their site. If you have any suggestions or feedback, let me know! I'll be posting updates as I get things started.

Want to use code from this post? Check out the license.

Reader Comments

15,848 Comments

@Andrew,

Thanks for the link. It's funny, I keep googling for articles on folder organization in websites, and it's such a generic topic that it was hard to find something that really spoke to what I was looking for. I even tried looking for ColdFusion-specific articles and couldn't really find much. I'll definitely check out Adam's article - while we don't always agree, that man thinks deeply about code!

Post A Comment — I'd Love To Hear From You!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel