0

As the title states..

I have the following organization to my project but am unable to access the related CSS and JavaScript files from within my HTML code --unless I create symbolic links from the file to my web root. Is this normal behavior for Apache or does the problem lie elsewhere?

If I remove the symbolic links and correct the path in my src attributes the content of those outside files becomes inaccessible

userName@hostName:/var/www/test$ tree
.
├── css
│   └── style.css
├── html
│   ├── code.js -> ../js/code.js
│   ├── index.html
│   ├── jquery-3.2.1.js -> ../libs/jquery-3.2.1.js
│   └── style.css -> ../css/style.css
├── js
│   └── code.js
└── libs
    └── jquery-3.2.1.js

4 directories, 7 files

userName@hostName:/var/www/test$ less html/index.html

<!doctype HTML>
<html>
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" type="text/css" href="./style.css">
      <title>Test</title>
   </head><!-- head -->
   <body>
     <h1>LOCAL TESTING SITE..</h1>
   </body><!-- body -->
    <script src="./code.js"></script>
</html><!-- html -->

html/index.html (END)

^ Works

userName@hostName:/var/www/test$ tree
.
├── css
│   └── style.css
├── html
│   ├── index.html
├── js
│   └── code.js
└── libs
    └── jquery-3.2.1.js

4 directories, 4 files

userName@hostName:/var/www/test$ less html/index.html

<!doctype HTML>
<html>
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" type="text/css" href="../css/style.css">
      <title>Test</title>
   </head><!-- head -->
   <body>
     <h1>LOCAL TESTING SITE..</h1>
   </body><!-- body -->
    <script src="../js/code.js"></script>
</html><!-- html -->

html/index.html (END)

^ Does NOT Work

userName@hostName:/var/www/test$ tree -p
.
├── [drwxrwxr-x]  css
│   └── [-rw-rw-r--]  style.css
├── [drwxrwxr-x]  html
│   ├── [lrwxrwxrwx]  code.js -> ../js/code.js
│   ├── [-rw-rw-r--]  index.html
│   ├── [lrwxrwxrwx]  jquery-3.2.1.js -> ../libs/jquery-3.2.1.js
│   └── [lrwxrwxrwx]  style.css -> ../css/style.css
├── [drwxrwxr-x]  js
│   └── [-rw-rw-r--]  code.js
└── [drwxrwxr-x]  libs
    └── [-rw-rw-r--]  jquery-3.2.1.js

4 directories, 7 files

^ Permissions on files

userName@hostName:/etc/apache2$ less sites-available/test.local.conf

<VirtualHost *:80>
        ServerAdmin [email protected]
        DocumentRoot /var/www/test/html
        ServerName test.local
        ErrorLog ${APACHE_LOG_DIR}/test.local.error.log
        CustomLog ${APACHE_LOG_DIR}/test.local.access.log combined
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

sites-available/test.local.conf (END)

^ Virtual Host Configuration

userName@hostName:/var/www/test$ uname -v

#35~16.04.1-Ubuntu


userName@hostName:/var/www/test$ apache2 -v

Server version: Apache/2.4.18 (Ubuntu)

^ System Info

1
  • Consider the resulting URL that ../css/style.css resolves to in your client-side HTML. (Note that it's a client-side request, not a server-side request.)
    – MrWhite
    Commented Feb 25, 2018 at 23:14

2 Answers 2

2

This doesn't really have anything to do with Apache or server-side permissions, but more to do with how the browser resolves relative client-side URLs (according to RFC 3986).

I'm assuming /html is your document root and index.html is accessed with an absolute URL of the form http://example.com/index.html.

The browser (user-agent) must resolve all relative URLs before it can make a request for that resource.

If in /index.html you reference a stylesheet with the relative URL ../css/style.css - how is the browser expected to resolve this? The browser can't construct a valid URL that goes above / (ie. http://example.com/) - this is already at the top of the URL path. And dot-segments (ie. ..) only work within the URL-path. (Note we are dealing with URL-paths in client-side HTML, not server-side filesystem paths.)

From RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax:

Parsers must be careful in handling cases where there are more ".." segments in a relative-path reference than there are hierarchical levels in the base URI's path. Note that the ".." syntax cannot be used to change the authority component of a URI.

(The "authority component" being the domain in this case.)

So, what happens in the above example (where ../css/style.css is requested from /index.html) is that the ../ prefix is simply stripped and the resulting absolute URL becomes http://example.com/css/style.css. This doesn't exist in your file system structure, so your server responds with a 404 Not Found.

0

The document root is security feature. There are lots of things you don't want accessible through your website. When you specify a document root, you are saying "all my website files are stored here, don't allow files from elsewhere to be viewed".

If Apache allowed files to be served from outside of that just because an HTML file had a reference to it, it would open up a large number of potential vulnerabilities.

  • Anybody who could upload HTML to your site could link to something outside your document root. That could cause user generated content such blog comments to become a huge security problem.
  • JavaScript can also change links, so cross site scripting (XSS) attacks would have potential to compromise the server in addition to the client.

The symlinks that you created can allow Apache to bypass some of that security and serve content outside the document root. That is turned on with Options +FollowSymLinks. I recommend turning that option off so that a symlink created to a sensitive file from your web server document root can't compromise security of your server.

The typical way of structuring your document root is not to create an html directory that contains index.html. That way your document root has an index file and contains all your supporting files so that they can be accessed.

.
├── index.html
├── css
│   └── style.css
├── js
│   └── code.js
└── libs
    └── jquery-3.2.1.js

I usually prefer to completely flatten my website structure. Doing so keeps URLs short and simple, even for JS, CSS, and image resources.

.
├── index.html
├── style.css
├── code.js
└── jquery-3.2.1.js

If I have a build process to create my website from source files, I keep the files separated by type for development, but have the build system flatten them for deployment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.