Hardening a LAMP Stack: The Four Layers and What Each One Gets Wrong
LAMP — Linux, Apache, MySQL and PHP — still runs an enormous share of the web, and it is the stack most commonly deployed by someone following a tutorial. Every layer ships with defaults suited to getting something working quickly, and the gap between working and secure is where the incidents come from.
What each layer does
Linux is the operating system, providing the process, filesystem and network foundation. Apache receives HTTP requests, serves static files and hands dynamic requests to the application. MySQL or MariaDB stores the data. PHP executes the application code.
Requests flow through all four, and a weakness at any layer is a weakness in the whole stack. The variants — nginx in place of Apache, PostgreSQL in place of MySQL, Python or Perl in place of PHP — change the components and not the reasoning.
Linux
Run each service as its own unprivileged account, never root, so a compromise of one is bounded. Set filesystem permissions so the web account can read application files and write only to the directories that genuinely need it — uploads, cache, sessions — using the octal values covered under Linux octal permissions. A world-writable web root is a recurring finding and an immediate path to code execution.
Keep mandatory access control enforcing rather than disabling it when a file will not load. The correct fix is a context or boolean change, as described under SELinux, and the habit of turning it off during troubleshooting is how it ends up off in production.
Close everything but the ports you need, and keep the database bound to localhost or an internal interface rather than to all addresses — the default in some packages, and the reason exposed databases turn up in internet-wide scans.
Apache
Disable modules you do not use; each one is code in the request path. Turn off directory listing so a directory without an index file does not enumerate its contents. Suppress the version string in the server header and in error pages — obscurity rather than a control, and free.
Restrict which directories can be served and disable symbolic link following where it is not needed. Ensure the server cannot serve files above the document root, and that dot-files such as version control directories and environment files are explicitly denied.
Set the security headers, which cost nothing and are usually absent — the list under web server hardening. Terminate TLS properly with current protocol versions and cipher suites, and redirect HTTP to HTTPS with HSTS.
Where a virtual host exists for testing, make sure it is not reachable from the internet, and remove default and sample content entirely.
MySQL
Run the secure installation step, which removes anonymous accounts, the test database and remote root login — the things a default installation leaves in place.
Give the application its own database account with privileges scoped to the one database and to the statements it actually issues. An application connecting as root is the reason an injection flaw becomes a full database compromise rather than a limited one — and it is the most consequential single misconfiguration in this stack.
Bind to localhost unless remote access is genuinely required, and where it is, restrict by source and require TLS. Enable logging of connections and errors, and back up with tested restores rather than assuming.
PHP
Turn off error display in production and log errors instead. Displayed errors leak file paths, database structure and query fragments, which is reconnaissance handed over for free.
Disable dangerous functions the application does not use — the ones permitting command execution — and disable remote file inclusion so an included path cannot be a URL, which removes the more severe half of the problem described under file inclusion.
Restrict file access to the application's own directories, set sensible upload size limits and execution timeouts, and store session data somewhere the web account can write and nothing else can read. Set session cookies with the Secure, HttpOnly and SameSite attributes.
Keep the runtime current. PHP versions reach end of life on a published schedule and a great many production sites run past it, which means known vulnerabilities with no patch coming.
The application on top
All of the above is infrastructure. The application still has to use parameterized queries, validate input, and authorize every request — the defects under SQL injection and its relatives are not fixed by server configuration, only contained by it.
Third-party components are the other half. A LAMP application built on a content management system inherits every vulnerability in its plugins, which is why composition analysis and a habit of removing unused plugins matter more than any single server setting.
Exam angles
Know the four LAMP components and their roles. Recognize least-privilege service accounts, correct filesystem permissions, disabled directory listing, suppressed version disclosure, a scoped database account, disabled error display and current runtime versions as the standard hardening steps. Understand that a database account with excessive privileges turns an application flaw into a full compromise, and that server hardening contains application vulnerabilities rather than fixing them.
Comments
Post a Comment