Repository: getsentry/sentry

Issue:
Potential Vulnerability: Permissive crossdomain.xml
## Important Details

* [x] On-Premise Docker [9.0.0]
* [x] Saas (sentry.io)

## Description

https://cwe.mitre.org/data/definitions/942.html
https://www.rapid7.com/db/vulnerabilities/spider-adobe-flash-permissive-crossdomain-xml
https://www.adobe.com/devnet/flashplayer/articles/cross_domain_policy.html

> Sites that use the common practice of authentication based on cookies to access private or user-specific data should be especially careful when using cross-domain policy files. Currently, the major web browsers include domain-specific cookies on most web requests. Even when cross-domain requests are made in Flash Player, browsers include the cookies of the domain that handle the request. In other words, a SWF file that is hosted on one server can make a request to any other server, and the browser automatically appends the cookies to that request.

In short, a malicious Flash application running in the browser may be able to access Sentry's cookies, hijack the session, and make authenticated requests on behalf of the user.

Are there any mitigating controls around this, or perhaps a reason that this isn't a problem for this platform?

## Steps to Reproduce

Go to https://sentry.io/crossdomain.xml
The following crossdomain.xml file will appear:

```html
<cross-domain-policy>
    <site-control permitted-cross-domain-policies="all"/>
    <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>
```

### Possible Solutions

* Locking down the crossdomain.xml file to only domains that are hosting Flash applications that should be making requests.  This might be a tough problem for the SAAS platform, as the crossdomain.xml file is going to be difficult to scope in any meaningful way since it's a multi-user platform. _Noticed that something like this was mentioned in a previous ticket: #649_

* Change the mechanism in which the Flash client operates.  It sounds as though the default behavior in Flash is to allow the sending of data, but not the loading of data.  Makes it sound as though there's no reason that a Flash client would need to load data from Sentry.

>When an attempt is made to load content into a SWF file at runtime, the request is subject to the Flash Player security model, which is in place to protect users and website owners. As part of this model, Flash Player by default prevents cross-domain loading of data, but allows cross-domain sending of data.



Discussion:
This has come up before.

I need to scrap this top level crossdomain file. There's nothing that can really be exploited here, but it serves as extreme legacy.

Events used to be ingested through simply `/api/store/`, and years ago were moved to `/api/<project>/store/` in which case we now also have specific `/api/<project>/crossdomain.xml` files that are being used.

I'm for just dropping this top level one entirely.

@dcramer ? I've also confirmed, as best I can tell, `raven-as3` explicitly checks the per-project crossdomain file. (https://github.com/skitoo/raven-as3/blob/master/src/scopart/raven/RavenMessageSender.as#L32)

Resolving patch:
diff --git a/src/sentry/web/api.py b/src/sentry/web/api.py
--- a/src/sentry/web/api.py
+++ b/src/sentry/web/api.py
@@ -810,13 +810,6 @@ def robots_txt(request):
     return HttpResponse("User-agent: *\nDisallow: /\n", content_type='text/plain')
 
 
-@cache_control(max_age=3600, public=True)
-def crossdomain_xml_index(request):
-    response = render_to_response('sentry/crossdomain_index.xml')
-    response['Content-Type'] = 'application/xml'
-    return response
-
-
 @cache_control(max_age=60)
 def crossdomain_xml(request, project_id):
     if not project_id.isdigit():
diff --git a/src/sentry/web/urls.py b/src/sentry/web/urls.py
--- a/src/sentry/web/urls.py
+++ b/src/sentry/web/urls.py
@@ -503,8 +503,7 @@ def init_all_applications():
     url(r'favicon\.ico$', lambda r: HttpResponse(status=404)),
 
     # crossdomain.xml
-    url(r'^crossdomain\.xml$', api.crossdomain_xml_index,
-        name='sentry-api-crossdomain-xml-index'),
+    url(r'^crossdomain\.xml$', lambda r: HttpResponse(status=404)),
 
     # plugins
     # XXX(dcramer): preferably we'd be able to use 'integrations' as the URL


Test patch:
diff --git a/tests/sentry/web/api/tests.py b/tests/sentry/web/api/tests.py
--- a/tests/sentry/web/api/tests.py
+++ b/tests/sentry/web/api/tests.py
@@ -728,21 +728,6 @@ def test_output_allows_x_sentry_auth(self):
         )
 
 
-class CrossDomainXmlIndexTest(TestCase):
-    @fixture
-    def path(self):
-        return reverse('sentry-api-crossdomain-xml-index')
-
-    def test_permits_policies(self):
-        resp = self.client.get(self.path)
-        self.assertEquals(resp.status_code, 200)
-        self.assertEquals(resp['Content-Type'], 'application/xml')
-        self.assertTemplateUsed(resp, 'sentry/crossdomain_index.xml')
-        assert '<site-control permitted-cross-domain-policies="all" />' in resp.content.decode(
-            'utf-8'
-        )
-
-
 class RobotsTxtTest(TestCase):
     @fixture
     def path(self):