Directory Structure and Security

I use an entire directory for my CSS so my root directory is just public-facing PHP files. Same with Javascript, Images, and many other common file types. The only harm it does is cause an extra 4 bytes per page… not really a big deal even to optimization nuts like me.

You can do better than that?!

You may have access to your local bank, but do you have access to every room in the bank?

You have access to your account on a system, but not everyone’s accounts.

It is not being overly sophisticated prohibiting people seeing what is in a directory, but it cannot hurt. For instance, maybe I don’t want you downloading all of my images, content, etc. Then preventing people from seeing what is in a directory cannot hurt.

ESPECIALLY when it comes to files like images, CSS, javscripts… The end user ALWAYS has access to them anyways.

IF they know something is there.

It is one thing to know that debbie.png is in my “images” directory, but why advertise that “deathshadow.png” is also in there?

Changing what the directory it’s in is names isn’t going to change that… especially since I can just hit “information” in opera to pull up links to CSS and Scripts, or ‘document size’ in the FF web developer toolbar to pull up EVERY link (assuming FF 3.5- since that’s STILL broken 3.6+, making FF useless for me since that’s about the only tool in it I use on a regular basis)

I don’t follow you…

You’re going to have to path to it in the markup or CSS ANYWAYS, so all they have to do is hit “view source” and if they can READ, they can find it.

I understand that if you can see it in your browser then you can read it and figure out where it came from.

I was simply proposing protecting people from casually walking through every directory and seeing everything in every directory.

There is a difference.

Goofy/obscure names are just going to make your job harder, and have ZERO impact on security.

Really? Not from any security articles I have read when it comes to things like protecting database access, etc.

Though… if you need an entire directory JUST for CSS, there’s probably something wrong with your CSS… and you’re probably uptree and/or root linking for the images making your directory structure more complex than need be.

I gotta hear an explanation on this one!

What, you put everything in the Web Root?! :rolleyes:

Debbie

For all includes??

I have heard about keeping your database configuration file (usually an “include”) outside of the Web Root, but not all PHP includes?! :eek:

Debbie

The part you didn’t follow was him talking about tools you can use to list all the files loaded in a page, then a random rant about something in FF3.6 being broken. :wink:

Goofy/obscure names are just going to make your job harder, and have ZERO impact on security.

I do actually agree with him on this one. Security through Obfuscation is a valid technique, but it really isn’t that great for the trade-off of all the extra work you have to do.

Having a strong password is important (and maybe your user), but obfuscating your database name, tables, columns, etc., is a bad idea.

I think there needs to be a distinction made here.

You’re probably thinking about things like a header.php which you include on every page, but it mostly contains HTML. These kinds of includes are perfectly valid being in your root directory. Depending on the size of the project I sometimes have it in the root (smaller), sometimes in a folder (larger).

Stormrider is most likely talking about files which contain things like class definitions and what not. This are almost always in some other folder.

(Apologizes if I’m off on my assumptions. =p)

I never said that, but having a directory called “admin” can’t be a good idea either! :wink:

Debbie

Okay, that makes sense. I never thought about things to that degree.

Are there any set-backs?

(Do you even have access outside of the Web Root on a VPS?)

Debbie

Is it linked to from a page on the site? If the answer is no, what is it DOING there?

Mind you, I saw that a lot cleaning up other people’s messes (which is/was my specialty) where you’d see directories FULL of garbage that wasn’t used ANYWHERE on the site – mixed in with stuff that was.

WHAT THE?!?!?

All I can figure is you are talking about stuff that isn’t actually used on the website in question – if it’s USED on the site the user can find it - PERIOD… that’s what I’m saying… and why this:

Makes me ask “Then why is it even ON the server in the first place?!?”

That’s what passwords are for – knowing a table name, or subfunction name doesn’t do you ANY good if you don’t have permission to use it… and once they have permission to use it you aren’t going to slow them down one bit with goofy naming schemes.

At least if the code is written in ANYTHING resembling secure practices. As I have seen proven time and time and time and time and TIME again the past three decades, security through obscurity is no security at all. See BlackBerry at Pwn2Own.

Think before saying something like that… if you cannot link uptree or rooted, that means what direction can you go? DOWN-TREE.

The three directory pathing methods:

uptree: …/images/image.png – /FAIL/

rooted: /images/image.png – /FAIL/

