Shifting Laminas MVC Document Root to the Public/ Directory
0 reputation · 24 Jul 2024, 06:11 UTC
0 reputation · 24 Jul 2024, 06:11 UTC
Ensure that a Laminas MVC application serves only the public/ directory to the web, keeping configuration, vendor code, and local secrets outside the document root.
The Laminas MVC skeleton assumes the web server’s document root points to public/ and relies on either Apache .htaccess routing or an nginx try_files front‑controller pattern. If the document root is mistakenly set to the project root, files such as config/autoload/*.local.php, composer.json, and the entire vendor/ tree become directly downloadable, potentially exposing credentials. While the framework does not detect or warn about an over‑broad root, teams can harden the web server or add extra deny rules.
public/ is exposed?config/ and vendor/ paths?public/ before releasing to production?31775 reputation · 24 Jul 2024, 07:48 UTC
Point the web server's document root at the project's public/ directory. That single change is the primary control; everything else is defense-in-depth. The Laminas MVC skeleton is built on the assumption that public/index.php is the front controller and the only entry point the web can reach.
For Apache, set DocumentRoot in the virtual host to the absolute path of public/ and keep the shipped .htaccess rewrite rules so requests route through index.php:
<VirtualHost *:80>
DocumentRoot /var/www/myapp/public
<Directory /var/www/myapp/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
For nginx, set root to public/ and use a front-controller try_files pattern:
server {
root /var/www/myapp/public;
index index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
}
Exact directive syntax varies by server version and distribution, so confirm against your installed Apache/nginx before rolling out.
If the document root is the project root instead, then config/autoload/*.local.php, composer.json, and the entire vendor/ tree become directly downloadable. Local config files commonly hold database credentials and API keys. Laminas does not detect or warn about an over-broad root — the framework simply never sees those requests, because the web server serves the files directly.
Web-server configuration alone is sufficient when correct, but misconfiguration is exactly the failure mode you're protecting against. Adding explicit deny rules for sensitive paths is cheap insurance for the day someone deploys with the wrong root. Two caveats: deny rules in a project-root .htaccess only work if the server is configured to read it, and a wrong DocumentRoot can bypass it entirely — so treat these rules as a second layer, not the fix.
Add a smoke test to the release pipeline that probes the deployed server externally and fails the deploy on exposure:
/composer.json, /config/autoload/, and /vendor/ — assert each returns 403 or 404, never 200 with file contents./ and a known static asset under public/ — assert 200 and correct routing.Also inspect the deployed vhost/server block and confirm DocumentRoot/root resolves to public/. Note that staging and production configs often differ, so run these checks against every environment, not just staging.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.