🚧 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 › PHP and Python Web Programming › Lesson 10
TEC-WEB46-03 · Lesson 10 · 13 clock hours · theory

Web Security: Common Vulnerabilities and Defensive Coding in PHP and Python

Objective. Students identify SQL injection, XSS, cross-site request forgery (CSRF), and insecure direct object reference vulnerabilities in provided code samples and apply the corresponding remediation technique in both PHP and Python

⚠ 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.

Why Web Security Matters

Every web application you build is a potential target. Attackers probe sites continuously, looking for predictable mistakes in how code handles user input, manages sessions, or controls access to data. Four vulnerabilities appear so consistently across real-world breaches that the Open Web Application Security Project (OWASP) has tracked them in its Top Ten list for years: SQL injection, cross-site scripting (XSS), cross-site request forgery (CSRF), and insecure direct object reference (IDOR). Learning to recognize these flaws and apply the correct fix is a core professional skill — and a legal responsibility when you handle other people's data.

SQL Injection

SQL injection happens when user-supplied input is concatenated directly into a database query without sanitization. An attacker types SQL syntax into a form field, and the database executes it as a command rather than treating it as data.

Vulnerable PHP example:

```php

$query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "'";

```

If the user types `' OR '1'='1`, the query returns every row in the table.

Remediation — Prepared Statements with Parameterized Queries:

```php

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");

$stmt->execute([$_POST['username']]);

```

The database driver separates code from data; no input can change the query structure.

Python (with sqlite3 or a library such as psycopg2):

```python

cursor.execute("SELECT * FROM users WHERE username = %s", (username,))

```

Always use the placeholder syntax provided by the database driver — never format strings into queries.

Cross-Site Scripting (XSS)

XSS occurs when an application echoes user input back to the browser without encoding it. The browser interprets the input as HTML or JavaScript and executes it. An attacker can steal session cookies, redirect users, or deface a page.

Vulnerable PHP:

```php

echo "Hello, " . $_GET['name'];

```

Input of `<script>alert(document.cookie)</script>` runs in every visitor's browser.

Remediation — Output Encoding:

```php

echo "Hello, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');

```

`htmlspecialchars()` converts `<`, `>`, `"`, and `'` to safe HTML entities.

Python (Jinja2 templating, used in Flask): Auto-escaping is enabled by default in Jinja2 when you render `.html` templates. Never mark user data `safe` unless you have specifically sanitized it. If building strings manually, use Python's `html.escape()` function.

Cross-Site Request Forgery (CSRF)

CSRF tricks a logged-in user's browser into sending an unwanted request to your application. Because the browser automatically includes cookies, the server cannot tell the request is forged. A common attack embeds an invisible form or image tag on a malicious page that submits a state-changing action (like changing a password or placing an order) to your site.

Remediation — Synchronizer Token Pattern:

1. When the form loads, generate a random, unpredictable token and store it in the user's session.

2. Embed the token as a hidden field in the form.

3. On submission, compare the posted token to the session token. Reject the request if they do not match.

An attacker on a different origin cannot read the victim's session token, so the forged request will fail the check.

PHP example (token generation and validation):

```php

// Generate token and store in session

$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

// In the form

echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';

// On form submission

if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {

die('CSRF validation failed.');

}

```

Use `hash_equals()` rather than `==` to prevent timing attacks.

Python / Flask: The Flask-WTF extension provides CSRF protection automatically via its `CSRFProtect` class and `{{ form.hidden_tag() }}` template tag.

Insecure Direct Object Reference (IDOR)

IDOR occurs when an application exposes an internal identifier — such as a database record ID — directly in a URL or form parameter, and does not verify that the requesting user is authorized to access that record.

Example: `https://example.com/invoice?id=1042` — if the application fetches the invoice matching `id` without checking ownership, changing `1042` to `1041` may display another customer's invoice.

Remediation:

PHP:

```php

$stmt = $pdo->prepare("SELECT * FROM invoices WHERE id = ? AND user_id = ?");

$stmt->execute([$_GET['id'], $_SESSION['user_id']]);

```