downtree: images/image.png – /WIN/

  1. Functions the user can call directly and/or static files in root; This is why I prefer to have a SINGLE index.php through which ALL functions are called… single valid .point of entry/exit means only one place they can hack.

  2. Subfunctions and things the user should not call directly for php in a subdirectory (like “sources” or “libraries”). Said files return NOTHING if called directly containing ONLY objects and functions. Secure functions (like returning SQL login info) I’ll typically code to throw if they aren’t called by the index.php in the directory above it. This also means NO global variables, no security information in DEFINE, etc, etc…

Off Topic:

Those two combined are where 90% (pulling a percentage out of my backside) of CMS have their gaping security holes.

  1. Content images (aka what should be in IMG tags) in a subdirectory so you can point DOWN-TREE. Likewise content files like downloads, movies, music can go in obviously named subdirectories down-tree of root.

<img
	src="forums/images/lookAtMe.png"
	alt="Yours Truly"
/>

  1. CSS and theme code can go in a nice easy directory named “themes” and you can even do easy multitheming with a subdirectory

<link
	type="text/css"
	rel="stylesheet"
	href="themes/[i]themename[/i]/screen.css"
	media="screen,projection,tv"
/>

  1. images called by the CSS are (or should be) inherently presentational, tied to the skin… so put those in a subdirectory of where the CSS is located.

body {
	background:#DEF url(themes/[i]themename[/i]/images/bodyBackground.png) top center;
}

All pointing down tree – markup calls css, images and scripts, so markup root, css images and scripts subdirectories. CSS calls images, put the ones that are CSS related under the CSS directory… in other words structure your page the same way it’s called by the browser! – such a radical concept; not.

The moment you resort to rooting (/) or up-tree (…/) you have to call your entire directory structure into question. Work WITH how the server and user agent works, not against it! Of course, I also filter ANY user input/value that might be translated into a directory to remove …/ on purpose, so as to prevent up-tree hacks (like the SMF/myBB/vBull avatar vulnerability from last year)

… and if it’s NOT something that actually appearas on the website, what is it doing in a directory with stuff that is? Either put it in a subdirectory behind a password, in a subdirectory with a index.html to prevent dir listings, or just don’t put it on the server in the first place.

After all, the only reason to put files on a server is for people to get access to them… you don’t want people seeing them, don’t upload them.

Of the four filetypes you listed, only “Includes” makes the LEAST bit of sense for what you are thinking; but frankly if those includes are written PROPERLY so they don’t output anything when called directly – by wrapping anything and EVERYTHING they do in functions or classes/methods – and by not defining anything that could be mis-used, and adding a throw so only certain files can request secure information… The name of the directory or even their pulling a listing shouldn’t matter.

But again, there’s a reason I’d like to see <?php and ?> removed from PHP completely

I never said that, but having a directory called “admin” can’t be a good idea either!

Why? If you control your site from there, why make it hard to remember? Is crazyfuzzykittenz111a325 better? Sure, I can’t guess it. But, if the site is secure and can’t be hacked, what’s it matter if they can see it?

The problem with obfuscation, aside from the usability issue, is that it is often just a band-aid for not fixing other problems. It also makes it harder for other developers to work on it, for you to remember what’s what, for you to be able to type it properly every time, etc.

The cons greatly outweigh the pros in many situations.

Okay, that makes sense. I never thought about things to that degree.

Are there any set-backs?

(Do you even have access outside of the Web Root on a VPS?)

Depending on your file permissions, probably. Apache isn’t bound to the web root, it is just restricted by it’s user/group, just like any other user.

There aren’t any real setbacks, other than having to be a bit more careful with what you’re doing (for example, if your FTP doesn’t default to your web root, you have to make sure you change to your web root before you upload things). As long as you’re organized, it’s fine.

Personally, I rarely keep mine OUTSIDE of the web root… for most things. There are a few things that I would (I just generally don’t work on those types of projects). I usually keep mine in a folder inside the web root (though it generally has different permissions, like 700 or 770).

A VPS is essentially the same as a dedicated server, in terms of what kind of control you have over it’s insides, so yes, you do have access to it all. The key differences are just the obvious ones, that you don’t have access to the hardware and the physical machine may be shared with other servers. Each server is essentially in it’s own little pocket it can’t break out of.


I do want to give you a general word of caution when it comes to security.

It is a very good idea to be well aware of this stuff, to actively think about it and understand how it all works.

Security is good. So is organization… but there is a difference between keeping papers on your desk in a neat stack and keeping papers on your desk in a neat stack ordered alphabetically by the fourth letter on the page and the number of characters.

There are things in security that are good to do always because they have very good return on the time invested. There are also things that have almost no return for a very large amount of time invested.

Cleaning user input for SQL queries, making sure turning off Javascript doesn’t break your site, etc., are all very good and should always be done.

