SyntaxStudy
Sign Up
Web Security Defence in Depth and the Principle of Least Privilege
Web Security Beginner 1 min read

Defence in Depth and the Principle of Least Privilege

Defence in depth is a security strategy that layers multiple independent controls so that the failure of any single control does not result in a complete breach. Inspired by medieval castle architecture — moat, walls, gates, and keep — modern web applications layer network firewalls, WAFs, TLS, authentication, authorisation, input validation, output encoding, and logging. An attacker who bypasses the WAF still faces authentication; one who steals a session token still cannot escalate to admin without further privilege. The principle of least privilege (PoLP) states that every user, process, or system component should operate with the minimum permissions required to fulfil its function. A read-only reporting service should connect to the database with a read-only account. A Lambda function that writes to one S3 bucket should have IAM permissions for that bucket only. When a component is compromised, blast radius is limited to what that component could access. Applied together, defence in depth and least privilege create a resilient security posture. Even if an attacker exploits a vulnerability in the application layer, they cannot pivot to the database server because network segmentation blocks direct access, and the database user account has no DROP TABLE permission. Document your security layers in architecture diagrams and review them regularly during threat modeling sessions.
Example
-- SQL: create least-privilege database users for different app roles

-- Read-only reporting user
CREATE USER 'app_reporter'@'10.0.1.%' IDENTIFIED BY 'StrongPassHere!';
GRANT SELECT ON myapp.* TO 'app_reporter'@'10.0.1.%';

-- Application CRUD user (no DROP, no GRANT)
CREATE USER 'app_web'@'10.0.1.%' IDENTIFIED BY 'AnotherStrongPass!';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'app_web'@'10.0.1.%';

-- Migration user (used only during deployments)
CREATE USER 'app_migrate'@'127.0.0.1' IDENTIFIED BY 'MigrationPass!';
GRANT ALL PRIVILEGES ON myapp.* TO 'app_migrate'@'127.0.0.1';
-- Revoke after migration: DROP USER 'app_migrate'@'127.0.0.1';

-- Verify grants
SHOW GRANTS FOR 'app_web'@'10.0.1.%';

-- PHP: connect with the least-privilege web user
// $pdo = new PDO(
//     'mysql:host=db.internal;dbname=myapp',
//     'app_web',
//     getenv('DB_PASS_WEB'),
//     [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
// );