We recently fixed an information leak in our Sidekick plugin.
Specifically, a user’s API keys could be leaked when sharing a .BNDB
database with someone else. Thankfully, this
issue did not expose user data in any way, but could have been used to gain free access to the service with another
user’s key. Additionally, this issue was discovered during internal testing and we do not have evidence it was
abused externally prior to identifying and correcting the issue.
If we have made this mistake, it’s likely other plugin authors may have as well, so we wanted to write up this post to provide more details about the issue and what we’ve changed in the API itself to mitigate it.
Using the Settings API
The Settings APIs allows for setting various
scopes. If you are making a sensitive setting in a plugin for example
(like we did in Sidekick), and you initialize the setting without ignoring the SettingsResourceScope
, the setting will be
serialized in any created databases as described in the documentation above:
my_settings = Settings()
title = "My UI Plugin"
description = "Enable My UI Plugin table display."
properties = f'{{"title" : "{title}", "description" : "{description}", "type" : "boolean", "default" : true, "ignore" : ["SettingsProjectScope"]}}'
my_settings.register_group("myPlugin", "My Plugin")
my_settings.register_setting("myPlugin.enableTableView", properties)
my_bv = load("/bin/ls", options={'myPlugin.enableTableView' : True})
Settings().get_bool("myPlugin.enableTableView")
The correct usage of the API for sensitive values would be to include SettingsResourceScope
in the ignore
list of the setting:
properties = f'{{"title" : "{title}", "description" : "{description}", "type" : "boolean", "default" : true, "ignore" : ["SettingsProjectScope", "SettingsResourceScope"]}}'
Indeed, this is one of the steps we’ve taken in our recently updated version of Sidekick available in the plugin manager.
Hidden Fields and a Mitigation
While it’s impossible to know for certain whether a setting will contain sensitive information for sure, because we do have a “hidden” property, we have added one new behavior in the latest dev build 4.1.5353.
Specifically, we will automatically reject any
register_settings
call that specifies a hidden property and does not explicitly specify a scope. This prevents the default behavior of
including the setting in the Resource scope, while still maintaining maximum backward compatibility with the current
behavior.
The default of including settings in the settings scope makes sense when you consider that most settings are things like analysis information that will impact the results of the database. Without consistent analysis settings, when someone else opens a database you’ve shared with them, they might get inconsistent results from what you expect them to see.
What About Sidekick?
Beyond just fixing the issue going forward, we’ve taken the following steps to ensure we mitigate the issue as thoroughly as possible:
- Writing up additional documentation on the issue for Sidekick users
- Invalidating all API keys that are used with a vulnerable version
- Prompting users to update their plugin and API key on connection to the server
- Creating a new feature in the Sidekick account management page to cycle an API key (should users ever accidentally leak their key in the future and need to change it without contacting support)
- Emailing all impacted users
Wrap Up
We sincerely apologize to all of our existing users who have been inconvenienced by having to update their API key. Also, while we don’t have a formal bug-bounty program, we do welcome all security reports should external users identify any issues in either Binary Ninja itself, or any of our web properties. Additionally, we are more than willing to compensate reporters of valid issues with licenses, swag, or even financial consideration depending on the situation.