Principle of Least Privilege
Also Known As
PoLP
least privilege
minimum privilege principle
TL;DR
Every component should operate with the minimum permissions required to do its job — nothing more.
Explanation
PoLP limits the blast radius of a compromise. A database user that can only SELECT and INSERT cannot DROP tables if SQL injection occurs. A PHP process that can only write to /var/www/uploads cannot overwrite system files if file upload validation fails. Apply PoLP at every layer: database users, OS file permissions, API token scopes, and PHP function allow-lists. Regularly audit what permissions are actually needed vs. what is granted.
Common Misconception
✗ Least privilege only applies to user accounts and database permissions. It applies to every access decision — API tokens scoped to only needed endpoints, service accounts with only required permissions, process users with minimal filesystem access, and PHP code that requests only the extensions it needs.
Why It Matters
Every component should have only the permissions it needs to do its job — limiting blast radius so a compromised component cannot access resources it was never meant to touch.
Common Mistakes
- Database users with GRANT ALL instead of SELECT, INSERT, UPDATE on specific tables.
- Application running as root or with sudo — a compromise gives attacker full system access.
- API keys with write permissions for services that only need read access.
- Developers with production database write access they never use — privileged access should be time-bounded.
Code Examples
✗ Vulnerable
// DB user with excessive privileges:
$pdo = new PDO('mysql:host=db', 'root', 'password'); // Root user in app!
// Compromise = attacker can DROP DATABASE, create admin users, read all data
// Least privilege:
$pdo = new PDO('mysql:host=db', 'app_user', $pass);
// app_user: SELECT, INSERT, UPDATE on app_db.* only — no DROP, no GRANT
✓ Fixed
-- DB user for the web app — only needs SELECT/INSERT/UPDATE/DELETE on app tables
-- Never run the app as root or with GRANT OPTION
CREATE USER 'webapp'@'%' IDENTIFIED BY '...secure...password...';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'webapp'@'%';
-- Separate user for migrations (can ALTER, CREATE, DROP):
CREATE USER 'migrator'@'localhost' IDENTIFIED BY '...';
GRANT ALL PRIVILEGES ON myapp.* TO 'migrator'@'localhost';
-- PHP — never store secrets with broader permissions than needed
-- File permissions: config files 640, not 777
-- PHP-FPM process user: www-data, not root
-- open_basedir restricts PHP to its own directory tree
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
31
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 9
Amazonbot 7
Ahrefs 2
Unknown AI 2
SEMrush 2
Google 1
Also referenced
How they use it
crawler 23
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Medium
⚡ Quick Fix
Give each user, process, and service account only the minimum permissions needed for their specific function — no more
📦 Applies To
PHP 5.0+
web
api
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Database user with root/all privileges; PHP process running as root; queue worker with admin role
Auto-detectable:
✗ No
semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File
CWE-272
CWE-250