From cec6cfd9a8c3f064cc4265733dfa0ca6143d6043 Mon Sep 17 00:00:00 2001 From: Anthony Quiros Date: Thu, 6 Oct 2022 18:26:23 +0200 Subject: [PATCH 1/8] Fixing typo in documentation (apache) (#2777) (cherry picked from commit d6bda76332381a2ff8487efb46f386ad7c6e9bda) --- docs/config-webapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config-webapp.rst b/docs/config-webapp.rst index 880738ef1..8daf1adeb 100644 --- a/docs/config-webapp.rst +++ b/docs/config-webapp.rst @@ -323,7 +323,7 @@ Finally, configure the nginx vhost: listen 80; location /static/ { - alias /opt/graphite/webapp/content/; + alias /opt/graphite/webapp/content/ } location / { From 0a77f9c2ff77cd3b889a6139ab1c18c1d80f5a83 Mon Sep 17 00:00:00 2001 From: Jan Szopinski Date: Thu, 6 Oct 2022 16:48:58 +0100 Subject: [PATCH 2/8] Remove old comment (#2781) (cherry picked from commit 00741ac2e09e24b1cb0d5c090b5707d7d387c931) --- webapp/graphite/render/functions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/webapp/graphite/render/functions.py b/webapp/graphite/render/functions.py index 14794aac8..308116e34 100644 --- a/webapp/graphite/render/functions.py +++ b/webapp/graphite/render/functions.py @@ -4002,7 +4002,6 @@ def holtWintersDeviation(gamma,actual,prediction,last_seasonal_dev): def holtWintersAnalysis(series, seasonality='1d'): alpha = gamma = 0.1 beta = 0.0035 - # season is currently one day seasonality_time = parseTimeOffset(seasonality) season_length = (seasonality_time.seconds + (seasonality_time.days * 86400)) // series.step intercept = 0 From f58586a2d826ddf4c0adf04d58d44ccf73c6fb51 Mon Sep 17 00:00:00 2001 From: Michail Safronov Date: Wed, 26 Oct 2022 17:53:57 +0500 Subject: [PATCH 3/8] Sanitize error output for prevent XSS security issues (#2782) * tests for XSS * sanitize error output for prevent XSS issues (cherry picked from commit 9c626006eea36a9fd785e8f811359aebc9774970) --- webapp/graphite/errors.py | 11 +++++++++- webapp/tests/base.py | 12 +++++++++++ webapp/tests/test_xss.py | 42 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 webapp/tests/test_xss.py diff --git a/webapp/graphite/errors.py b/webapp/graphite/errors.py index 289541798..144946309 100644 --- a/webapp/graphite/errors.py +++ b/webapp/graphite/errors.py @@ -94,6 +94,15 @@ def __str__(self): return msg +# Replace special characters "&", "<" and ">" to HTML-safe sequences. +def escape(s): + s = s.replace("&", "&") # Must be done first! + s = s.replace("<", "<") + s = s.replace(">", ">") + + return s + + # decorator which turns InputParameterExceptions into Django's HttpResponseBadRequest def handleInputParameterError(f): def new_f(*args, **kwargs): @@ -102,6 +111,6 @@ def new_f(*args, **kwargs): except InputParameterError as e: msgStr = str(e) log.warning('%s', msgStr) - return HttpResponseBadRequest(msgStr) + return HttpResponseBadRequest(escape(msgStr)) return new_f diff --git a/webapp/tests/base.py b/webapp/tests/base.py index 3039513cc..512e1e6d3 100644 --- a/webapp/tests/base.py +++ b/webapp/tests/base.py @@ -5,3 +5,15 @@ class TestCase(OriginalTestCase): def tearDown(self): stop_pools() + + # Assert that a response is unsanitized (for check XSS issues) + def assertXSS(self, response, status_code=200, msg_prefix=''): + if status_code is not None: + self.assertEqual( + response.status_code, status_code, + msg_prefix + "Couldn't retrieve content: Response code was %d" + " (expected %d)" % (response.status_code, status_code) + ) + + xss = response.content.find(b"<") != -1 or response.content.find(b">") != -1 + self.assertFalse(xss, msg=msg_prefix+str(response.content)) diff --git a/webapp/tests/test_xss.py b/webapp/tests/test_xss.py new file mode 100644 index 000000000..7a3a2c9b7 --- /dev/null +++ b/webapp/tests/test_xss.py @@ -0,0 +1,42 @@ +import logging +import sys + +try: + from django.urls import reverse +except ImportError: # Django < 1.10 + from django.core.urlresolvers import reverse + +from .base import TestCase + +# Silence logging during tests +LOGGER = logging.getLogger() + +# logging.NullHandler is a python 2.7ism +if hasattr(logging, "NullHandler"): + LOGGER.addHandler(logging.NullHandler()) + +if sys.version_info[0] >= 3: + def resp_text(r): + return r.content.decode('utf-8') +else: + def resp_text(r): + return r.content + + +class RenderXSSTest(TestCase): + def test_render_xss(self): + url = reverse('render') + xssStr = '