Skip to content
All work
Secure Software · Web App
2025–26

FreightDesk — Secure Business Application

A hardened Flask logistics portal with live FX, RBAC and a full security self-assessment

Secure CodingWeb AppOWASPRBAC Code
17
Automated tests
auth · RBAC · CSRF · SQLi · FX
10/10
OWASP Top 10 addressed
each with a mitigation
3
RBAC roles
viewer · clerk · admin
0
String-built SQL
fully parameterised

Context

Built for the Secure Scripting & Business Applications brief (CSEC2001D). Staff sign in against role-based permissions, manage freight shipments in a normalised SQLite database, and see each shipment’s declared value converted to a base currency using exchange rates pulled live over HTTPS from a remote web service.

The problem

The brief’s real test isn’t “can you build a CRUD app” — it’s “can you build one that withstands the common business-application attacks”: SQL injection, broken access control, CSRF, session hijacking and unsafe outbound requests. The emphasis is as much on how it’s secured as on what it does.

My approach

A Flask application factory wires configuration, the database, a remote FX client, authentication, central CSRF enforcement and security headers. Every query is parameterised; passwords are PBKDF2-hashed; access control is enforced server-side with role decorators; and the outbound FX call is HTTPS-only with a timeout, defensive parsing and an offline fallback.

Secure request pipeline

Browser
session + CSRF
Flask app
RBAC · validation
SQLite
parameterised SQL
Remote FX API
HTTPS · cached · fallback
Audit log
append-only

Security-by-design controls

Each control is deliberately hand-rolled so the mechanism is visible and auditable, and each is backed by a test.

  • Injection: parameterised queries everywhere; allow-list input validation
  • Access control: server-side role decorators (viewer < clerk < admin), never UI-only
  • CSRF: per-session token enforced centrally for every state-changing request
  • Session: PBKDF2 hashes, HttpOnly + SameSite cookies, session rotation on login
  • Headers: strict CSP, X-Frame-Options DENY, nosniff, Referrer-Policy

Remote web service integration

Shipment values in mixed currencies are converted using live rates from a public FX API — fetched over HTTPS with a short timeout, parsed defensively, cached with a TTL, and gracefully degraded to bundled fallback rates if the service is unreachable. The endpoint is fixed in config, not user-controlled, to resist SSRF.

Self-penetration test (OWASP)

I attacked my own app and documented it: SQL-injection auth-bypass and table-drop payloads (blocked by parameterisation), forced-browsing privilege escalation (403 server-side), CSRF replay (400), reflected-XSS (Jinja autoescape + CSP) and clickjacking (frame-ancestors none) — every finding mapped to the OWASP Top 10 with the mitigation and a test.

Outcome

A production-shaped business application that treats security as a first-class requirement — with a written OWASP self-assessment, a data-protection (UK GDPR) analysis and a green test suite — demonstrating secure development end to end, not just a working feature set.