Skip to main content

Hack Smarter Web App Pentest - Portfolio Writeup

Updated 7 min readMarkdown
Hack Smarter Web App Pentest - Portfolio Writeup

I recently wrapped up the Hack Smarter web app pentesting course, and this is my capstone for it. Honestly, I learned a ton here, and most of it was hands-on, which is the only way this stuff really sticks for me. Going from "here's what a vulnerability is" to actually chaining a SQL injection into full account takeover on a live app is a different kind of learning. If you're getting into web app pentesting, I'd recommend it.

This is the short version, focused on the three findings that tell the best story. The full report covers all 13.

This writeup walks through the three flagship findings that chain together into full account and data compromise. Testing was authorized and the results are shareable.

Risk at a glance

Overall: Critical. A single unauthenticated SQL injection reads the entire database, including the user table and password hashes. Those hashes meet almost no resistance, no login rate limiting and a weak password policy which can convert directly into account takeover. A separate stored-XSS flaw hijacks live sessions. Either path ends in the same place: full control of accounts and data.

The three findings below are chosen because they tell that story end to end. The full engagement includes all 13 findings with CVSS vectors, remediation roadmap and evidence in the complete report.

At a glance: the attack chain

how the confirmed findings combine

how the confirmed findings combine

SQL injection alone reads the whole database, and its dumped hashes ,cracked against weak passwords with no brute-force protection, hand over accounts. Separately, stored XSS hijacks a live session. Either path reaches account takeover and full data compromise.

F-01 -  SQL injection, full database compromise

Critical · CVSS 9.8 · AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H · CWE-89 · unauthenticated

The search parameter on store.php is concatenated straight into the SQL query. A single quote returned a MySQL syntax error, confirming the input reaches the database unparameterized.

store.php search parameter returning a MySQL syntax error

store.php?search=%27 - the database error that confirms injection.

From there, SQLMap enumerated five databases and dumped the application's users table with usernames, roles and password hashes  with no authentication.

SQLMap listing the four tables in the hacksmarter database

The hacksmarter database and its tables.

SQLMap dump of the users table with hashes redacted

The users table dumped - hashes redacted; is_admin=1 marks the admin account.

Impact. Unauthenticated full read of every database on the server including all accounts and password hashes. Those hashes feed the takeover chain below.

Fix. Allow-list the sort/search inputs and use parameterized queries everywhere; run the database user with least privilege.

F-02 - Brute force to account takeover

High · CVSS 8.1 · AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N · CWE-307

The login form has no lockout, throttling, CAPTCHA or delay. A rockyou.txt run against the confirmed username user completed uninterrupted across 6,246 attempts; the correct password stands out by its HTTP status code and response length.

Caido list of 6,246 password attempts separated by status and length

6,246 attempts, no throttling - status code and response length isolate the valid password.

Impact. This is where F-01 pays off: the dumped hashes, cracked against a wordlist with no brute-force protection, become working logins  including privileged accounts. Username enumeration (F-11) and a weak password policy (F-12) make it faster still.

Fix. Lock or throttle after a few failures, per account and per IP, add MFA for staff and check new passwords against breached-password lists.

F-03 - Stored cross-site scripting

High · CVSS 7.6 · AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N · CWE-79

User input is stored and later rendered without output encoding, so injected script runs in the browser of anyone who views it. The session cookie has no HttpOnly flag, so script can read it.

Browser alert leaking the PHPSESSID value via stored script

Stored payload reads document.cookie and leaks the PHPSESSID which shows the session can be stolen from the script.

Impact. This is the second route into the chain where an attacker steals a victim's session and acts as them. If an admin views the content, the back office falls, no password needed.

Fix. Context-encode all user content on output; set the session cookie HttpOnly, Secure, SameSite=Strict; add a Content-Security-Policy.

Takeaways

None of these bugs is exotic, they're all textbook OWASP issues. What makes them critical is when a threat actor combines them. One injection point reads the credentials, the missing brute-force controls crack them, and a single stored script hijacks whatever the injection didn't reach. Fixing any one link weakens the chain. Fixing the shared root causes such as the unencoded output and unparameterized queries , breaks it.

The three highest-leverage fixes:

  1. Parameterize every database query (closes F-01).

  2. Add login rate limiting and a real password policy (closes F-02, and defangs the dumped hashes).

  3. Encode all user-supplied output and set HttpOnly cookies (closes F-03 and the other XSS/HTML-injection findings).

The full engagement covers 13 findings which includes session fixation, IDOR, reflected XSS, and session-invalidation gaps , each with evidence, CVSS scoring, and a remediation roadmap, plus an appendix of what was tested clean and what's queued next.

Appendix: reading the CVSS vector

Each finding carries a CVSS v3.1 base vector , a shorthand for how the score was reached. Reading AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (F-01) left to right:

Metric In F-01 Means Possible values
AV — Attack Vector N Network — exploitable remotely over the internet N (Network), A (Adjacent), L (Local), P (Physical)
AC — Attack Complexity L Low — no special conditions needed L (Low), H (High)
PR — Privileges Required N None — attacker needs no account N (None), L (Low), H (High)
UI — User Interaction N None — no victim action required N (None), R (Required)
S — Scope U Unchanged — impact stays within the vulnerable component U (Unchanged), C (Changed)
C — Confidentiality H High — total loss of data confidentiality H (High), L (Low), N (None)
I — Integrity H High — total loss of data integrity H (High), L (Low), N (None)
A — Availability H High — total loss of availability H (High), L (Low), N (None)

In plain terms, that vector says: an attacker anywhere on the network, with no account and no help from a victim, can easily and fully compromise the data's confidentiality, integrity and availability which is why F-01 scores 9.8 (Critical).

Scope (S) is the one that trips people up: it flips to Changed when the vulnerable component can impact resources beyond itself. That's why the stored-XSS finding (F-03) uses S:C , a flaw in the web app executes in a victim's browser, a different security authority.

The base score (0.0–10.0) is computed from these eight metrics and maps to the severity bands used throughout: Critical 9.0–10.0, High 7.0–8.9, Medium 4.0–6.9, Low 0.1–3.9. You can plug any vector into the FIRST CVSS v3.1 calculator to see the math.

About the author

  • Cybersecurity Professional | Writer | Frontend Developer

No comments yet. Be the first to comment.