Henkie T - DomDoen ft. Jonna Fraser (prod. Jordan Wayne & Zerodix)

I have a family history website, call it 'my_family.com'. The primary file, index.php, has some introductory remarks of explanation and an html form into which one puts the website's password (there's a single password used by all family members). If one runs 'my_family.com' and inserts the correct password and clicks on the 'Submit' button, the php code in the file takes you to the first of several html files -- call it 'first.html,' which gives one links to further html files. All of these files contain family trees, copies of letters, photos, reminiscences, obituaries, etc., and none of them should be available to non-family-members.

The problem is that if an intruder happens to learn the filename 'first.html' and puts 'my_family.com/first.html' into his/her browser, the intruder is immediately taken to first.html, skipping the password process altogether. From there, the intruder has access to the entire website.

How can I prevent this from happening?

A technician from GoDaddy, my web host, showed me how to insert a password protector in an .htaccess file. With this change, the website's first action is, in a sterile dialog box, to request a username and password. But I don't want to employ a username at all and I want to use my custom form for the password.

Any help would be greatly appreciated.

  • What you're asking for is a password for 'anonymous' users. This is easily done in Microsoft, but I don't know about Apache. I'm not an Apache person, but take a look at httpd.apache.org/docs/2.4/mod/… and see if this has any value. It appears that you can configure Apache to allow 'anonymous' users access to your site. I don't know what the password prompt will look like though.

I know it's not exactly what you want, but I think your GoDaddy technician is onto the best, easiest solution. What I'd do is put all your secure files into a separate directory and link to that directory from your unsecured index.php file. You can include a note telling your users what username to use if you only want them to have to remember a password. Essentially then you'd have a site like this:

For example, in https://my_family.com/index.php:

Login Here with the username 'Guest'

Then in https://my_family.com/secure/ you'd have your .htaccess file as described by your GoDaddy tech which would be something like:

Authtype Basic AuthName 'WHATEVER_YOU_WANT_HERE' AuthUserFile /path/to/password/file Require valid-user 

Unauthenticated users would thus be able to view and visit your index.php page, but they'd then need the correct password to access your sensitive content. Granted, they'd have the ugly login form you're talking about, but it would be quick, easy and secure.

That said, if you really want to have a custom form, it's going to add a whole lot of complexity. But there are a number of approaches you could take. Here's one:

  1. Secure your sensitive files by putting them into a separate directory as above -- or better yet, take them out of the DocumentRoot completely.
  2. Create a script that allows for authentication and that reads and outputs the secure files to authenticated users upon request.

You could do something like this:

<?php class MySecurePage { const PASSWORD = 'YOUR_PASSWORD_HERE'; const SECURE_PATH = '/path/to/secure/folder'; /** * Run the page */ public static function run() { session_start(); if (isset($_GET['directory'])) { $directory = $_GET['directory']; } else { $directory = '/'; } if (isset($_GET['file'])) { // Regularize forward slashes and remove any periods in the path which could otherwise be a security risk $file = $_GET['file']; } else { $file = ''; } if (isset($_GET['log_out'])) { $_SESSION['logged_in'] = false; echo 'Logged Out'; } elseif (!self::checkLogin() && !self::checkPassword()) { self::showLoginForm(); } elseif ($file) { self::readFile($directory, $file); } else { self::showFiles($directory); } return true; } /** * Returns TRUE if the user is logged in. * * @return bool * 1 */ public static function checkLogin() { if (isset($_SESSION['logged_in'])) { return $_SESSION['logged_in']; } else { return false; } } /** * If the user submitted the correct password, sets the logged_in SESSION variable and refreshes the page to complete * the log in process. * * @return bool */ public static function checkPassword() { if (isset($_POST['password']) && $_POST['password'] === self::PASSWORD) { $_SESSION['logged_in'] = true; header('Location: ' . self::getBaseUrl()); exit; } else { return false; } } /** * Show the login form * * @param bool $hasError */ public static function showLoginForm($hasError = false) { if (isset($_POST['password'])) { echo '
Invalid password
'; } <form action='' method='post'>

Please note that the script above is only meant to be an example. It's not very usable; it hasn't been thoroughly tested; and it may well introduce security vulnerabilities!

Despite the above example, I'd seriously suggest you consider the first option even if it's not exactly what you want. It's not only much easier to implement, but it's also likely to be more secure. For instance, in the script I included, I essentially hard-coded a plaintext password into the file, which is a big no-no from a security practice. (I suppose you could do something like hash the password to make it a little more secure, but even this is far less than ideal!) As another example, it would also be relatively easy to accidentally allow authenticated users to access files you don't even want them to be able to access if you're not careful.

I guess the question you need to decide is how much time and effort you're willing to spend just to have a prettier login form.

  • This approach will not work on first.html (or any .html file) - the OP will have to switch to .php files
  • @Steve, the script I included would indeed read and output any file (HTML or otherwise) in the secure directory. But it has a whole slew of other problems -- horrible navigation, or other tags referencing files in the secure directory not working, incorrect ContentType for non-HTML pages, etc -- none of which are unsolvable, but all of which seem to add up to more work than is worth it. In theory he could switch to PHP pages -- adding a login check to each of them -- but that wouldn't secure things like images, which he seemed to want to be able to do.

fungerat för dig: Charles Robertson | Vill du kontakta oss?