Vanilla Forums is a lean PHP application that stores its entire runtime identity inside conf/config.php and writes member avatars, attachments, and cached templates into the uploads/ and cache/ trees. On a managed shared account those directories live under your home path, readable by the same PHP worker that serves every request. When permissions drift too wide, when the /vanilla/dashboard entry point sits open to brute-force attempts, or when response headers reveal the framework version, the forum becomes an easy target for credential stuffing, spam registration floods, and automated config scraping. None of these weaknesses require a kernel exploit to abuse, which is exactly why they matter on hosting where you control the account but not the server.

The good news is that every meaningful fix here is reachable from an unprivileged hosting user. You will work entirely inside cPanel Jupiter or DirectAdmin Evolution, the File Manager, phpMyAdmin, and a pair of .htaccess and .user.ini files. Because the stack runs LiteSpeed on AlmaLinux with CloudLinux, the Apache-style directives in your document root are honored natively, and the per-account PHP Selector lets you pin a supported interpreter without touching anything global.

Correcting file and directory permissions

The first weakness worth closing is the permission spread on sensitive files. Vanilla's installer frequently leaves conf/config.php at 0644 or looser, and some restores push it to 0666 so the web process can rewrite it. That file holds your database credentials, cookie salt, and update token in plain text. On shared hosting the PHP process already runs as your user under CloudLinux CageFS, so the file only needs to be readable by you, not writable by the world.

Open cPanel File Manager, navigate to the Vanilla document root (commonly public_html or public_html/forum), and enable Settings → Show Hidden Files. Select conf/config.php, click Permissions, and set it to 0600 (owner read and write only). Directories throughout the install should sit at 0755 and PHP files at 0644; anything showing 0777 is a liability. In DirectAdmin, File Manager exposes the same numeric chmod field per item.

Vanilla does need write access to a handful of runtime paths: conf/, cache/, and uploads/. Keep those directories at 0755 and let the owner handle writes. If the dashboard reports it cannot write to cache/, that is a sign the ownership is wrong after a migration rather than a reason to loosen to 0777. A quick recursive correction through File Manager's Permissions dialog, with the apply-to-subfolders option, restores a clean baseline.

Finally, protect the config directory at the HTTP layer so no misconfiguration ever serves it as plain text. Create or edit .htaccess in the Vanilla root and add:

<FilesMatch "(config\.php|\.ini|\.log|\.sqlite)$">
  Require all denied
</FilesMatch>

RedirectMatch 403 ^/conf/.*$
RedirectMatch 403 ^/cache/.*$

This returns a 403 for any direct request against the config and cache trees even if a future upgrade changes the bundled rules.

Locking down the dashboard and authentication

The management interface lives at /dashboard (for example https://forum.example.com/dashboard/settings), and the sign-in form at /entry/signin is the single highest-value target on the whole install. Automated tools hammer these endpoints with leaked credential lists. Two layers stop the overwhelming majority of that traffic before it ever reaches PHP.

Add a second authentication gate in front of the dashboard using an .htaccess password. In cPanel, open Directory Privacy, browse to the folder, and create a protected user; cPanel writes the AuthUserFile and hashed password for you. Because Vanilla routes everything through index.php, a path-based protection needs a LiteSpeed-compatible rewrite condition rather than a physical directory. Place this near the top of your root .htaccess:

<If "%{REQUEST_URI} =~ m#^/dashboard#">
  AuthType Basic
  AuthName "Restricted"
  AuthUserFile "/home/youruser/.htpasswds/forum/passwd"
  Require valid-user
</If>

Replace the path with the exact file cPanel generated. Visitors now face a browser-level prompt before Vanilla's own login even renders, which defeats bots that only understand the application form.

Inside the Vanilla dashboard itself, go to Settings → Security and Settings → Roles & Permissions. Confirm that the default Administrator account is not still named admin, since predictable usernames halve the work of a brute-force attempt. Create a fresh administrator with a strong passphrase, verify its access, then demote or remove the original. Under Membership, enable email confirmation so new accounts cannot act until they verify an address.

Harden the PHP session layer through a .user.ini file in your document root, which CloudLinux honors per account without any global edit:

session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = "Lax"

These flags keep the Vanilla session cookie out of JavaScript reach, bind it to HTTPS, and reject session fixation. Confirm the interpreter in cPanel MultiPHP Manager or the DirectAdmin PHP Selector is a supported 8.1+ build, because older branches ignore samesite and carry unpatched parser bugs.

Blocking spam abuse and adding HTTP security headers

Spam registration is the most common real-world abuse of an open forum, and it compounds quickly: thousands of junk accounts bloat the GDN_User table and give attackers a foothold for signature link spam. Vanilla ships with the Akismet and StopForumSpam addons. Enable them under Settings → Add-ons, then supply an Akismet key and set the StopForumSpam threshold to challenge or block. Pair this with the built-in registration throttle under Settings → Registration, switching from Basic to Approval on forums that attract heavy bot traffic so a human reviews each sign-up.

At the HTTP boundary, add response headers that reduce clickjacking, MIME sniffing, and version disclosure. LiteSpeed applies Header directives from .htaccess directly:

<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  Header unset X-Powered-By
  Header unset Server
</IfModule>

ServerSignature Off

The HSTS header should only go live once HTTPS is confirmed working through cPanel's SSL/TLS Status with AutoSSL issued, otherwise you can lock visitors out of an unencrypted fallback. Add a Content-Security-Policy gradually; start in report mode and tighten rather than pasting a strict policy that breaks Vanilla's inline theme assets.

Verify every change with your browser's network inspector or an online header scanner, and watch ~/public_html/error_log (or the per-domain log in DirectAdmin) for 403 spikes and PHP warnings after each edit. If a directive triggers an HTTP 500, comment it out and reload, since LiteSpeed rereads .htaccess on the next request. Those same error-diagnosis habits apply across PHP apps on shared hosting; the approach in our osCommerce error diagnosis guide translates cleanly to Vanilla when a header or rewrite rule misbehaves. With permissions tightened, the dashboard double-gated, spam filters active, and headers in place, a standard shared Vanilla install sheds the overwhelming majority of opportunistic attacks without any root access.