---
# System prepended metadata

title: Challenge report

---

---
title: Challenge report

---

# Juice Shop — Security Lab Report

**Course:** 5SEC1
**Group:** 63731 - Opre Nicoleta & 60991 - Abla Aninia Negue
**Submission date:** 18/10/2025

---

## Summary

This report documents the steps taken to compromise various parts of the Juice Shop web application, detailing the vulnerabilities found, their impact, and evidence. Each challenge includes technical details, reproduction steps, screenshots, and suggested mitigations.

---

## Environment

* **Juice Shop image:** `bkimminich/juice-shop` (Docker)
* **Run command:**

```bash
docker pull bkimminich/juice-shop
docker run --rm -p 3000:3000 bkimminich/juice-shop
```

* **Tools used:** Burp Suite, browser developer tools, text editor.

---

## Completed Challenges

1. **Score Board** — (⭐)
2. **Outdated Whitelist** — (⭐)
3. **DOM XSS** — (⭐)
4. **Confidential Document (FTP)** — (⭐)
5. **Five-Star Feedback** — (⭐⭐)
6. **Upload Type** — (⭐⭐⭐)
7. **Login Jim** — (⭐⭐⭐)
8. **Forged Review** — (⭐⭐⭐)
9. **Login Bender** — (⭐⭐⭐)
10. Bjoern’s Favorite Pet - (⭐⭐⭐)
11. **Legacy Typosquatting** - (⭐⭐⭐⭐)
12. **Forgotten Sales Backup** - (⭐⭐⭐⭐)
13. **Poison Null Byte** - (⭐⭐⭐⭐)
14.  **forged feedback** - (⭐⭐⭐)

---

# 1. Score Board

**Vulnerability Type:** Miscellaneous

**Difficulty:** ⭐


**Description:** The hidden Score Board page is accessible without authentication and exposes challenge metadata and internal links. This administrative page is supposed to be hidden from regular users, but anyone who discovers the URL can access it. The page shows all security challenges, their difficulty levels, and tracks which ones have been solved


**Reproduction Steps:**

1. Open `http://localhost:3000`.
2. Open Developer Tools (F12) → Go to the Sources tabor `board`.
3. Search for keywords like score or board in the JavaScript files
4. Discover the /score-board route in the application code
5. Navigate directly to http://localhost:3000/#/score-board

