Ahosting Logo
Knowledge Base

How to Password Protect Directories in cPanel

Directory privacy puts a username and password in front of a directory at the web server level. The browser prompts before anything inside is served, before PHP runs, before WordPress loads, before any application on the other side gets a chance to respond.

That position is what makes it useful. It protects things that have no login of their own: a staging copy, a client preview, a folder of documents, an admin path being hammered by automated attempts.

Setting it up

In cPanel, open Directory Privacy. Browse to the directory you want to protect and click it.

Tick the option to password protect, give the protected area a name. This appears in the browser prompt, so make it recognisable rather than "Protected", and save.

Then create a user underneath: username, password, and Add. This is a separate step, and skipping it is the mistake that produces a prompt nobody can get past, including you.

Test in a private browsing window. Your normal browser may have already stored the credentials, which makes the protection look broken when it is working.

Where directory privacy sits, and why that position mattersDirectory privacythe web server asks first, before anything else runsPHP startsonly after the prompt is satisfiedThe application loginruns last, inside code that may be out of dateThis is why directory privacy protects a broken or unpatched application, and an application login cannot.

What it protects that an application login does not

The distinction matters. A WordPress login happens after WordPress has loaded and processed the request. Directory privacy happens before anything on your side runs at all.

So it protects an application that is outdated, broken, or already compromised. A vulnerability that would be reachable by an unauthenticated request is simply never reached, because the request is refused earlier.

This is why it is the right tool for a staging copy. The staging site may be running old code you have not updated in months, and directory privacy means nobody reaches it regardless.

Good uses

A staging or development copy. The most valuable use. It keeps the copy away from visitors and away from search engines: more reliably than a robots setting, because it does not depend on the crawler choosing to respect it.

A client preview. Work in progress that one person needs to see and nobody else should.

A documents folder. Files for a group of people, without building any login system.

An admin path under attack. Adding server-level protection in front of a login page stops automated attempts before they consume a PHP process. It also breaks anything that needs to reach that path programmatically, so test afterwards.

Poor uses

Your public site. Obvious, but it happens: someone protects public_html to hide a site during development and forgets. Visitors get a password prompt they cannot answer.

Files linked from public pages. An image or stylesheet inside a protected directory will not load on a public page, because the browser's request for it is refused too. The result is a site with missing images and no obvious explanation.

As your only protection for genuinely sensitive data. It is a reasonable barrier, not encryption at rest.

HTTPS is a precondition

This kind of authentication sends the password with little protection. Over plain HTTP it is readable by anyone on the network path.

Ahosting includes free SSL, so confirm the certificate is active for the domain before relying on this. Over HTTPS the credentials are inside the encrypted connection and the arrangement is sound.

Managing access

Create one user per person rather than sharing one credential. Removing an individual's access then does not mean changing the password for everyone else, which is the moment shared credentials always fail, because nobody wants to disrupt five people to remove one.

To remove access, delete that user on the same screen. To lift protection entirely, untick the protection option; the users remain defined and can be re-enabled later.

When it does not behave

No prompt appears. The protection is on a different directory than you think. Check the path shown at the top of the screen, and remember that protecting a directory also covers everything beneath it.

The prompt appears but nothing is accepted. No user was created. Add one.

It keeps letting you in. Stored credentials. Test in a private window.

Images or stylesheets stopped loading. They are inside the protected directory and are being requested by public pages. Move them out, or protect a narrower path.

An application broke. Something it depends on is now behind the prompt. A callback URL, a cron target, an API path. Protect a narrower directory in place of the application root.

If you are protecting a staging subdomain, creating and managing subdomains explains setting one up, and this is the step that keeps it out of search results.

For the shorter version of the same job, How to Password Protect a Directory deals with it.

Confirm the rule is being applied

The panel reports what it wrote. Whether the server is honouring it is a separate question, and one request answers it.

curl -sI https://example.com/private/ | head -1
curl -sI -u wrong:wrong https://example.com/private/ | head -1
curl -sI -u correct:password https://example.com/private/ | head -1

The first two must be refused and the third accepted. If the first returns a page, the rule is present in a file that is not being read, which happens when the directory is served by an application rather than as files.

The panel writes rules into a file inside the directory. Anything that bypasses that directory, including a rewrite sending every request to a single entry point, bypasses the protection with it.

Where the password file lives

The credentials are stored in a file, and where that file sits decides whether the protection is a protection.

grep -i AuthUserFile ~/public_html/private/.htaccess
ls -la "$(grep -i AuthUserFile ~/public_html/private/.htaccess | awk '{print $2}' | tr -d '"')"
curl -sI https://example.com/private/.htpasswd | head -1

The file must be outside the web root. If it can be requested over the web, the hashed passwords are downloadable, and hashes are worth considerably more to an attacker than nothing.

The panel places it correctly by default. The case to check is a directory protected by hand or copied from another site, where the path may point somewhere that is served.

Removing access properly

Access is removed by deleting the user, and deleting the user does not end a session that is already open.

grep -c . /home/user/.htpasswds/public_html/private/passwd 2>/dev/null
cat /home/user/.htpasswds/public_html/private/passwd 2>/dev/null | cut -d: -f1

Read the list of names occasionally. What accumulates is accounts created for a contractor, a client review or a one off, each still valid years later.

Browsers also remember the credentials for the session, so a removed user keeps working in an already open browser until it is closed. Where the removal matters, change the remaining passwords as well rather than assuming the deletion took effect immediately.