Sentrifugo is a self-hosted HRMS that stores sensitive employee data: payroll figures, identity documents, performance reviews, and contact details. On a managed shared platform you are running it as an unprivileged hosting user, which means the attack surface you can actually control sits inside your own document root. The defaults that Sentrifugo ships with are permissive by design to simplify installation, and that convenience leaves several weaknesses in place after go-live: broadly writable directories, a readable database.php containing credentials, uploaded files served directly from a predictable path, and no HTTP security headers at the response layer.
None of the fixes below require root, SSH administration, or server-wide configuration. Everything is achieved through the cPanel or DirectAdmin File Manager, .htaccess rules interpreted by LiteSpeed, the .user.ini mechanism for PHP directives, and the Sentrifugo AdminCP itself. Work through them in order, and keep a backup of any file you edit so a single bad rule does not lock you out.
Correcting file and directory permissions
The most common weakness on a fresh Sentrifugo deployment is a document root full of 777 directories. Installers frequently instruct users to loosen permissions so the writability checks pass, and those settings are rarely tightened afterwards. On a shared server running under CloudLinux with suEXEC, PHP executes as your own user, so there is no technical reason to grant world-write access to anything. Directories should be 755 and files should be 644. The only paths that genuinely need to be writable by the application are the upload and cache locations, and even those only need 755 because the web server process already runs as you.
Open the File Manager in cPanel (Jupiter theme: Files → File Manager) or DirectAdmin (System Info & Files → File Manager) and navigate to your Sentrifugo root, for example /home/youruser/public_html. Select the top-level folders, choose Permissions, and set them to 755. Then select files and set 644. The directories that Sentrifugo writes to during normal operation are the upload trees under uploads/ and the temporary data areas; confirm they are 755 and owned by your account.
Pay special attention to config/database.php. This file holds your database host, name, username, and password in plain PHP. It must never be group or world readable in a way that other tenants could reach, and more importantly it must never be served as text. Set it to 644 (owner read/write, others read only at the filesystem level, which under suEXEC still means only your processes execute it), and then block direct HTTP access to it as described in the next section. A quick way to audit is to request the file in a browser: https://yourdomain.com/config/database.php. Because it is PHP it should return a blank page rather than source, but you still want a hard block in front of it so a misconfigured handler can never leak contents.
Blocking sensitive files and exposed admin paths
Sentrifugo keeps its bootstrap, configuration, logs, and installer in predictable locations. Attackers scan for exactly these. The install/ directory, if left in place after setup, can allow a reconfiguration attack; delete it entirely through File Manager once your instance is live. For everything that must remain on disk, use .htaccess to deny direct web access. LiteSpeed reads Apache-style .htaccess natively, so these rules apply without a restart.
Create or edit .htaccess in your document root and add a block that protects configuration and log files:
<FilesMatch "\.(ini|log|sql|bak|old|conf)$">
Require all denied
</FilesMatch>
# Protect dotfiles and VCS leftovers
<FilesMatch "^\.">
Require all denied
</FilesMatch>
RedirectMatch 404 ^/config/database\.php$
RedirectMatch 404 ^/install/The uploads path deserves separate treatment. Sentrifugo stores employee documents, profile images, and attachments under uploads/. Serving these directly means anyone who guesses or enumerates a filename can download a payslip or ID scan without authenticating. More dangerously, if a malicious user manages to upload a .php file through a form that does not validate extensions strictly, that file could execute. Prevent execution inside the uploads tree by placing a dedicated .htaccess in uploads/:
# public_html/uploads/.htaccess
<FilesMatch "\.(php|phtml|php5|php7|phar|cgi|pl|py|sh)$">
Require all denied
</FilesMatch>
# Disable the PHP handler as a second layer
<IfModule litespeed>
RemoveHandler .php .phtml
</IfModule>
Options -IndexesThe Options -Indexes directive stops directory listing so an attacker cannot browse the folder to collect filenames. Add that same line to your root .htaccess as well, because a visible listing of your application structure is reconnaissance you do not need to hand out. For an additional hardening layer against uploaded script execution, use the PHP Selector in cPanel (Software → Select PHP Version → Options) or DirectAdmin's PHP settings to keep allow_url_fopen disabled unless Sentrifugo explicitly needs it, which reduces the usefulness of any remote-inclusion attempt.
Strengthening authentication and PHP runtime limits
Weak authentication is the other half of the problem. Inside Sentrifugo's AdminCP, go to Security → Password Policy (available under the configuration area) and enforce a minimum length of at least twelve characters with mixed case, numbers, and symbols. Rename the default admin account away from admin and remove any demo or test users created during evaluation. Sentrifugo does not provide native rate limiting, so brute-force protection has to come from the application-level session controls plus a .user.ini that constrains the PHP environment.
The .user.ini file sits in your document root and is honoured per-directory by the PHP handler under CloudLinux. Use it to tighten upload handling and session security without touching any server-wide file:
; public_html/.user.ini
upload_max_filesize = 8M
post_max_size = 10M
max_execution_time = 60
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
expose_php = OffSetting session.cookie_secure ensures session cookies only travel over HTTPS, which matters because HRMS sessions carry full access to personnel records. session.cookie_httponly keeps JavaScript from reading the cookie, blunting cross-site scripting attempts, and expose_php = Off stops PHP from advertising its version in response headers. Keeping upload_max_filesize modest limits the size of anything a compromised form could push. After saving, allow a few minutes for the handler to pick up the new values, then confirm them through a small phpinfo() page that you delete immediately afterward.
Adding HTTP security headers and enforcing HTTPS
Sentrifugo sends no browser security headers by default, leaving clickjacking, MIME sniffing, and mixed-content risks open. Add them in your root .htaccess so every response from the application carries them:
<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=15552000; includeSubDomains"
Header always unset X-Powered-By
</IfModule>
# Force HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]Issue a free AutoSSL or Let's Encrypt certificate from Security → SSL/TLS Status in cPanel before enabling the HSTS header, otherwise visitors could be stranded on a site with no valid certificate. If you run other applications that embed Sentrifugo in a frame, adjust X-Frame-Options accordingly, but for a standalone HRMS SAMEORIGIN is the safe choice. After deploying these rules, watch your account's error_log (visible in File Manager at the document-root level, or via Metrics → Errors in cPanel) for any .htaccess syntax complaints or redirect loops, and roll back the single offending block if something misbehaves. A short test cycle here prevents a self-inflicted lockout while still closing the real gaps attackers probe for.