Things like setting up file permissions and what not are in between. Most of the time they don’t have huge returns, but they don’t take long so it’s not bad to do it.

Obfuscation is at the bottom of the barrel. It costs you a lot of time to do (when you consider how many times you have to type it, look it up, fix errors causes by it, etc.) and has only a very little return (keeps people from guessing).

Just a little food for though. :wink:

deathshadow’s tone could definitely use some work, but he has some valid points.

About the web root, I think you guys are misunderstanding (and I actually misunderstood you as well, deathshadow). I think what Debbie though was you put all your files in your root directory directly (so, you’d have http://mysite.com/myimage.png, etc).

I do agree that if there are images in your site that aren’t being used, why are they there? However, at the same time, I do still support using -Indexes (which without may let them casually browse your directories). Going far beyond that is a bit pointless though because there shouldn’t be anything non-public in there. Now, if it has secure documents or something, that is a different story, but then those wouldn’t be accessible by the user anyways, so if you just pick a folder (with a reasonable name), who’s gonna find it?

I think 1 needs a bit of clarification (in case I’m reading it out how I think I am, which doesn’t make sense). It sounds like you’re saying all your functions go in index.php, which I doubt you’re saying. You’re saying all of your function calls should go in index.php, an branches out from there.

So, for example, say you build a site using OOP. You have one main class called MySite. You’d call MySite in index.php, no matter which page you were on. You’d then use the functions in the class and what not to create other pages (with rewrites, etc.). I agree with this kind of single-starting-point approach.

Absolutely agree with number 2, which are the kinds of files I think StormRider was talking about earlier. I think it’s also a good idea to check if they should be there in some way, and if not, redirect them to the home page.

3 is definitely a good idea. It’s occasionally unavoidable, but 99% of the time it is easily done with proper planning.

4 and 5 are debatable. Aside from Wordpress, I don’t do many skinnable projects, so I like to keep my images all in one place (unless it is a huge number). However, there are definitely advantages the the approach deathshadow talks about as well. I think this is personal preference.

As do I – usually it’s not because of security for me so much as it is

Though they’ve become a non-issue since every site I’ve written the past five years has this .htaccess:


RewriteEngine On
RewriteRule !\\.(gif|jpg|png|css|js|swf|html|ico|zip|rar|pdf|xml|mp4|mpg|flv|mkv)$ index.php

Since any request off the root directory of the site that isn’t a direct link to one of those filetypes is FORCED through the CMS. So much for browsing :wink:

Correct – I’m not even sure where you’re getting that I was saying dump it all in root – Oh, you’re confusing function php’s with function CALLS and DECLARATIONS – there’s a difference. See how I said “function php’s” – user functions; stuff the user can call directly via the URL as a separate file… Which I don’t actually HAVE anymore on anything I’ve written after 2006. Basically I was referring to the half-assed coding approach of systems like myBB or phpBB where every ‘function’ has it’s own php file the user calls directly – I hate that.

Off Topic:

But then I don’t get a lot of where people misunderstand me online – Like where people have a problem with my tone either; It’s like people have never worked in a business or something.

But I say the same thing given how people react to Simon Cowell and Gordon Ramsey. They behave like every REAL professional businessman I’ve ever dealt with.

While I’d not waste the overhead of a class/object on the outermost handler – and due to my adding functions based solely on what the user called for a function objects are not extensible enough (in php) for me to use that approach, yes, that’s the general idea.

But then, I don’t just slap objects on things because it’s trendy… I use them when they are appropriate like when there’s going to be more than ONE instance or secure data is being handled – which in php typically means a PDO object and… well, that’s about it. (since 99% of the stuff I’d actually use objects for is handled by the SQL server)

That’s why I’m using that .htaccess above – except for files with those extensions, send EVERY other request be it a directory or file through the index.php and let it do the error handling. Also lets me do styled 404’s that match the rest of the site layout since I can still call the theme.

Only time I’ve found it unavoidable is when cleaning up some mess somebody else wrote. If you plan it properly from the start with clearly defined roles for what goes where, it should be a non-issue. You sleaze together a site using some garbage off the shelf solution, YMMV.

Even if it’s single theme and I’m creating a new system, I’d use theme/screen.css and theme/images/bodyBackground.png (for example) removing the theme name. It’s just nice to keep it separated and it helps with the directory linking.

While yes, it’s a personal preference, it’s also good organization. I can’t stand it when you see a directory of a few hundred images slapped together that are a mix of theme and content images. The more you organize your files in a clean consistent manner and establish clear-cut easy to follow roles for directories, the easier it is to maintain. Basically it’s applying to the directory structure the same old rules that are used for building an application. (Not that it seems anyone knows or has been taught those rules after about 2002)

Mostly it’s about using one of the best features of how a user agent reads a page to your advantage – if you omit any sort of leading slashes any directory access from the html is automatically treated as where that HTML file was accessed from. If you do the same in a CSS file, all accesses treat the location of that CSS file as the current location…

Oh, and there’s a typo in my last post, the directory for the CSS version is wrong. Should be:

background:url(images/bodyBackground.png);

Which will point at “theme/themename/images/bodyBackground.png” so long as the css file in question is in “theme/themename”…

My bad.

Just to clarify, I understood what you meant… it’s just how it sounded when I first read it, it screamed confusion for others, so I wanted to add an example. =p I definitely agree with you. Unfortunately I have to work with vBulletin on a near daily basis and it drives it nuts.

I also don’t throw together an object for everything either… it was just the quickest, clearest way for me to explain the separation of functions.

I can see why you like using a “theme” structure. I agree that it’s annoying to have a billion images in one folder all thrown together. I didn’t think of your approach in those terms at first, because my “images” folder almost always contains just design images (some are used as images, but they’re still mostly decoration). Things like image galleries, icons, attachments, etc. always get their own folders.

Of course, my approach does mean I use …/, which I know isn’t ideal, but I still like it. =p It is actually the first time I’ve seen your approach though, and I must say, it’s not a bad idea. I doubt I’ll adopt it any time soon, but I’m sure I’ll keep it in mind.

It is what I meant, yes, although in my projects just about everything except index.php, and the static assets (js, css, images) live outside the web root anyway!

I can’t WAIT to hear the explanation for this one :stuck_out_tongue:

Absolute paths (or ‘rooted’ as you call them) are a fail, but nothing wrong with the above. It’s still a method of relative linking, no different to ‘down tree’ linking as you are calling it in terms of issues.

[ot]

Also lets me do styled 404’s that match the rest of the site layout since I can still call the theme.

I am thoroughly surprised that there ISN’T a valid page on Crusty’s sites called whisky tango foxtrot : )[/ot]

