Broken Authentication

Lecture Notes

This lecture will present an overview over issues with authentication methods, especially session handling in Web applications.

Download here

Practical tasks

The objective of this lab is to explore the Broken Authentication exercises in bWAPP and the OWASP Mutillidae II application. It is required the use of the OWASP ZAP or Burp Suite. If you do not have a license for the Burp software, OWASP ZAP with most of the addons available in the marketplace will be a better option.

This guide will provide you with hints, but not the answers. While doing the exercises, do a write up of what you find, the reason why it happens and the impact of it.

Mutillidae II

The application is vulnerable and the vulnerabilities are present almost over the application. The left menu allows getting some information or hints which may be useful. The objective of this lab is to cover the OWASP 2017 - A2 Broken authentication exercises. They cover basic errors present on standard applications, either in this form or other form, but always sharing similar principles.

The exercises are split into Authentication Bypass, Privilege Escalation and User Enumeration.

User Enumeration

These exercises are important as they are related to a behavior that is very common on the internet. Differentiated feedback based on the existence of a user. If the user exists the login form provides a message stating that the password is incorrect. If the user doesn’t exist the login form provides a message stating that the user is not found. With tools, this allows for rapid enumeration of all users.

The vulnerability can be explored with three methods: the login form, a SOAP interface and a REST interface.

In all situation, the method will involve using Burp Intruder or OWASP ZAP Fuzzer to repeat payloads with different users. In alternative, you can also devise a simple script to do this. It should not take much effort if you use the requests package in python.

In the description of CWE-204, you can find the typical code that results in this issue:

my $username=param('username');
my $password=param('password');

