Directory listing in a web server

Posted on

Problem

I have Ubuntu 16.04 with standard apache web server installed. Nothing special about it. No open ports but 80.

Instead of the default index page I put this one:

<?php
$path = ".";
$dh = opendir($path);
$i=1;
while (($file = readdir($dh)) !== false) {
    if($file != "." && $file != ".." && $file != "index.php" && $file != ".htaccess" && $file != "error_log" && $file != "cgi-bin") {
        echo "<a href='$path/$file'>$file</a><br /><br />";
        $i++;
    }
}
closedir($dh);
?> 
<!DOCTYPE html>
<html>

<head>
  <title>CLIENT Website</title>
</head>


</html>

Just a simple page that show the web server’s root directory content.

I didn’t change any configuration, just added a user (with htpasswd) and my default virtual server configuration looks like this:

<VirtualHost *:80>
   # The ServerName directive sets the request scheme, hostname and port that
   # the server uses to identify itself. This is used when creating
   # redirection URLs. In the context of virtual hosts, the ServerName
   # specifies what hostname must appear in the request's Host: header to
   # match this virtual host. For the default virtual host (this file) this
   # value is not decisive as it is used as a last resort host regardless.
   # However, you must set it for any further virtual host explicitly.
   #ServerName www.example.com

   ServerAdmin webmaster@localhost
   DocumentRoot /var/www/html

   # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
   # error, crit, alert, emerg.
   # It is also possible to configure the loglevel for particular
   # modules, e.g.
   #LogLevel info ssl:warn

   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined

   # For most configuration files from conf-available/, which are
   # enabled or disabled at a global level, it is possible to
   # include a line for only one particular virtual host. For example the
   # following line enables the CGI configuration for this host only
   # after it has been globally disabled with "a2disconf".
   #Include conf-available/serve-cgi-bin.conf
   <Directory "/var/www/html">
           AuthType Basic
           AuthName "Restricted Content"
           AuthUserFile /etc/apache2/.htpasswd
           Require valid-user
   </Directory>
</VirtualHost>

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

How easily can my server be hacked? (assuming the user password is not breakable in short time). I don’t want anybody to go to other directories in my server.

Solution

The variable $i is not used in the whole program. You should remove it.

You output the <a> elements before the <!DOCTYPE> and the character set declaration. This generates malformed HTML and can lead to wrongly displayed file names in the browser.

As soon as your directory contains files with funny characters in their names, such as <body onload="alert('hello')"> (yes, that’s a valid filename), the browser will execute some JavaScript code. (Learn about cross-site scripting to fix this properly.)

Since you declared your document to be HTML (and not XML), the br tags should look like <br> instead of <br />.

To improve usability, you should sort the filenames alphabetically. Right now they are output in filesystem order, which can be anything.

Leave a Reply

Your email address will not be published. Required fields are marked *