Python:

```python

cursor.execute("SELECT * FROM invoices WHERE id = %s AND user_id = %s",

(invoice_id, session['user_id']))

```

Safety and Professional Responsibility

Handling other people's personal data carries legal obligations under statutes such as state breach-notification laws and, where applicable, federal sector-specific rules (health, financial). Even in a vocational training environment:

Defensive coding is not optional polish; it is the standard of care expected of every professional web developer.

Key terms8

SQL InjectionAn attack in which malicious SQL syntax is inserted into a user-input field and executed by the database, potentially exposing or destroying data.
Parameterized QueryA database query technique that separates the SQL command from user-supplied data using placeholders, preventing SQL injection.
Cross-Site Scripting (XSS)An attack in which an application echoes unencoded user input to the browser, allowing malicious scripts to execute in other users' sessions.
Output EncodingConverting special characters such as < and > into HTML entities before displaying user-supplied data, preventing the browser from interpreting them as code.
Cross-Site Request Forgery (CSRF)An attack in which a malicious site tricks a logged-in user's browser into sending an unintended, authenticated request to a target application.
CSRF TokenA random, session-bound secret embedded in a form and verified on submission; it prevents forged cross-origin requests because an attacker cannot read the token.
Insecure Direct Object Reference (IDOR)A vulnerability in which an application exposes internal identifiers (such as record IDs) in URLs or parameters without verifying that the requesting user is authorized to access the referenced resource.
OWASP Top TenA widely referenced list published by the Open Web Application Security Project identifying the most critical security risks to web applications.
In class: Students read the OWASP Top Ten overview (owasp.org) and for each of the four vulnerabilities covered in the lesson, write a one-paragraph plain-language explanation of the attack mechanism and one-sentence description of the defensive technique · Vulnerability hunt: instructor provides four intentionally vulnerable PHP and Python code files (one per vulnerability); students identify the vulnerability, write a test input that would exploit it, then apply the remediation and confirm the attack no longer works · Students add CSRF token generation and validation to their PHP product-management page from Lesson 9 and document the implementation steps in their lab log, explaining why CSRF tokens prevent the attack
Materials: OWASP Top Ten (owasp.org), PHP manual (CSRF, htmlspecialchars), Python docs, instructor-provided vulnerable code files, VS Code, student lab log template
Check: Vulnerability hunt: all four vulnerable files correctly identified, exploited with a test input, and remediated; CSRF implementation is functional; written explanations are accurate — pass requires all four remediations working and explanations graded accurate by instructor

Practice check8

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

Security concepts / secure coding
1. A developer builds the following PHP query: `$sql = "SELECT * FROM orders WHERE id = " . $_GET['id'];`. Which vulnerability does this code contain?
Security concepts / secure coding
2. Which PHP function should be used to encode user-supplied output before displaying it in an HTML page to prevent XSS?
Security concepts / secure coding
3. A Flask application uses Jinja2 templates. A developer writes `{{ user_comment | safe }}` to render a comment. What is the security risk?
Security concepts / secure coding
4. Which of the following best describes how a CSRF attack works?
Security concepts / secure coding
5. A PHP application validates a CSRF token using `if ($_POST['csrf_token'] == $_SESSION['csrf_token'])`. A developer recommends replacing `==` with `hash_equals()`. Why?
Security concepts / secure coding
6. A web application displays invoice details at `/invoice?id=55`. A logged-in user changes the URL to `/invoice?id=54` and sees a different customer's invoice. The server fetched the record using only `WHERE id = 54` with no ownership check. This is an example of which vulnerability?
Security concepts / secure coding
7. Which Python database query pattern correctly prevents SQL injection when using a cursor from a standard DB-API 2.0 library?
Security concepts / professional and legal responsibility
8. When conducting the vulnerability hunt activity, a student wants to test a real government website to verify their SQL injection technique works on a live system. What is the correct action?
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.