Auditing a Deployed Laravel Site — 3 Layers in Priority Order
Laravel sites deployed on shared hosts behind Cloudflare have recurring exposures that an external check can find within minutes — .env files returning 200, debug files left accessible, permissions loose enough for neighboring users to read DB passwords. Work through the layers and fix issues in order of severity.
I deploy Laravel sites to production often, and before letting people use them, I run through the same security checks every time. Laravel exposures on shared hosts tend to repeat, and an external check can find them within minutes, so I have organized the checks into three layers + the order in which to fix things.
Layer 1: Probe externally — endpoints that should not be accessible
Send requests directly from an external machine and check whether files/routes that should be inaccessible return 200.
SITE=https://example.com
for p in .env .git/config .git/HEAD vendor/composer/installed.json \
storage/logs/laravel.log _ignition/health-check _debugbar/open up; do
code=$(curl -sk -o /dev/null -w '%{http_code}' "$SITE/$p")
echo "[$code] /$p"
done
/.env returning 200 = the full set of DB credentials/APP_KEY exposed (immediate P0) · /.git/config = the entire repo's source can be downloaded · /_ignition/... previously had an RCE vulnerability (CVE-2021-3129) · /_debugbar/open left accessible = queries/internal data exposed · /up health route can be used to fingerprint the Laravel version
Every endpoint that should be blocked must return 403/404, not 200 — if .env is exposed, that is the most urgent issue.
Layer 2: Files and permissions on the server
Use ssh to check permissions — on shared hosts, the defaults are often too permissive.
cd ~/domains/example.com/laravel_app
stat -c '%a %n' .env # ต้องเป็น 600 ไม่ใช่ 644/664
find . -name '.env*' -perm /o+r # .env ที่ others อ่านได้ = เพื่อนบ้านอ่าน DB pass ได้
ls -la storage bootstrap/cache # ควร 775 เจ้าของถูกต้อง ไม่ใช่ 777
grep -n 'APP_DEBUG' .env # production ต้อง false
The default 644/664 means other users on the same machine can read my files — so .env, which contains DB credentials, always needs chmod 600 after deployment, along with APP_DEBUG=false; otherwise, error pages show stack traces + config values to outsiders.
Layer 3: Grep for vulnerabilities in the code
Check for dangerous patterns that often slip into the code.
# mass-assignment เปิดกว้าง
grep -rn 'protected $guarded = \[\]' app/Models/
# raw SQL ที่ต่อ string ตรง ๆ (SQL injection)
grep -rn 'DB::raw\|whereRaw\|->raw(' app/ | grep -v '?'
# echo ตัวแปรดิบใน blade (XSS)
grep -rn '{!! *\$' resources/views/
# ฟังก์ชันอันตราย
grep -rn 'eval(\|shell_exec\|system(\|proc_open' app/ routes/
{!! $var !!} in blade is a classic XSS entry point (escaping is disabled) — if the variable comes from a user, change it to {{ }} or sanitize it first.
Fixing order: P0 → P2
- P0 — Close credential leaks: .env/.git returning 200, loose .env permissions, APP_DEBUG=true
- P1 — Fix hardening gaps: accessible debug endpoints, fingerprints revealing versions, missing security headers
- P2 — defense-in-depth: overly broad mass-assignment, raw SQL, XSS in the code — work through deeper fixes
The order matters because P0 issues "leave the door wide open for anyone to walk in" and must be closed first, while P2 reduces the impact when an attack actually happens — prioritizing correctly avoids wasting time polishing code while the front door is still open.
All three layers take less than five minutes combined. I put them into a single script and run it after every deployment — better than waiting for someone else to find a vulnerability.
In summary, Laravel security in production usually fails on forgotten basics rather than complex vulnerabilities — files that should be inaccessible are exposed, permissions are too loose, and debug mode is left on. Making these three layers of checks a habit after every deployment will eliminate nearly all of these problems. If you maintain several Laravel sites, feel free to turn them into a routine script. If I have left anything out or made a typo, I will come back and correct it later.
Want us to set this up?
Get help with server setup, configuration, migration, or troubleshooting. Save time for the work that matters.
Hit something like this? Stuck somewhere?
Come trade notes on the LinuxThai board



Comments 0
No comments yet — be the first