if (IsValidUsername($username) == 1) {
	if (IsValidPassword($username, $password) == 1) {
		print "Login Successful";
	} else {
		print "Login Failed - incorrect password";
} else {
	print "Login Failed - unknown username";

In this case, the system is providing information to an attacker, allowing user enumeration. The correct implementation should provide a binary answer (Success or Fail), without further detail.

The past exercises focus on getting authenticated while subverting the standard interface. The first suggests using a brute force. Both OWASP ZAP and Burp provide the means to intercept and repeat request with small variations (Intruder in Burp, Fuzzing in OWASP ZAP). The objective is to use a single user and then attempt multiple passwords.

The next exercise focus on the cookie itself, and for an attacker to obtain the cookie. Follow the hints there, in particular the XSS as it may allow stealing someones cookie. Most importantly, observe the cookies set in your browser (Dev Tools -> Storage). You can directly manipulate the values and see the impact into the webpage. Developers frequently “trust” cookies because they are set in the server side, but they ignore that clients can freely manipulate them. Access multiple pages, analyse the cookies, login and logout and devise an exploration.

SQL Injection will not be covered here. However, you can apply the techniques you used in the previous classes in order to obtain access to the system.

CWE-287 provides a good overview of the issues found here and their remediation. The code sample from the CWE exposes how cookies can be abused.

my $q = new CGI;

if ($q->cookie('loggedin') ne "true") {
	if (! AuthenticateUser($q->param('username'), $q->param('password'))) {
		ExitError("Error: you need to log in first");
	} else {
		# Set loggedin and user cookies.
			-name => 'loggedin',
			-value => 'true'

			-name => 'user',
			-value => $q->param('username')

if ($q->cookie('user') eq "Administrator") {

In this case, an attacker can directly edit the cookie and then bypass authentication or even impersonate another user. The obvious fix is to use proper session handling mechanisms, either by avoid sending session data in cookies, or by encrypting/signing cookies with private data.

Authentication Bypass due to Wrong Ciphermodes

These exercises focus on getting one account (Use the Register option) which can then be escalated to a user with higher privileges. The user admin is present in this system and will be the target to explore.

When exploring this vulnerability through cookies, once again, fuzz the values and see what happens.

When exploring this vulnerability through CBC bit flip consider the operation of the CBC mode in block ciphers. You can notice that the IV is simply XORed to the cryptogram after decryption. Because the IV is public, it allows an attacker to predictively modify the final text. In this case, the permissions are decrypted using the IV in the argument. Do small variations and see what happens.

We created a goat application that has a vulnerable autentication check and attackers can bypass the controls in use.


Sometimes we see developers signing their cookies with a shared secret. However, instead of using secure methods, such as JWT, the use crafted signing processes. Consider the following code Python:

def get_cookie(app_key, username):
    val = f'username={username}'
    cookie = b64e(val.encode()) + b"." + calculate_signature(app_key, val.encode())

    return cookie

def calculate_signature(app_key, data):
    hash = sha256()

    hash.update(app_key + data)
    h = hash.digest()

    return b64e(h)

In this snippet, the signature is SHA256(secretkey | cookie), and the cookie format is base64(username=string).base64(signature). An attacker cannot change the cookie, because he cannot access the secretkey. Therefore he cannot compute the new signature.

However, because the SHA-1 and SHA-2 family of digests use the Merkle–Damgård construction, they are vulnerable to an attack called Length Extension Attack. This attack allows an actor to change the data and calculate a new valid signature, without knowing the server secret key.

Asymmetric cryptography to sign keys is not vulnerable, as well as SHA-3 and should be used. More importantly, JWT and other well adopted technologies should preferred as they had more thoughtfully tested.

Check the code on this repository

Then head to the Photo Gallery application in the internal environment and get admin rights. For this purpose, analyse the cookie returned and add new data in order to force the admin user.


Select Broken Auth. — Insecure Login Forms. This bug could be silly but to create cognizance, one must sift through the page source to find sensitive information. So, when you view the page source (right click on page and select view page source), you should see the user credentials stored in the HTML. This allows hackers to gain authentication with ease, anyway this won’t be the case in the real world, you may see this rarely, but sometimes it happens. It is more frequent to find keys to APIs and credentials to APIs. But some information may also be in the comments. ZAP will show this in the HUD.

Now we will see another code level flaw, select Session Mgmt. — Administrative Portals’ and set security level to ‘low‘. If you notice the URL /bWAPP/smgmt_admin_portal.php?admin=0__ there’s a string appended after the ‘?’with a value ‘0’, which means the session ID was passed in the query string where anyone could see and manipulate the values. See what happens when it is modified.

Now look at the bug Session Mgmt. — Session ID in URL

Now, set the security level to ‘medium‘ in Administrative Portals page and refresh the page (CTRL+R). If you notice the URL, there’s no query string with ‘admin’. So, was that bug fixed? No, as a security analyst you should always look for numerous ways to find the flaw, in simple words just think like a developer, how did he fix that. Especially how did he fix that without much effort? HINT: Check the cookies.

The other most common vulnerability is incorrect logout management. Select the bug Broken Auth. — Logout Management and click on ‘here’ link displayed in the page

Once you click on ‘Yes’ you will be redirected to Login page. But session is still alive. Just click on Browser back button, you will be redirected to /bWAPP/ba_logout.php page. Hence an attacker can easily perform session fixation attack. Can you find how?

Correlate what you found with the source code available at the SonarCloud analysis.

Juice Shop

This guide is provided by OWASP as part of their official documentation and is replicated here for convenience and longer term archival.

Reset the password of Bjoern’s OWASP account via the Forgot Password mechanism

This challenge is not about any technical vulnerability. Instead it is about finding out the answer to user Bjoern’s chosen security question and use it to reset the password of his OWASP account.

Many website registrations use security questions for both password retrieval/reset and sign-in verification. Some also ask the same security questions when users call on the phone. Security questions are one method to verify the user and stop unauthorized access. But there are problems with security questions. Websites may use poor security questions that may have negative results:

The user can’t accurately remember the answer or the answer changed, The question doesn’t work for the user, The question is not safe and could be discovered or guessed by others. It is essential that we use good questions. Good security questions meet five criteria. The answer to a good security question is:

  • Safe: cannot be guessed or researched
  • Stable: does not change over time
  • Memorable: can remember
  • Simple: is precise, easy, consistent
  • Many: has many possible answers

It is difficult to find questions that meet all five criteria which means that some questions are good, some fair, and most are poor. In reality, there are few if any GOOD security questions. People share so much personal information on social media, blogs, and websites, that it is hard to find questions that meet the criteria above. In addition, many questions are not applicable to some people; for example, what is your oldest child’s nickname – but you don’t have a child.

Hints to the answer to Bjoern’s question can be found by looking him up on the Internet. More precisely, Bjoern might have accidentally (😜) doxxed himself by mentioning his security answer on at least one occasion where a camera was running. Brute forcing the answer might be very well possible with a sufficiently extensive list of common pet names. Doxing (from dox, abbreviation of documents) or doxxing is the Internet-based practice of researching and broadcasting private or identifiable information (especially personally identifiable information) about an individual or organization.

The methods employed to acquire this information include searching publicly available databases and social media websites (like Facebook), hacking, and social engineering. It is closely related to Internet vigilantism and hacktivism.

Doxing may be carried out for various reasons, including to aid law enforcement, business analysis, risk analytics, extortion, coercion, inflicting harm, harassment, online shaming, and vigilante justice.

Change Bender’s password into slurmCl4ssic without using SQL Injection or Forgot Password

This challenge can only be solved by changing the password of user Bender into slurmCl4ssic. Using any sort of SQL Injection will not solve the challenge, even if the password is successfully changed in the process. Beating Bender’s security question to change his password also does not suffice to solve this challenge!

In previous releases of OWASP Juice Shop this challenge was wrongly accused of being based on Cross-Site Request Forgery. It might also have been put into the Improper Input Validation category. Bender’s current password is so strong that brute force, rainbow table or guessing attacks will probably not work. A rainbow table is a precomputed table for reversing cryptographic hash functions, usually for cracking password hashes. Tables are usually used in recovering a plaintext password up to a certain length consisting of a limited set of characters. It is a practical example of a space/time trade-off, using less computer processing time and more storage than a brute-force attack which calculates a hash on every attempt, but more processing time and less storage than a simple lookup table with one entry per hash. Use of a key derivation function that employs a salt makes this attack infeasible

Log in with Chris’ erased user account

This challenge is about loggin in with the account of a user who previously insisted on his “right to be forgotten” in accordance with Art. 17 GDPR.

Trying out the Request Data Erasure functionality might be interesting, but cannot help you solve this challenge in real time. If you have solved the challenge Retrieve a list of all user credentials via SQL Injection you might have already retrieved some information about how the Juice Shop “deletes” users upon their request. What the Juice Shop does here is totally incompliant with GDPR. Luckily a 4% fine on a gross income of 0$ is still 0$. Log in with Bjoern’s Gmail account The author of the OWASP Juice Shop (and of this book) was bold enough to link his Google account to the application. His account even ended up in the initial user records that are shipped with the Juice Shop for your hacking pleasure!

If you do not see the Log in with Google button, do not despair! The hostname your Juice Shop is running on is simply not configured in the OAuth integration with Google. The OAuth-related challenges are still solvable! It might just take a little bit more detective work to find out how an OAuth login is handled.

You can always use the official demo instance at to play with Google login and learn how it works there, then apply what you learned on your local instance.

  • There are essentially two ways to light up this challenge in green on the score board:
    • In case you, dear reader, happen to be Bjoern Kimminich, just log in with your Google account to automatically solve this challenge! Congratulations!
    • Everybody else might want to take detailed look into how the OAuth login with Google is implemented.
  • It could bring you some insight to register with your own Google account and analyze closely what happens behind the scenes.
  • The security flaw behind this challenge is 100% Juice Shop’s fault and 0% Google’s.

The unremarkable side note without hacking his Google account in the challenge description is not a joke. Please do not try to break into Bjoern’s (or anyone else’s) Google account. This would be a criminal act.

Log in with the administrator’s user credentials without previously changing them or applying SQL Injection You might have already solved this challenge along with Log in with the administrator’s user account if you chose not to use SQL Injection. This challenge can only be solved if you use the original password of the administrator. If you changed the password previously, do not despair: The original password will always be accepted to make sure you can solve this challenge.

  • Guessing might work just fine.
  • If you harvested the admin’s password hash, you can try to attack that.
  • In case you use some hacker tool, you can also go for a brute force attack using a generic password list

Reset Bender’s password via the Forgot Password mechanism

This challenge is about finding the answer to user Bender’s security question. It is probably slightly harder to find out than Jim’s answer.

  • If you have no idea who Bender is, please put down this book right now and watch the first episodes of Futurama before you come back.
  • Unexpectedly, Bender also chose to answer his chosen question truthfully.
  • Hints to the answer to Bender’s question can be found in publicly available information on the Internet.
  • If a seemingly correct answer is not accepted, you might just need to try some alternative spelling.
  • Brute forcing the answer should be next to impossible.

Reset the password of Bjoern’s internal account via the Forgot Password mechanism

This challenge is about finding the answer to the security question of Bjoern’s internal user account bjoern@juice-sh.op.

  • Other than with his OWASP account, Bjoern was a bit less careless with his choice of security and answer to his internal account.
  • Bjoern chose to answer his chosen question truthfully but tried to make it harder for attackers by applying sort of a historical twist.
  • Again, hints to the answer to Bjoern’s question can be found by looking him up on the Internet.
  • Brute forcing the answer should be next to impossible.

Reset Jim’s password via the Forgot Password mechanism

This challenge is about finding the answer to user Jim’s security question.

  • The hardest part of this challenge is actually to find out who Jim actually is
  • Jim picked one of the worst security questions and chose to answer it truthfully
  • As Jim is a celebrity, the answer to his question is quite easy to find in publicly available information on the internet
  • Even brute forcing the answer should be possible with the right kind of word list

Solve the 2FA challenge for user “wurstbrot”

Multi-factor authentication (MFA) is an authentication method in which a computer user is granted access only after successfully presenting two or more pieces of evidence (or factors) to an authentication mechanism: knowledge (something the user and only the user knows), possession (something the user and only the user has), and inherence (something the user and only the user is).

Two-factor authentication (also known as 2FA) is a type, or subset, of multi-factor authentication. It is a method of confirming users’ claimed identities by using a combination of two different factors: 1) something they know, 2) something they have, or 3) something they are.

A good example of two-factor authentication is the withdrawing of money from an ATM; only the correct combination of a bank card (something the user possesses) and a PIN (something the user knows) allows the transaction to be carried out.

Two other examples are to supplement a user-controlled password with a one-time password (OTP) or code generated or received by an authenticator (e.g. a security token or smartphone) that only the user possesses.

In the Juice Shop one customer was very security-aware and set up 2FA for his account. He goes by the hilarious username wurstbrot.

  • As always, first learn how the feature under attack is used and behaves under normal conditions.
  • Make sure you understand how 2FA with TOTP (time-based one-time password) works and which part of it is the critically sensitive one.
  • Solving the challenge Retrieve a list of all user credentials via SQL Injection before tackling this one will definitely help. But it will not carry you all the way.

Username Enumeration Response varies wether the username exists or not “Account does not exist” vs “Password incorrect”

Do request, fuzz

Username Enumeration - SOAP Service

Do request, edit, fuzz, load wordlist

POST /webservices/soap/ws-user-account.php HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml;charset=UTF-8 Content-Length: 458 Host: localhost Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soapenv:Envelope xmlns:xsi=“" xmlns:xsd=“" xmlns:soapenv=“" xmlns:urn=“urn:ws-user-account”> soapenv:Header/ soapenv:Body <urn:getUser soapenv:encodingStyle=“"> Jeremy </urn:getUser> </soapenv:Body> </soapenv:Envelope>

Username Enumeration - REST Service

GET HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8 Accept-Language: en-US,en;q=0.5 Connection: keep-alive Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5; showhints=1 Upgrade-Insecure-Requests: 1 Host:

_Authentication Bypass


Use XSS attack to steal cookie

pc local nc -v 8080

Privilege Escalation

Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5; showhints=1

after login with user test Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5; showhints=1; username=test; uid=24 Modificar uid para outro valor inteiro: p.ex 1 = admin Dev tools, Storage, modify uid

CBC bit flip modify the value of the IV argument, one bit at a time Check CBC mode result=6bc24fc1aa650b24b4114e93a98f1