🚧 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 › Capstone Project: Full-Stack Web Application Build, Documentation, and Defense › Lesson 2
TEC-WEB46-08 · Lesson 2 · 80 clock hours · lab

Iterative Development: Backend, Database, and API Build

Objective. The student will implement the application's backend in Python (Flask or Django) or PHP, wire it to a PostgreSQL database using parameterized queries, and expose a documented REST API — all committed through pull requests on the develop branch — while eliminating SQL injection and XSS vulnerabilities confirmed by instructor code review.

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

Iterative Development: Backend, Database, and API Build

This lab spans three one-week sprints. Each sprint ends with a working, tested feature merged into your `develop` branch through a pull request. By the end of all three sprints you will have a Python (Flask or Django) or PHP 8 backend, a PostgreSQL 15 database, and a documented REST API — all protected against the most common web vulnerabilities.

Sprint Structure and Why It Matters

A sprint is a fixed-length cycle in which a team delivers working software. Using sprints trains you to break a large project into manageable pieces, ship code frequently, and get feedback before problems compound. Each sprint here has the same rhythm: plan the feature, write tests first (or alongside), build, run CI, conduct a peer security audit, then merge.

Parameterized Queries: Your Primary Defense Against SQL Injection

SQL injection is consistently listed in the OWASP Top Ten because it allows an attacker to manipulate your database by inserting SQL syntax into user-supplied input. The fix is always the same: use parameterized queries (also called prepared statements). Never concatenate user input directly into a SQL string.

Python / psycopg2 example:

```python

cur.execute(

"SELECT * FROM users WHERE email = %s AND active = %s",

(email, True)

)

```

The database driver sends the SQL template and the data separately. The database engine never interprets the data as code.

PHP / PDO example:

```php

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');

$stmt->execute(['email' => $email]);

```

The `:email` placeholder is filled by the driver, not by string concatenation.

Preventing Cross-Site Scripting (XSS)

XSS occurs when unescaped user data is written into an HTML page and a browser executes it as JavaScript. Flask's Jinja2 and Django's template engine escape variables by default. In PHP, always call `htmlspecialchars()` before echoing user data into HTML. For API responses that return JSON, the browser does not render the JSON as HTML, which reduces XSS risk — but your front end must still escape data before inserting it into the DOM.

Writing Tests and Running CI

A CI (continuous integration) pipeline automatically runs your test suite every time you push a commit or open a pull request. GitHub Actions is configured with a YAML file stored in `.github/workflows/`. A basic Python workflow installs dependencies, runs `pytest`, and reports pass or fail. A failing build blocks the merge — this is the safety net that keeps broken code out of `develop`.

Your test suite must cover at least 70 percent of custom functions and every function that touches the database. For Python, `pytest` with `pytest-cov` measures coverage. For PHP, PHPUnit has built-in coverage reporting. Write tests that check both the happy path (valid input returns expected result) and error paths (invalid input raises the correct exception or returns the correct HTTP status code). These skills map directly to the PCEP Python exam areas of functions, error handling, and program logic.

REST API Design and Documentation

A REST API uses standard HTTP methods to express intent: `GET` retrieves data, `POST` creates a resource, `PUT` or `PATCH` updates it, and `DELETE` removes it. Each endpoint should return a consistent JSON structure and an appropriate HTTP status code (200, 201, 400, 401, 403, 404, 500). Use Postman or `curl` to test each endpoint manually during development, and keep a simple API reference document (a Markdown table or an OpenAPI YAML file) updated as you build.

The Peer Security Audit

Before each sprint closes, your partner attempts SQL injection against your login and search endpoints and inspects your HTML output for unescaped data, using the OWASP Top Ten as a checklist. Every finding becomes a GitHub Issue labeled `security`. You resolve it and close the issue before the sprint ends. This mirrors real-world penetration testing workflows and reinforces defense-in-depth thinking.

Pull Request Discipline