Meh.
wget -r --no-parent -A png,“jpe?g”,gif http://your-website.com/images/

Though I can also just ask for everything in that folder if I think they are just image files.

My point only being that stopping ppl from seeing what’s in a dir has little bearing on whether they want to copy from it (and then they see it, no?). I’m not disagreeing with it not being a bad thing to remove indexes and use DirectoryIndex in Apache.

Poes You may want to explain wget for debbie.

ds60 your linking names made me scratch my head. I never heard them referred to that way.

That’s because they aren’t referred to in that way. There is absolute linking and relative linking. ‘up-tree’ and ‘down-tree’ as DS calls them are equivalent (no difference at all), and are both forms of relative linking. Starting with a / would be absolute linking.

Starting with a / would be absolute linking.

Might be off-topic but the way my husband sets things up, everything looks like it’s from root (so the main page/default is “/” and everything starts with /) but it isn’t really. It’s some kind of fakery set up in the back end. It’s always confused me why and how, but so just saying that seeing urls start with / in the source isn’t necessarily what it seems.

[ot]

Poes You may want to explain wget for debbie.

ok
wget is a tool that comes standard on all work computers (computers built to do actual computery-stuff). It’s basically a user agent (a browser is also a user agent) you can control from the command line to grab stuff (documents, files) from the web and save them locally (actually, it can also just spider things… check that the files are there but not copy).
What’s nice/useful about it is you can grab whole groups of files at once, and preserve their hierarchy (if you’re trying to make a copy of a site, you can keep all the associated files in relatively the same place, meaning when you view the files locally, links, images, styles and scripts should all work just as if you had built it locally… not sure about sites who use absolute (http:// starting) links for everything like Wordpress tho).

*edit I 'spose I should mention there are other tools that do similar, like cURL (comes on Macs instead of wget I think)[/ot]

Yeh, indeed. I usually set a <base href> then all my URLs in the HTML are just set relative to that URL. The base url value is controlled with a config file.

CSS background images etc have to use …/images/image.jpg etc in the urls, because you have to jump out of the css directory then into the images one. This is still relative linking and will still work if you move the site to another directory.

I have officially protested the use of the base element. =p vBulletin absolutely abuses it for all of their scripts, which completely destroys jump links. I couldn’t just remove the base element because of their reliance on it, so I had to add Javascript to make jump links work… seriously… =(