Browse Source

HUE-7179 [core] Avoid issue with searching documents on assist or global search box

Romain Rigaux 8 năm trước cách đây
mục cha
commit
f5a57dedbb
2 tập tin đã thay đổi với 63 bổ sung8 xóa
  1. 9 8
      desktop/core/src/desktop/api2.py
  2. 54 0
      desktop/core/src/desktop/api2_tests.py

+ 9 - 8
desktop/core/src/desktop/api2.py

@@ -28,6 +28,7 @@ from django.core import management
 
 from django.http import HttpResponse
 from django.shortcuts import redirect
+from django.utils.html import escape
 from django.utils.translation import ugettext as _
 from django.views.decorators.csrf import ensure_csrf_cookie
 from django.views.decorators.http import require_POST
@@ -600,11 +601,11 @@ def search_entities(request):
     entities = _search(user=request.user, search_text=search_text)
     response = {
       'entities': [{
-          'hue_name': e.name,
-          'hue_description': e.description,
+          'hue_name': escape(e.name),
+          'hue_description': escape(e.description),
           'type': 'HUE',
-          'doc_type': e.type,
-          'originalName': e.name,
+          'doc_type': escape(e.type),
+          'originalName': escape(e.name),
           'link': e.get_absolute_url()
         } for e in entities['documents']
       ],
@@ -629,12 +630,12 @@ def search_entities_interactive(request):
     entities = _search(user=request.user, search_text=search_text, limit=limit)
     response = {
       'results': [{
-          'hue_name': e.name,
-          'hue_description': e.description,
+          'hue_name': escape(e.name),
+          'hue_description': escape(e.description),
           'link': e.get_absolute_url(),
-          'doc_type': e.type,
+          'doc_type': escape(e.type),
           'type': 'HUE',
-          'originalName': e.name
+          'originalName': escape(e.name)
         } for e in entities['documents']
       ],
       'count': len(entities['documents']),

+ 54 - 0
desktop/core/src/desktop/api2_tests.py

@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+
+from nose.tools import assert_true, assert_false, assert_equal, assert_not_equal, assert_raises
+
+from django.contrib.auth.models import User
+
+from desktop.lib.django_test_util import make_logged_in_client
+from desktop.lib.test_utils import grant_access
+from desktop.models import Document2
+
+
+class TestApi2():
+
+  def setUp(self):
+    self.client = make_logged_in_client(username="api2_user", groupname="default", recreate=True, is_superuser=False)
+
+    self.user = User.objects.get(username="api2_user")
+
+    grant_access(self.user.username, self.user.username, "desktop")
+
+  def test_search_entities_interactive_xss(self):
+    query = Document2.objects.create(name='<script>alert(5)</script>', description='<script>alert(5)</script>', type='query-hive', owner=self.user)
+
+    try:
+      response = self.client.post('/desktop/api/search/entities_interactive/', data={
+        'sources': json.dumps(['documents']),
+        'query_s': json.dumps('alert')
+      })
+      results = json.loads(response.content)['results']
+      assert_true(results)
+      assert_false('<' in json.dumps(results))
+      assert_false('>' in json.dumps(results))
+      assert_true('&lt;' in json.dumps(results))
+      assert_true('&gt;' in json.dumps(results))
+    finally:
+      query.delete()