Each sprint's work is committed to a feature branch, then merged into `develop` through a pull request. The PR must show a green CI build and must pass instructor code review at 70 percent or higher on the sprint rubric (logic correctness, security, code style, test coverage). A PR scoring below 70 percent is revised and re-reviewed within three class days. This gate exists to protect code quality — the same way a building inspector must sign off before a structure is occupied.

Key terms8

Parameterized queryA database query in which user-supplied values are passed separately from the SQL template, preventing the database engine from treating input as executable SQL code.
SQL injectionAn attack in which malicious SQL syntax is inserted into user input and executed by the database, potentially exposing or destroying data; listed in the OWASP Top Ten.
XSS (Cross-Site Scripting)A vulnerability in which unescaped user data is rendered in a browser as executable JavaScript, allowing attackers to hijack sessions or steal data.
Continuous integration (CI)An automated process that builds and tests code every time a commit is pushed, providing rapid feedback and blocking merges when tests fail.
JWT (JSON Web Token)A compact, signed token issued by the server after login that the client sends with subsequent requests to prove identity without storing server-side session state.
CRUDThe four fundamental database operations — Create, Read, Update, and Delete — typically mapped to the HTTP methods POST, GET, PUT/PATCH, and DELETE in a REST API.
Password hashingThe process of transforming a plaintext password into a fixed-length digest using a one-way algorithm (such as bcrypt) with a salt, so that stored credentials cannot be reversed if the database is compromised.
Pull request (PR)A mechanism in Git-based workflows in which a developer asks that a feature branch be reviewed and merged into a target branch, providing a checkpoint for code review and CI validation.
In class: Complete three one-week sprints, each ending with a working, tested feature merged via pull request; sprint 1 covers data models and CRUD routes, sprint 2 covers user authentication (hashed passwords, session or JWT), and sprint 3 covers any remaining core features and input validation. · Write a Python or PHP unit test suite covering at least 70 percent of custom functions and all database interaction functions; run tests in a CI step (GitHub Actions or GitLab CI) and fix any failures before merging — maps directly to PCEP Python exam area: functions, error handling, and program logic. · Conduct a peer security audit using the OWASP Top Ten checklist: the partner attempts SQL injection against login and search endpoints and inspects HTML output for unescaped user data; findings are logged as GitHub Issues and resolved before the sprint closes.
Materials: Python 3 (Flask or Django) or PHP 8, PostgreSQL 15, psycopg2 or PDO library, Postman or curl for API testing, pytest or PHPUnit, GitHub Actions YAML reference, OWASP Top Ten (owasp.org), instructor sprint review form, VS Code with ESLint and Pylint plugins
Check: Each sprint pull request must pass automated CI tests (green build) and instructor code review scoring 70 percent or higher on the sprint rubric (logic correctness, security, code style, test coverage); a sprint scoring below 70 percent is revised and re-reviewed within three class days before the next sprint begins.

Practice check8

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

CompTIA ITF+ — Security concepts; PCEP Python — program logic and functions
1. A student writes the following Python code to log in a user: `query = 'SELECT * FROM users WHERE email = ' + email`. Which vulnerability does this code introduce?
PCEP Python — functions and program logic
2. Which psycopg2 call correctly uses a parameterized query to fetch a user by email?
CompTIA ITF+ — Security threats and vulnerabilities
3. During the peer security audit, a partner finds that a search result page reflects the query string directly into the HTML without escaping. Which OWASP Top Ten category does this finding belong to?
CompTIA ITF+ — Security best practices
4. A student stores a new user's password in the database as plaintext. Which Sprint 2 requirement does this violate?
PCEP Python — error handling and program logic
5. A GitHub Actions workflow runs `pytest` on every push. The test run reports three failing tests. What must the student do before merging the pull request?
PCEP Python — functions and program logic; CompTIA ITF+ — networking basics
6. A Flask route should return HTTP status 201 when a new resource is created successfully. Which response is correct?
PCEP Python — functions, error handling, and program logic
7. A student needs to test that a database insert function raises a `ValueError` when given an empty string for a required field. Using pytest, which approach is correct?
CompTIA ITF+ — professional skills and project workflow
8. A sprint pull request scores 65 percent on the instructor rubric. According to the course policy, what happens next?
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.