Changes between Initial Version and Version 1 of P9Security


Ignore:
Timestamp:
01/22/26 01:57:50 (3 weeks ago)
Author:
193284
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P9Security

    v1 v1  
     1= Phase 9 — Security (SQL Injection & Least Privilege) =
     2
     3== Overview ==
     4This section explains how security is enforced in the Wedding Planner database system, with a focus on SQL injection prevention and the principle of least privilege.
     5Security is implemented through a combination of database-level controls, safe query practices, and role-based access management in PostgreSQL.
     6
     7== What we cover in this phase ==
     8 * SQL injection prevention through parameterized queries
     9 * Database-level protection using constraints
     10 * Role-based access control (RBAC)
     11 * Least privilege principle for database users
     12
     13== SQL Injection Prevention ==
     14
     15=== Description ===
     16SQL injection occurs when user input is directly concatenated into SQL queries, allowing attackers to manipulate query logic and access or modify unauthorized data.
     17
     18Examples include:
     19 * bypassing authentication
     20 * reading private wedding or user data
     21 * deleting bookings or entire tables
     22
     23=== Example: Unsafe vs Safe Query ===
     24
     25'''Unsafe (vulnerable to SQL injection)'''
     26{{{
     27SELECT * FROM "user"
     28WHERE email = 'user_input';
     29}}}
     30
     31If user_input = 'x' OR '1'='1', all users are returned.
     32
     33'''Safe (parameterized query)'''
     34{{{
     35SELECT * FROM "user"
     36WHERE email = $1;
     37}}}
     38
     39=== Reason for use ===
     40Parameterized queries ensure that malicious input is always treated as data, not executable SQL code.
     41
     42== Input Validation and Domain Constraints ==
     43While application-level validation is applied, the database also enforces security-related constraints:
     44 * NOT NULL on mandatory fields (email, names)
     45 * UNIQUE constraints to prevent duplicate accounts
     46 * CHECK constraints to prevent invalid values
     47
     48These rules ensure that even if malicious input reaches the database, it cannot violate domain rules.
     49
     50== Principle of Least Privilege ==
     51
     52=== Concept ===
     53The principle of least privilege states that each user or service should have only the minimum permissions required to perform its tasks.
     54
     55In the Wedding Planner system, different database roles are created for different responsibilities.
     56
     57=== Role-Based Access Control (RBAC) ===
     58Roles used in our application:
     59 * wp_app_user – used by the application backend
     60 * wp_admin – used only for schema migrations and maintenance
     61 * wp_readonly – used for reporting or analytics
     62
     63=== Example ===
     64{{{
     65CREATE ROLE wp_app_user LOGIN PASSWORD 'strong_password';
     66
     67GRANT CONNECT ON DATABASE wedding_planner TO wp_app_user;
     68GRANT USAGE ON SCHEMA public TO wp_app_user;
     69
     70GRANT SELECT, INSERT, UPDATE, DELETE
     71ON "user", wedding, venue, venue_booking
     72TO wp_app_user;
     73}}}
     74
     75=== Explanation ===
     76This role represents the database user used by the application backend.
     77It is allowed to connect to the database and use the public schema, but its privileges are strictly limited to data manipulation on specific application tables.
     78
     79=== Reason for use ===
     80This approach enforces the principle of least privilege and reduces the impact of:
     81 * application bugs
     82 * SQL injection vulnerabilities
     83 * compromised application credentials
     84
     85Even if the application role is abused, attackers cannot DROP tables, ALTER constraints/triggers, or access data outside the permitted scope.
     86
     87== Protecting Sensitive Data ==
     88
     89=== Example 1: Unauthorized Data Access Prevention ===
     90In the Wedding Planner system, sensitive data protection is enforced by ensuring that queries are always scoped to the authenticated user and never rely on client-supplied identifiers alone.
     91
     92Example endpoint:
     93{{{
     94GET /weddings/{id}/guests
     95}}}
     96
     97Potential attack scenario:
     98An attacker could attempt to access another user’s wedding by guessing or manipulating the wedding ID.
     99
     100To prevent this, the database query always filters by both wedding ID and the authenticated user ID.
     101
     102'''SQL code'''
     103{{{
     104SELECT g.*
     105FROM guest g
     106JOIN wedding w ON w.wedding_id = g.wedding_id
     107WHERE g.wedding_id = $1
     108  AND w.user_id = $2;
     109}}}
     110
     111'''Explanation'''
     112$1 represents the wedding ID from the request, while $2 represents the authenticated user’s ID.
     113
     114'''Reason for use'''
     115If the wedding does not belong to the user, the query returns no results, keeping data secure.
     116
     117=== Example 2: Availability Query Without Sensitive Data Exposure ===
     118Example endpoint:
     119{{{
     120GET /availability/venue?date=2026-06-10
     121}}}
     122
     123Potential attack scenario:
     124An attacker could try to infer booking details for venues by repeatedly