🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Web & Software Development › SQL and PostgreSQL Database Development › Lesson 11
TEC-WEB46-04 · Lesson 11 · 15 clock hours · lab

Application Integration: Python/PHP with PostgreSQL and SQL Injection Prevention

Objective. Students will connect a Python or PHP application to PostgreSQL using a database driver, execute parameterized queries, and demonstrate that the code is not vulnerable to SQL injection.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Connecting a Python or PHP Application to PostgreSQL

Web and software applications rarely store data inside the program itself. Instead, they connect to a database server, send queries, and receive results. PostgreSQL is a widely used open-source relational database. To connect an application to it you need a database driver — a library that handles the network connection, authentication, and translation of Python or PHP code into messages the database server understands.

A typical connection in psycopg2 looks like this:

```python

import psycopg2

conn = psycopg2.connect(

host="localhost",

dbname="library",

user="student",

password="secret"

)

cur = conn.cursor()

```

In PHP with PDO:

```php

$dsn = "pgsql:host=localhost;dbname=library";

$pdo = new PDO($dsn, 'student', 'secret');

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

```

What Is SQL Injection and Why Is It Dangerous?

SQL injection is one of the most critical and long-standing web application security vulnerabilities. It appears on the OWASP Top 10 list of security risks. It happens when user-supplied input is concatenated directly into a SQL string before being sent to the database. An attacker can craft input that changes the meaning of the query, allowing them to read unauthorized data, modify or delete records, or even execute administrative commands.

Vulnerable example (Python):

```python

term = input("Search author: ")

query = "SELECT * FROM books WHERE author = '" + term + "'"

cur.execute(query)

```

If the user types `' OR '1'='1`, the query becomes:

```sql

SELECT * FROM books WHERE author = '' OR '1'='1'

```

This condition is always true, so every row in the table is returned — a data breach. More destructive payloads can drop tables or bypass login checks entirely.

The Fix: Parameterized Queries

A parameterized query (also called a prepared statement) separates the SQL structure from the user data. The driver sends the query and the parameters to the database in separate steps. The database engine treats the parameter as a literal value, never as executable SQL, no matter what it contains.

Safe example (psycopg2):

```python

term = input("Search author: ")

cur.execute("SELECT * FROM books WHERE author = %s", (term,))

rows = cur.fetchall()

for row in rows:

print(row)

```

Note the `%s` placeholder and the tuple `(term,)` passed as the second argument. psycopg2 handles escaping automatically.

Safe example (PDO):

```php

$stmt = $pdo->prepare("SELECT * FROM books WHERE author = :author");

$stmt->execute([':author' => $term]);

$rows = $stmt->fetchAll();

```

Parameterized queries are always the correct approach when incorporating user input into a query. There is no safe way to manually escape strings that matches the protection level of parameterized queries.

Connection Management and Error Handling

Database connections are limited resources. Leaving connections open wastes server memory and can exhaust the connection pool. Use a context manager in Python to ensure the connection closes even if an error occurs:

```python

import psycopg2

from contextlib import closing

with psycopg2.connect(host="localhost", dbname="library",

user="student", password="secret") as conn:

with closing(conn.cursor()) as cur:

cur.execute("SELECT title FROM books WHERE id = %s", (1,))

print(cur.fetchone())

```

Wrap database calls in try/except (Python) or try/catch (PHP) blocks to catch driver exceptions, log them, and handle failures gracefully without leaking error details to end users.

```python

try:

cur.execute("INSERT INTO books (title, author) VALUES (%s, %s)",

(title, author))

conn.commit()

except psycopg2.DatabaseError as e:

conn.rollback()

print("Database error. Transaction rolled back.")

```

Always call `conn.commit()` after INSERT, UPDATE, or DELETE. If an error occurs, call `conn.rollback()` to undo partial changes.

Building a CRUD Command-Line Application

A complete application needs four operations:

| Operation | SQL Statement | Notes |

|-----------|--------------|-------|

| Create | `INSERT INTO books ...` | Use parameterized values; commit after |

| Read | `SELECT * FROM books ...` | Use parameterized WHERE clause |

| Update | `UPDATE books SET ... WHERE id = ...` | Always filter by primary key |

| Delete | `DELETE FROM books WHERE id = ...` | Confirm before deleting; commit after |

Structure your application with one function per operation. Each function opens a cursor, executes a parameterized query, and handles its own exception. Keep the main loop simple: prompt the user, call the appropriate function, and display the result.

Security Best Practices Summary

Following these practices protects user data, satisfies employers' security requirements, and demonstrates the professional standards expected in the trade.

Key terms8

psycopg2The most widely used PostgreSQL database adapter for Python; it provides a connection object, cursor, and parameterized query support following the DB-API 2.0 specification.
PDO (PHP Data Objects)A built-in PHP database abstraction layer that supports multiple database backends, including PostgreSQL, through a consistent interface that includes prepared statements.
Parameterized queryA query in which user-supplied values are passed to the database separately from the SQL text using placeholders, so the database engine treats them as data rather than executable code.
SQL injectionAn attack in which malicious SQL code is inserted into an input field and executed by the database because the application concatenated user input directly into a query string.
Context managerA Python language construct (using the 'with' statement) that guarantees a resource such as a database connection is properly closed when the block exits, even if an exception occurs.
Connection poolA cache of reusable database connections maintained by a library or middleware, reducing the overhead of opening and closing a connection for every request.
OWASP Top 10A regularly updated list published by the Open Worldwide Application Security Project identifying the ten most critical web application security risks; SQL injection has historically appeared on this list.
Commit / RollbackDatabase transaction controls: commit makes all changes in a transaction permanent, while rollback undoes them — essential for maintaining data integrity when errors occur during write operations.
In class: Use psycopg2 (Python) or PDO (PHP) to write a script that connects to the library database, retrieves rows matching a user-supplied search term using a parameterized query, and prints formatted results to the terminal. · Demonstrate the SQL injection vulnerability by first writing the search query using string concatenation, then attempt an injection payload (e.g., ' OR '1'='1); document the result, then fix the code with parameterized queries and show the injection attempt is neutralized. · Build a small command-line CRUD application (create, read, update, delete a book record) using parameterized queries, error handling (try/except or try/catch), and connection pooling or context-manager-style connection management.
Materials: Python 3 with psycopg2, or PHP 8 with PDO, library database, VS Code, OWASP SQL Injection Prevention Cheat Sheet, instructor integration code scaffold
Check: Students present their CRUD application; instructor enters a SQL injection payload into the search field and verifies it does not affect the database; pass = application performs all four CRUD operations correctly and injection attempt produces no unintended results.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Security concepts / application security
1. A student writes the following Python query: `cur.execute("SELECT * FROM books WHERE title = '" + user_input + "'")`. What is the primary security risk?
Programming and scripting / database integration
2. Which psycopg2 syntax correctly passes a user-supplied value as a parameterized query?
Security concepts / application security
3. A user enters the string `' OR '1'='1` into a search field. The application uses parameterized queries. What happens?
Programming and scripting / database integration
4. After a successful INSERT in psycopg2, the new row is not visible to other connections. What must the developer call to make the change permanent?
Programming and scripting / database integration
5. Which PHP PDO code correctly uses a named placeholder to prevent SQL injection?
Programming and scripting / database integration
6. A database error occurs during an UPDATE. The developer's code calls `conn.rollback()`. What is the purpose of this call?
Security concepts / access control
7. What is the principle of least privilege as it applies to a database application account?
Programming and scripting / Python fundamentals
8. A developer uses Python's `with` statement to manage a psycopg2 connection. Which statement best describes the benefit?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.