The discovered vulnerability allows an attacker to obtain permissions on a Bugzilla service they would not otherwise receive. This is achieved by tricking the system into believing that the attacker is part of a privileged domain, causing the system to grant domain-specific permissions.

This vulnerability has been tested and found working on Bugzilla.mozilla.org - the Bugzilla for the Mozilla Foundation. Upon successful exploitation of the vulnerability we were granted permissions that would have potentially allowed us to view confidential data (see screen capture below). The vulnerability was assigned CVE-2015-4499, and at the time of dislosure all Bugzilla versions were vulnerable, going back to version 2.0.

If you are using email based permissions in your Bugzilla deployment and have not yet installed a patched version, take it down until patched. Make sure to go over the logs and user-list to identify users that were created using this vulnerability. This vulnerability is extremely easy to exploit and the details have been known for more than a week, you have been or will be attacked!

Screen capture of the permissions screen on bugzilla.mozilla.org

Background

After presenting “The Perl Jam” at the 31st Chaos Communication Congress (31c3) last December, I opened a Pandora’s box full of Perl debates and controversies; but, as I always say, a proper 0-day is a resolution for any debate. This is why now, when I’m working on “The Perl Jam 2”, more vulnerabilities were called for. As Bugzilla is the largest open-source project developed using Perl, I naturally examined it first.

Another reason for choosing Bugzilla is, of course, the recent data leak at the Mozilla deployment of the platform. We at PerimeterX wanted to see whether a platform that’s supposed to be responsible for extremely sensitive information was as secure as it should be.

In this post, I will share our research efforts and their results, as well as share some of the mind-set of White-Hat vulnerability researchers. If you want the technical details you can jump directly to the technical description section at the end of the post.

What makes Bugzilla so important?

Given the nature of a bug tracking systems, the description of a bug in Bugzilla typically includes detailed information about the found issue to help developers reproduce problems more easily and therefore resolve them faster.

While this is a great feature for standard product bugs (e.g. a specific browser version does not properly handle a specific HTML5 function), detailed bug-related information is extremely sensitive when it relates to security vulnerabilities in that product. Users often disclose software vulnerabilities and those working on patching the product interact and share all information related to those vulnerabilities. This database of reported, yet unpatched vulnerabilities could become a very powerful weapon if it fell into the wrong hands.

What did you find in Bugzilla?

In order to provide protected and secure access, Bugzilla has built-in controls in the product that offer different access levels for users and restrict sensitive data access to a small trusted group of those users. A common method used by Bugzilla to assign those access privileges is based on a user’s email address. If a user can provide an email address belonging to a certain organization, that person is assumed to be a member of that organization and therefore a “trusted” user. In the case of Mozilla’s Bugzilla it would be an email under the ‘mozilla.com’ domain. For more information about groups and security settings in Bugzilla see here.

The vulnerability we discovered allows an attacker to create an account using an email in any domain, even if they do not actually have that email account or any access to that domain. With an account within the privileged domain of an application, and the user privileges as defined by that organization’s Bugzilla implementation, attackers could potentially view confidential data and unresolved security vulnerabilities within that application, as well as modify data and change settings, depending on the privileges set for that group.
See the permissions we received on bugzilla.mozilla.org above as an example.

Why is this vulnerability so significant?

The implications of this vulnerability are severe - it could allow an attacker to access undisclosed security vulnerabilities in hundreds of products, in a manner similar to the Mozilla major data leak in August this year, only multiplied by the thousands of publicly available Bugzilla deployments. Imagine the hundreds or thousands of zero-days and other security vulnerabilities that could potentially be exposed!

The information about your security vulnerabilities is extremely important and the software or service that manages and keeps all this data needs to be extremely well protected. In addition, exploiting the vulnerability is extremely easy and does not require any complex tool or methods.

Have you reported it?

Yes. We reported the vulnerability to the Bugzilla security-team/developers and they quickly acknowledged and fixed it.
Disclosure timeline:

Sep 07, 2015 - Date of detection and disclosure to Mozilla

Sep 07, 2015 - Acknowledgment of the vulnerability

Sep 10, 2015 - Patch released by Bugzilla

Sep 17, 2015 - Disclosure published by PerimeterX

What can we do about it?

First of all, we encourage Bugzilla administrators to update their installation ASAP using the patch released under the officialBugzilla website.