**Evidence:** 
![score_board](https://hackmd.io/_uploads/S17UfCyCll.png)

**Root Cause:** Debug or tracking page left accessible in production build. The application doesn't check if the user should have access to this page - it only checks if they know the correct URL. This is a common security misconfiguration where development or testing features are accidentally left enabled in production.

---

# 2. Outdated Allowlist

**Vulnerability Type:** Unvalidated Redirects

**Difficulty:** ⭐

**Description:** The application has a redirect feature that accepts a to parameter in the URL (like /redirect?to=...) and automatically sends users to whatever address is provided. The problem is that this redirect doesn't properly check if the destination is safe - it will happily redirect users to external websites, including potentially malicious ones.

An attacker could use this to create fake links that look legitimate (they start with the Juice Shop domain) but end up redirecting victims to phishing sites.



**Reproduction Steps:**

1. In the browser, navigate to this URL:
```
http://localhost:3000/redirect?to=https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm
```

2. Observe that the application redirects your browser to the external blockchain.info website.

3. The redirect works with any external domain - the application doesn't verify if the destination is safe

**Evidence:**

*Client-side code showing the redirect being used:

  * Image: ![outdated-link-sources](https://hackmd.io/_uploads/HkEufRy0lx.png)


* Browser showing the redirect URL still on Juice Shop domain before redirecting:

  * Image: ![outdated-link](https://hackmd.io/_uploads/ByW9zAJ0gx.png)


* Final page after redirection (external Bitcoin site):

  * Image: ![outdated-link-bitcoin](https://hackmd.io/_uploads/ry09M0yCgx.png)


**Root Cause:**
The redirect endpoint accepts any URL without proper validation. The server either has no whitelist at all, or the whitelist is outdated and doesn't block external domains. Since the redirect link starts with the legitimate Juice Shop domain, users might trust it and click without realizing they'll end up on a different website.

---

# 3. DOM XSS 

**Vulnerability Type:** XSS

**Difficulty:** ⭐


**Description:** The search bar doesn't properly clean user input before displaying it on the page. When I search for something, the application takes my text and directly inserts it into the webpage (the DOM) without checking if it contains dangerous code. This means I can inject JavaScript code that will run in anyone's browser who sees the search results. In this case, I used an iframe with JavaScript to trigger an alert box, proving that code execution is possible.

**Reproduction Steps:**

1. Go to the Juice Shop homepage at http://localhost:3000
2. Click on the search bar at the top of the page
3. Enter this malicious payload:

```html
<iframe src="javascript:alert(`xss`)"></iframe>
```

![ch3-1](https://hackmd.io/_uploads/HJ22GRJRgl.png)


4. Press Enter or click the search button

5. An alert box appears with "xss" - this proves that JavaScript code was executed

![ch3-2](https://hackmd.io/_uploads/ryupfRkRel.png)

**Root Cause:** The application takes the search input and directly inserts it into the HTML page without sanitizing or escaping it first. When the page displays "Search results for: [your input]", it doesn't convert dangerous characters like < and > into safe versions. This allows HTML tags and JavaScript code to be interpreted and executed by the browser instead of being displayed as plain text.

---

# 4. Confidential Document

**Vulnerability Type:** Sensitive Data Exposure

**Difficulty:** ⭐

**Description:** The application has a publicly accessible file directory at /ftp that contains sensitive documents. Anyone can browse this directory and download files without needing to log in or have special permissions. Among these files, there's a document called acquisitions.md that contains confidential business information about company acquisitions. This is a serious data leak because these documents should only be accessible to authorized employees.


**Reproduction Steps:**

1. While exploring the application, I found a link to the FTP directory

![ftp](https://hackmd.io/_uploads/S19WE0JAgg.png)

2. Navigate to http://localhost:3000/ftp in the browser

![confidetial-document-site](https://hackmd.io/_uploads/S1o_VCJ0lg.png)

3. Click on files like acquisitions.md to download them
4. Open the downloaded file and read its contents - no authentication required

![evidence](https://hackmd.io/_uploads/HkvR4AJAgg.png)

**Root Cause:** The FTP directory is exposed through a web route without any access control. The server doesn't check if the user is logged in or has permission to view these files - it just serves them to anyone who knows the URL. This is a configuration mistake where sensitive files are placed in a publicly accessible location.

---
# 5. Five-Star Feedback

**Vulnerability Type:** Broken Access Control

**Difficulty:** ⭐⭐

**Description:**
This challenge combines two vulnerabilities. First, I used SQL injection to bypass the login and access an admin account without knowing the password. Once logged in as admin, I discovered that I could delete customer feedback from the administration panel. The application doesn't properly check if users should have permission to delete feedback - it just assumes that if you can access the admin page, you're allowed to do anything there.

**Reproduction Steps:**

1. **Bypass authentication with SQL injection:**

   * Go to the login page at  http://localhost:3000/#/login
2. In the Email field, enter this SQL injection payload
   
     ```text
     admin@juice-sh.op' --
     ```

3. In the Password field, type anything (like "test" or "12345") - it doesn't matter because the SQL injection skips the password check

4. Click Log in
   ![admin](https://hackmd.io/_uploads/HyD3HAyAxe.png)



 **Locate the feedback delete endpoint:**

5. Navigate to the administration panel at http://localhost:3000/#/administration
6. Find the customer feedback section showing all reviews

7. Click the trash icon next to any 5-star feedback to delete it
---
![5star](https://hackmd.io/_uploads/B16vU0JCel.png)

**Root Cause:**

* The authentication endpoint is vulnerable to SQL injection (insecure concatenation of user input into database queries), allowing attackers to bypass password checks and assume other users' identities.

---

# 6. Upload Type

**Vulnerability Type:** Improper Input Validation

**Difficulty:** ⭐⭐⭐

**Description:** The file upload feature only checks file types on the client side (in the browser), not on the server. The application seems to only accept PDF files when you try to upload normally, but this validation happens in JavaScript before sending the file. By using Burp Suite to intercept the upload request, I can modify the filename and content type after the client-side check but before it reaches the server. The server then accepts any file type because it trusts that the client-side validation already did the security check

**Reproduction Steps:**

1. Navigate to the file upload feature in the application (usually in the complaint section)
![test-upload-pdfUpload](https://hackmd.io/_uploads/SygNwAkRgl.png)


2. Start uploading a file and configure Burp Suite to intercept the request
3. In Burp Suite's Proxy tab, you'll see the intercepted POST request being sent to the server
![test-upload-post](https://hackmd.io/_uploads/rkD4DRkRee.png)


4. Modify the request in Burp Suite:
  * Change the filename parameter to include a different 
  extension (like .json)
  
  * And change the Content-Type header to a different type
 
5. Forward the modified request to the server
![test-upload-response](https://hackmd.io/_uploads/BJxSv0JAxx.png)

6. The server accepts the file with the forbidden extension
![test-upload-reusi](https://hackmd.io/_uploads/ByUHPCyCxl.png)

**Root Cause:** The application only validates file types in the browser using JavaScript. It doesn't perform any validation on the server side. This means the server blindly trusts whatever the client sends, assuming the browser already checked it. Since we can intercept and modify requests between the browser and server using tools like Burp Suite, the client-side validation is completely useless for security purposes.

---

# 7. Login Jim

**Vulnerability Type:** SQL Injection

**Difficulty:** ⭐⭐⭐

**Description:** The login form is vulnerable to SQL injection in the email field. When the application checks if a user's credentials are correct, it builds a database query using the email and password I provide. However, it doesn't properly clean my input before adding it to the query. By adding special SQL characters like a single quote ' and a comment marker --, I can manipulate the query to skip the password check entirely. This lets me log into Jim's account without knowing his actual password.

**Reproduction Steps:**

1. Go to the login page at http://localhost:3000/#/login

2. In the Email field, enter this SQL injection payload:

```
jim@juice-sh.op'--
```

3. In the Password field, type anything (like "test" or "12345") - it doesn't matter because the injection ignores it

4. Click **Log in**.
![jim](https://hackmd.io/_uploads/SybRwAJRgl.png)

**Result:** Successfully logged in as Jim! The challenge notification pops up confirming the exploit worked.

![Capture d'écran 2025-10-14 223959](https://hackmd.io/_uploads/S1yYdCkCxl.png)

**Root Cause:** The application builds its SQL query by directly inserting user input into the query string without sanitization. The normal query probably looks like: SELECT * FROM Users WHERE email = 'USER_INPUT' AND password = 'PASSWORD'. When I inject jim@juice-sh.op'--, the single quote ' closes the email string, and the double dash -- is a SQL comment that makes everything after it (including the password check) get ignored. So the query becomes: SELECT * FROM Users WHERE email = 'jim@juice-sh.op' - no password needed!

---

# 8. Forged Review

**Vulnerability Type:** Broken Access Control

**Difficulty:** ⭐⭐⭐

**Description:** The review system doesn't properly check who is submitting a review. When I post a review, the application lets me specify the author name in the request itself. The server doesn't verify that I'm actually that user - it just trusts whatever author name I send. This means I can write reviews that appear to come from other users, potentially damaging their reputation or making fake positive/negative reviews look like they came from legitimate customers.



**Reproduction Steps:**

1. Go to any product page and click to write a review

   ![test-review-review](https://hackmd.io/_uploads/BkKl_0yAlg.png)


2. Fill in the review form with your text, then open Burp Suite to intercept the request when you submit
3. In Burp Suite, you can see the PUT request being sent to /rest/products/6/reviews

   ![test-review-put](https://hackmd.io/_uploads/r1JMu0J0gl.png)


4. Look at the request body - it contains JSON data like:

```json
{
  "message": "bananas bad",
  "author": "63731@etu.he2b.be"
}
```

5. Modify the author field to any email address you want (even someone else's email)

6. Forward the request and the server accepts it with 201 Created status

   ![test-review-response](https://hackmd.io/_uploads/ryXmu0yRlg.png)


7. Check the product page - the review now appears under the forged author's name
![test-review-reusi](https://hackmd.io/_uploads/rkWruCkRxl.png)

**Root Cause:**
The server accepts the author information directly from the client without verification. It should check that the currently logged-in user matches the author field in the request, but instead it just trusts whatever author name is sent. This is a broken access control issue where the application doesn't properly enforce authorization rules

---


# 9. Login Bender

**Vulnerability Type:** SQL Injection

**Difficulty:** ⭐⭐⭐

**Description:** Just like with Jim's account, the login form is vulnerable to SQL injection. I used the same technique to log into Bender's account without knowing his password. By injecting SQL code into the email field, I can manipulate the database query to skip the password verification and authenticate as Bender. First, I had to find Bender's email address by looking through product reviews


**Reproduction Steps:**

1. Browse through the product pages to find reviews by Bender
2. I found a review on the "Banana Juice" product where Bender left his email: bender@juice-sh.op

3. Go to the login page at http://localhost:3000/#/login

4. In the Email field, enter the SQL injection payload:

```
bender@juice-sh.op'--
```

5. In the Password field, type anything (like "test" or "12345") - the injection makes it irrelevant

6. Click **Log in**.

![ch5](https://hackmd.io/_uploads/BJ2dd0kAll.png)


Successfully logged in as Bender! The challenge notification confirms the successful exploit.

**Root Cause:** This is the exact same vulnerability as challenge #7 (Login Jim). The application builds SQL queries using string concatenation without sanitizing user input. The single quote ' closes the email string in the query, and the double dash -- comments out everything after it, including the password check. The query becomes: SELECT * FROM Users WHERE email = 'bender@juice-sh.op' with no password verification.

---

# 10. Bjoern’s Favorite Pet

**Vulnerability Type:** Broken Authentication

**Difficulty:** ⭐⭐⭐

**Description:**
The password reset mechanism uses security questions that can be answered using publicly available information. In this case, Bjoern (one of the OWASP Juice Shop developers) has a security question asking about his favorite pet's name. Since Bjoern is a public figure in the OWASP community, information about him can be found online. By searching the internet, I was able to find the answer and reset his password without any other verification.

**Reproduction Steps**

1. Go to the Forgot Password page from the login screen

2. Enter Bjoern's email address:

```
bjoern@owasp.org
```

3. The security question displayed asks for **the name of his favorite pet**.
4. Search online for “Bjoern OWASP favorite pet”; the public answer found is **Zaya**.
5. Enter the answer **Zaya** in the security question field.
6. Set a new password and confirm it.
7. A success message confirms the password reset.

* Challenge card:

![bjorn-pet-1](https://hackmd.io/_uploads/Hyv3_RJCle.png)


* Answer for the question found online:

![bjorn-pet-2](https://hackmd.io/_uploads/H1ea_0y0le.png)


* Challenge solved notification:

![bjorn-pet-solution](https://hackmd.io/_uploads/rJkAdCJAee.png)

## Root Cause

* The application uses weak security questions where answers can be found through public sources. For public figures or people active on social media, personal information like pet names, birthdates, or hometowns are often publicly available. The system also doesn't require any secondary verification (like an email confirmation link) before allowing the password change, and there's no rate limiting to prevent multiple guessing attempts.


---

# 11. Legacy Typosquatting

**Vulnerability Type:** Vulnerable Components

**Difficulty:** ⭐⭐⭐⭐

**Description:**
This challenge involves finding a malicious npm package that was accidentally included in the application's dependencies. Typosquatting is when an attacker creates a fake package with a name very similar to a popular one (like "epilogue-js" instead of "epilogue"), hoping developers will install it by mistake. To find this, I had to access a backup file containing the project's dependency list, which required bypassing file extension restrictions using a null byte injection.

**Reproduction Steps:**

1. The challenge hint mentions looking for a "forgotten developer backup file" (not web domain typos).
![fadf640c-7cad-427f-9607-1b39a380f3a9](https://hackmd.io/_uploads/HydltCyRlg.png)

2.Navigate to the FTP directory at http://localhost:3000/ftp
  ![84277663-4107-495b-ac0a-3ef5172ca854](https://hackmd.io/_uploads/Bys-F0JCxg.png)

3. I found package-lock.json.bak which contains all the project dependencies, but clicking it gives an error: "Only .md and .pdf files are allowed!"

![9c768013-2bc5-40c8-890d-e3d9962639b0](https://hackmd.io/_uploads/S1IztC10le.png)

4. To bypass this restriction, I modified the URL using a null byte injection technique:

```
   http://localhost:3000/ftp/package-lock.json.bak%2500.md

```
 The %2500 tricks the server into thinking the file ends   with .md instead of .bak
 
 ![e61c6fa3-9b6c-4251-9332-3f7f30601917](https://hackmd.io/_uploads/ByvXK01Rex.png)

5. The file downloads successfully!
![8481653f-4e74-48d6-9627-fa25153edef9](https://hackmd.io/_uploads/BJ_Vt0JCgg.png)


6. I opened the file and found a list of all dependencies used in version 6.2.0-SNAPSHOT of Juice Shop.

![f97c3c85-2538-4d72-b97e-b50d3bbf811d](https://hackmd.io/_uploads/HJQrKCyCel.png)

7. I went through the dependencies and checked them on npmjs.com. When I searched for epilogue-js, I found this warning:

"THIS IS NOT THE MODULE YOU ARE LOOKING FOR! Please use https://github.com/dchester/epilogue instead"

![c352136f-827b-4c69-b2b2-1f73e7947614](https://hackmd.io/_uploads/SkmIKAJ0gg.png)

 This confirmed that epilogue-js is a typosquatting    package pretending to be the legitimate epilogue  package!


8. I went to the "Customer Feedback" or "Inform the shop" page in the application

![c0b05fc0-b2c0-4e1d-b7de-5365bc2cae87](https://hackmd.io/_uploads/B17wtRkCxe.png)


9. I reported the malicious dependency by entering epilogue-js

![b12e49b0-fe78-4bb4-a9b3-fa0981d1a491](https://hackmd.io/_uploads/HJgfs0JRxx.png)


**Root Cause:**

A developer accidentally installed the wrong package due to a typo or confusion between similar package names. The malicious epilogue-js package was included instead of the legitimate epilogue package. This is a supply chain attack where attackers exploit human error in package naming. The application also had no automated security scanning to detect suspicious or typosquatted dependencies during the build process.

---

# 12. Forgotten Sales Backup 

**Vulnerability:** Sensitive Data Exposure

**Difficulty:** ⭐⭐⭐⭐

**Description:**

The FTP directory contains backup files (like coupon codes) that shouldn't be publicly accessible. The server tries to protect these files by only allowing downloads of .md and .pdf files. However, I found a way to bypass this restriction using a null byte injection technique. By adding a special encoded character (%2500) to the URL, I can trick the server into thinking I'm requesting an allowed file type while actually accessing the restricted backup file.


**Reproduction Steps** (exact steps taken)

1. Go to the FTP directory: http://localhost:3000/ftp

 
2.Try to click on the file coupons_2013.md.bak - the server blocks it with an error message: "Only .md and .pdf files are allowed!
![forgotten-sales-backup-1](https://hackmd.io/_uploads/HybujCJ0ex.png)


 3. To bypass this, I modified the URL by adding %2500.md at the end:

http://localhost:3000/ftp/coupons_2013.md.bak%2500.md
How this works: The %2500 is a double-encoded null byte (%25 = %, then 00 = null byte). This tricks the server's validation check into seeing the file as ending with .md, while the file system still accesses the actual .bak file.

![forgotten-sales-backup-2](https://hackmd.io/_uploads/H1GKj0y0xe.png)

4 .The file downloads successfully! I opened it in a text editor and found old coupon codes and sales data
![forgotten-sales-backup-3](https://hackmd.io/_uploads/ryhtoAk0ge.png)

## Root Cause
The server validates file extensions by checking the URL string, but it doesn't properly handle encoded characters or null bytes before doing the check. The validation logic sees .md at the end of the URL and allows the download, but the underlying file system interprets the null byte and accesses the .bak file instead. This is a classic null byte injection vulnerability where special characters can confuse string processing and bypass security checks.

---


# 13. Poison Null Byte 

**Vulnerability:** Improper Input Validation

Difficulty: ⭐⭐⭐⭐

**Description:**
This challenge focuses on the null byte injection technique itself as a vulnerability. While Challenge #12 was about finding sensitive backup files, this one demonstrates that the same null byte bypass can be used to access ANY restricted file type on the FTP server. The core problem is that the server doesn't properly clean or normalize the URL before checking the file extension, so encoded control characters like null bytes can trick the validation logic.


**Reproduction Steps (same steps used to solve both challenges)**

1. Navigate to http://localhost:3000/ftp

2.Try to access any blocked file (for example,  coupons_2013.md.bak)

3.Observe the 403 error: "Only .md and .pdf files are allowed!"
4.Modify the URL by appending %2500.md: `http://localhost:3000/ftp/coupons_2013.md.bak%2500.md`.


5.The server returns the file contents, bypassing the extension check

**Result:** The validation is completely bypassed. This technique works on any file with a restricted extension in the FTP directory.

**Evidence:**
The evidence and screenshots are the same as Challenge #12, as both challenges exploit the same underlying vulnerability using identical techniques.
**Root Cause**

The server validates file extensions by doing a simple string check on the URL without first normalizing encoded characters. When it sees %2500.md, it reads the %25 as a percent sign and 00 as part of the filename, making the URL appear to end with .md. However, the file system interprets %00 as a null byte (string terminator), so it stops reading at that point and accesses the .bak file. This is a failure to properly sanitize and canonicalize input before security checks.

# 14. Forged feedback

**Vulnerability:**  Broken Access Control

Difficulty: ⭐⭐⭐

**Description:**
The customer feedback form has a CAPTCHA to prevent automated spam submissions. However, the CAPTCHA implementation is completely broken. When the page loads a CAPTCHA challenge, the server's API response actually includes the correct answer in the JSON data! This means I can use Burp Suite to see the answer before submitting, or even submit feedback with any CAPTCHA ID and answer combination I want. The server trusts whatever CAPTCHA data the client sends without verifying it.

**Reproduction Steps (same steps used to solve both challenges)**

 1. Go to the Customer Feedback page and fill in the form (Author, Comment, Rating)
 2. Solve the displayed CAPTCHA (for example, "3+1*2") 
![Capture d'écran 2025-10-17 154400](https://hackmd.io/_uploads/SJ9TNA10lg.png)

 3. Before submitting, check Burp Suite's HTTP history to see the GET request to /rest/captcha/
 
 
 4. Look at the server's response - it contains the answer!
  
   ![Capture d'écran 2025-10-17 154952](https://hackmd.io/_uploads/SJAEvRkCll.png)

 5. Now I can craft a POST request to /api/Feedbacks/ with any captchaId and answer I want, since I know the server sends the answers
![Capture d'écran 2025-10-17 155811](https://hackmd.io/_uploads/SJZGI010lg.png)

 6. Send the forged request - the server accepts it!
![Capture d'écran 2025-10-17 160106](https://hackmd.io/_uploads/rJZSIAJClx.png)

 Result: I can bypass the CAPTCHA completely and submit unlimited automated feedback.

**Root Cause**
  The server makes two critical mistakes. First, it sends the correct CAPTCHA answer to the client in the API response, which completely defeats the purpose of having a CAPTCHA. Second, it trusts the captchaId and answer values that come from the client without verifying them on the server side. The server should store CAPTCHA answers internally and only check if the user's submitted answer matches, never sending the c

---

## Conclusion
This security assessment of the OWASP Juice Shop application revealed 14 vulnerabilities across different categories. We successfully exploited SQL injection attacks, broken access control, weak authentication mechanisms, sensitive data exposure, and input validation flaws.
The most critical findings included SQL injection enabling account takeover, null byte injection bypassing file restrictions, and a typosquatted npm dependency in the supply chain. Many vulnerabilities resulted from trusting client-side validation and failing to properly sanitize user input.
This hands-on lab provided valuable experience in identifying and exploiting real-world web vulnerabilities in a controlled environment. Understanding how these attacks work is essential for building secure applications as future developers.


![Capture d'écran 2025-10-17 174122](https://hackmd.io/_uploads/rkT6XJg0gl.png)
![Capture d'écran 2025-10-17 174138](https://hackmd.io/_uploads/r1-0Q1xCgg.png)


**Prepared by:** 63731 - Opre Nicoleta & 60991 - Abla Aninia Negue
**Date:** 18/10/2025

*End of report.*
