Project

General

Profile

Fixed security issue that affected tsp.opensuse.org

We were contacted by a security researcher, to inform us that TSP had a significant security flaw that impacted our production systems. We have since patched the vulnerability and assessed the impact. This is the write up about the process
Added by hellcp 22 days ago

Hi,

We were contacted by Lukas Euler from Positive Security, to inform us that Travel Support Program (TSP), the application we use to reimburse the costs of traveling to events where you can promote or are organized by the project, had a significant security flaw that impacted our and others' production systems. We have since patched the vulnerability, contacted other organizations that also use the software, and have spent some time and wrote a script to parse logs, in order to asses the impact. Over the span of the last 2 years, the flaw has not been abused, outside of a script written by Lukas, which read contents of the production database via brute force.

The what & the how

In essence, the flaw allowed an attacker to see if any arbitrary string is in the database by detecting size of a response to a request with a query containing the string, table by table. Let me illustrate:

Observe the following requests:

"GET /events.json?q[end_date_gteq]=0&q[name_eq]=Open Mainframe Summit&q[requests_comments_body_cont]=a HTTP/1.1" 200 516
"GET /events.json?q[end_date_gteq]=0&q[name_eq]=Open Mainframe Summit&q[requests_comments_body_cont]=aa HTTP/1.1" 200 12
  • /events.json is our public api endpoint containing all the events ever created on the instance
  • end_date_gteq means match to end_date greater or equal to what is after the equals sign
  • name_eq means match to name equal (not case sensitive) to what is after the equals sign
  • requests_comments_body_cont means all the comment bodies that contain what is after the equals sign in all the requests that were created

As you can see, the two requests have wildly different response sizes (last number), the one with 516B returned a body containing the details of the event, while the second one with 12B did not, because no comment body in any request associated with that event matched string 'aa'. Since every reimbursement request has to have an event that is attached to it, you could find contents of every comment in the database if you spent the time going through every character one by one. Of course, the comments are the least of our worry in an application that deals with addresses and bank information. Bank information is attached to a reimbursement, which is mapped directly onto a request, so that's easy enough to find. You could find users through any object created by them, comments, reimbursements, requests, and from there you have an easy time getting to address information.

The why

By default the Ransack library that we use for querying various objects in the frontend allows for querying any association of those objects. We didn't limit the scope of association or columns that could be accessed by it. Since all the objects within the database of TSP are associated in some way or another, that gave just anybody access to the entire database.

Here's some documentation on the subject:
https://activerecord-hackery.github.io/ransack/going-further/associations/
https://activerecord-hackery.github.io/ransack/getting-started/search-matches/

And the way to fix the scopes that ransack can access:
https://activerecord-hackery.github.io/ransack/going-further/other-notes/#authorization-allowlistingdenylisting

How we fixed it:
https://github.com/openSUSE/travel-support-program/commit/d22916275c51500b4004933ff1b0a69bc807b2b7

Github Advisory:
https://github.com/openSUSE/travel-support-program/security/advisories/GHSA-2wwv-c6xh-cf68

Huge thanks to Lukas and the Positive Security team for letting us know about this, we wouldn't have known about this without you, and our data would have been in jeopardy.


Comments

Added by ddemaio 22 days ago

Thank you hellcp and a huge thank you to Lukas for helping with the security.