Password-Protect a Directory with .htaccess and .htpasswd

8 min read Auf Deutsch lesen

Some parts of a website are none of the public’s business: the staging environment, the draft for a client, the folder with internal downloads. The classic way to seal them off is directory protection – a password gate at server level that has worked for decades and takes five minutes to set up. Provided you know the two or three traps.

What directory protection is – and why it is so effective

Directory protection uses HTTP Basic Authentication: the web server itself demands a username and password before delivering anything from the protected directory. The browser shows its plain grey login prompt for it – no beauty, but that is exactly the point: the protection kicks in before any application.

That makes it special: a PHP application with a vulnerability, a forgotten admin script, a form with a weakness – behind directory protection, none of it even executes without a login. Attacks bounce off the server before a single line of application code runs.

What it is good for – and what it isn’t

Well suited:

  • Staging and development environments – the most common case. As a side effect, the gate also keeps search engines out, without a forgotten noindex becoming a trap later.
  • Client previews – a draft that exactly a handful of people should see.
  • Internal areas and downloads – documents that must not be public behind a guessable link.
  • As a second layer in front of login pages – a wall before the actual application login. We’ve covered the WordPress special case including the WooCommerce traps separately: securing wp-admin with directory protection.

Not suited:

  • As user management. There is no registration, no password reset, no roles – just a text file with users. Real customer areas are a case for an application login.
  • As the only protection for sensitive data. Basic Auth is a solid door, not a vault – more on that below.

The two files behind it

The whole mechanism consists of two small text files:

The .htaccess sits in the directory to protect and holds the rule – four lines:

  • AuthType Basic – the method.
  • AuthName "…" – the text in the login prompt.
  • AuthUserFile /absolute/path/.htpasswd – where the credentials live. The most common source of errors: this must be the absolute path in the server’s file system, not the URL.
  • Require valid-user – any user from the file may enter.

The .htpasswd holds the credentials, one line per user in the format name:hash. The password never appears there in plain text but as a hash – normally created with the htpasswd command-line tool, which is rarely available on shared hosting. That is exactly what the generator here is for:

Directory Protection Generator

Generate .htaccess & .htpasswd

Add users, copy both files, done. The password is hashed locally and never leaves your browser.

What do you want to protect?

Your hosting panel shows the real path – or a PHP file containing <?php echo __DIR__;

Users

    Username and password never leave your browser – the hash (APR1-MD5, htpasswd-compatible) is generated locally via JavaScript.

    Setting it up step by step

    1. Find the path. Place a file path.php containing <?php echo __DIR__; in the target directory and open it in the browser – it prints the absolute server path. Delete it afterwards.
    2. Save the .htpasswd – with the user lines from the generator, ideally one directory above the public web root. That way it is fundamentally unreachable via the browser.
    3. Add the .htaccess – in the directory to protect, with the real path in AuthUserFile. If a .htaccess already exists there, add the lines at the top instead of replacing the file.
    4. Test – best in a private browser window, so no saved login skews the result.
    5. If it fails: a 500 error almost always means the AuthUserFile path is wrong. If no login prompt appears at all, the server isn’t evaluating the .htaccess – rare on Apache hosting, the rule on nginx (see below).

    One more real-world stumbling block: FTP clients often hide files starting with a dot, and some editors quietly save htaccess.txt. The file names must be exactly .htaccess and .htpasswd.

    Security, honestly assessed

    Three things to know before entrusting secrets to this gate:

    • HTTPS is mandatory. Basic Auth transmits the credentials merely Base64-encoded on every request – without HTTPS, anyone listening along the way reads them. Since modern websites run over HTTPS anyway, this is solvable, but it needs saying.
    • Strong passwords are the actual protection. A login prompt can be brute-forced automatically. The random generator in the tool produces passwords where that is hopeless.
    • Protect the .htpasswd itself. If it sits in the public web directory, Apache blocks access to .ht* files by default – but relying on that is unnecessary when a directory outside the web root is just as easy.

    On the hash format: the generator produces APR1-MD5 – the classic htpasswd format that works on practically every Apache and LiteSpeed hosting. It is not the most modern scheme (that would be bcrypt), but entirely adequate for an additional protective layer with a strong password – and compatibility beats theory here: a hash format your hosting doesn’t understand protects nothing at all.

    And on nginx?

    nginx ignores .htaccess files entirely – yet the principle exists there too: the auth_basic and auth_basic_user_file directives do the same job, but belong in the server configuration, which is usually out of reach on shared hosting. The good news: the password file has the same format, so the user lines from the generator work there as well. On nginx hosting, the route leads through the hosting panel or the provider’s support.

    An honest conclusion

    Directory protection is one of the web’s oldest tools – and one of its most underrated: two text files, no plugin, no dependency, and the protection kicks in before any application code runs. It replaces neither a real application login nor careful handling of sensitive data. But for staging, previews, and internal areas it is exactly the right measure: quickly set up, robust, and proven for decades.


    Want your website not just sealed off but securely operated long-term? That is exactly what our WordPress maintenance is for – updates, tested backups, security monitoring. Or drop us a line if you need help setting it up.

    Frequently Asked Questions

    What is directory protection?

    A password gate at server level (HTTP Basic Authentication): before the server delivers anything from the protected directory, the browser demands a username and password. It therefore kicks in before any application – even PHP code with security holes never executes without a login. It is set up via two files: .htaccess (the rule) and .htpasswd (the credentials as hashes).

    Is directory protection via Basic Auth secure?

    With HTTPS: yes, as a solid protective layer. Without HTTPS: no – Basic Auth transmits the credentials merely Base64-encoded on every request, effectively in plain text. Since practically every website runs over HTTPS today, this is rarely an issue in practice. What remains important: a strong password (the gate can be brute-forced) and a .htpasswd that is not publicly retrievable.

    Why do I get a 500 error after setting it up?

    In almost all cases the AuthUserFile path is wrong: it must be the absolute server path to the .htpasswd – not the URL and not a relative path. If Apache cannot find the file there, it answers with a 500. Your hosting panel reveals the real path, or a short PHP file containing echo __DIR__. Second most common cause: a typo in one of the directives.

    Does directory protection work with nginx too?

    The principle yes, the .htaccess no: nginx ignores .htaccess files entirely. There, the directives (auth_basic and auth_basic_user_file) belong in the server configuration, which on shared hosting usually only the host can change. The password file itself has the same format – so the generated user lines work for nginx as well.

    Daniel Nilges
    Daniel Nilges

    Founder & Full-Stack Developer

    20+ years of web development experience. Specialised in Laravel, WordPress and custom software for mid-sized businesses.