At the end of the day, any code is prone to bugs and potential security holes, including the code that, well, manages bugs and potential security holes.

The traditional method of patch-based and signature-based protections is proving to be inadequate in fighting against zero-day attacks. Only a modern approach, that integrates behavioral analysis and based on anomaly detection can identify new attacks as they happen, and protect against a potential exploitation of vulnerable code without setting predefined signatures or rules.

Technical Description

The Bugzilla authentication mechanism relies on email validation. Prior to the actual registration, the user enters their email address and the system sends an activation link to that address. This link contains a token which allows the user to register using that address and set their real name and their account password.

When the user registers with their email address, it is saved in the tokens DB table, along with the token required to activate the address. The email address is stored in a special column named eventdata.

Only when the user validates their email address using the token, the email address is taken from that column and used to create the actual account.
After the account is created, a group-auto-assign regex is triggered and tries to match the email address against specific patterns the admin has set, usually matching the domain name as it is the only part an attacker can’t control.

This makes the email address of the user an extremely important part of the permissions mechanism in the system. It also makes it the weakest link in it. However, for an attacker to actually use a certain email address, they must prove ownership of the address by providing the validation token sent to that address.

Because the registration process described above is so important, let’s dig into it:
First, the entered email address is tested to prevent any forbidden (dangerous) characters and be properly formatted. Only then, the registration token is created for that email. This can be seen in the following code:

### Bugzilla/User.pm::check_and_send_account_creation_confirmation()sub check_and_send_account_creation_confirmation{my($self,$login)=@_;# Check the email address of the user$login=$self->check_login_name($login);if($login!~/$creation_regexp/i){
ThrowUserError('account_creation_restricted');}# Create and send a token for this new account.require Bugzilla::Token;
Bugzilla::Token::issue_new_user_account_token($login);}

Followed by the code to issue_new_user_account_token():

### Bugzilla/Token.pm::issue_new_user_account_token()sub issue_new_user_account_token{my$login_name= shift;# The email address we enteredmy$template= Bugzilla->template;my$vars={};# Create the new token in the DBmy($token,$token_ts)= _create_token(undef,'account',$login_name);# Set the email address, expiration date, and token as the email message variables# (Bugzilla->params->{'emailsuffix'} is empty by default [and in almost all installations])$vars->{'email'}=$login_name. Bugzilla->params->{'emailsuffix'};$vars->{'expiration_ts'}= ctime($token_ts+ MAX_TOKEN_AGE *86400);$vars->{'token'}=$token;# Render the email message using the complied variablesmy$message;$template->process('account/email/request-new.txt.tmpl',$vars,\$message)|| ThrowTemplateError($template->error());# Send the confirmation email
MessageToMTA($message);}

Looking at this code, we can see that the token for the user registration is created in the DB, and then inserted into the email message sent to the registration address.
It is important to note that the system doesn’t validate that the token has been correctly created in the database. Instead, it simply assumes it has been, and sends the user the confirmation email.

This looks like our opening: we need to find a way to corrupt the email address as it is being inserted into the DB. The column in which the address is stored, eventdata, is of type tinytext. This data type represents a text string and, in MySQL, is limited to 255 bytes. For other DBs not supporting this data type, Bugzilla specifies 255 bytes as the exact size of the column using the regular ‘text’ data type.
Let’s test and see what happens when we try to insert more than 255 bytes. Will the DB raise an exception? Will it crash? No – It automatically truncates the data so it fits the column size.

We can take advantage of this behavior, by creating an email address that is longer than 255 bytes, and, upon getting truncated, will look like it belongs to a domain of our choice. That, in return, will cause the system to miss-identify our domain (the only part we cannot entirely control).
We will use an address of exactly 255 bytes, ending with the domain we want the system to recognize. Then, we will append another domain, which we control or own, essentially turning the previous domain into a sub-domain of our own. An example for this can be seen here:
aaa[...]aaa@mozilla.com.attackerdomain.com

Where mozilla.com is the domain we’d like to spoof and .attackerdomain.com is the attacker owned domain.
The resulting email will be sent to an address which we can read, however when the malicious email address is inserted into the DB it will be truncated, forcing the application to assume we identified an email under a different domain.
This essentially performs a privilege-escalation attack, allowing us to obtain privileges we otherwise could not.