[tor-commits] [bridgedb/main] Filter user-requested language input

meskio at torproject.org meskio at torproject.org
Thu Jun 24 17:43:55 UTC 2021


commit 0cdee596d91b7576a95f69fff0a6af0fb46b774f
Author: Cecylia Bocovich <cohosh at torproject.org>
Date:   Mon May 31 12:48:59 2021 -0400

    Filter user-requested language input
    
    There was an HTML injection attack made possible by the fact that we
    were including the unsanitized language inputs in the HTML page
    returned to the user. This change filters any user-requested languages
    (either from the Accept-Language header or the "lang" parameter) and
    only includes languages supported by BridgeDB.
---
 bridgedb/distributors/https/server.py | 23 ++++++++++++++++++++---
 bridgedb/translations.py              | 23 ++++++++++++++++++++---
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/bridgedb/distributors/https/server.py b/bridgedb/distributors/https/server.py
index fd3fc74..6310e75 100644
--- a/bridgedb/distributors/https/server.py
+++ b/bridgedb/distributors/https/server.py
@@ -405,12 +405,17 @@ class TranslatedTemplateResource(CustomErrorHandlingResource, CSPResource):
             langs = translations.getLocaleFromHTTPRequest(request)
             rtl = translations.usingRTLLang(langs)
             template = lookup.get_template(self.template)
-            rendered = template.render(strings,
+            if langs:
+                rendered = template.render(strings,
                                        getSortedLangList(),
                                        rtl=rtl,
                                        lang=langs[0],
                                        langOverride=translations.isLangOverridden(request),
                                        showFaq=self.showFaq)
+            else:
+                rendered = template.render(strings,
+                                       getSortedLangList(),
+                                       showFaq=self.showFaq)
         except Exception as err:  # pragma: no cover
             rendered = replaceErrorPage(request, err)
         request.setHeader("Content-Type", "text/html; charset=utf-8")
@@ -539,13 +544,19 @@ class CaptchaProtectedResource(CustomErrorHandlingResource, CSPResource):
             # TODO: this does not work for versions of IE < 8.0
             imgstr = b'data:image/jpeg;base64,%s' % base64.b64encode(image)
             template = lookup.get_template('captcha.html')
-            rendered = template.render(strings,
+            if langs:
+                rendered = template.render(strings,
                                        getSortedLangList(),
                                        rtl=rtl,
                                        lang=langs[0],
                                        langOverride=translations.isLangOverridden(request),
                                        imgstr=imgstr.decode("utf-8"),
                                        challenge_field=challenge)
+            else:
+                rendered = template.render(strings,
+                                       getSortedLangList(),
+                                       imgstr=imgstr.decode("utf-8"),
+                                       challenge_field=challenge)
         except Exception as err:
             rendered = replaceErrorPage(request, err, 'captcha.html')
 
@@ -1084,13 +1095,19 @@ class BridgesResource(CustomErrorHandlingResource, CSPResource):
                 langs = translations.getLocaleFromHTTPRequest(request)
                 rtl = translations.usingRTLLang(langs)
                 template = lookup.get_template('bridges.html')
-                rendered = template.render(strings,
+                if langs:
+                    rendered = template.render(strings,
                                            getSortedLangList(),
                                            rtl=rtl,
                                            lang=langs[0],
                                            langOverride=translations.isLangOverridden(request),
                                            answer=bridgeLines,
                                            qrcode=qrcode)
+                else:
+                    rendered = template.render(strings,
+                                           getSortedLangList(),
+                                           answer=bridgeLines,
+                                           qrcode=qrcode)
             except Exception as err:
                 rendered = replaceErrorPage(request, err)
 
diff --git a/bridgedb/translations.py b/bridgedb/translations.py
index b6a9ef3..7569ee7 100644
--- a/bridgedb/translations.py
+++ b/bridgedb/translations.py
@@ -94,6 +94,7 @@ def getLocaleFromHTTPRequest(request):
 
     langs = list(map(lambda l: l if isinstance(l, str) else l.decode('utf-8'), langs))
 
+    langs = filterRequestedLangs(langs)
     installTranslations(langs)
     return langs
 
@@ -110,6 +111,22 @@ def getLocaleFromPlusAddr(address):
 
     return replyLocale
 
+def filterRequestedLangs(langs):
+    """
+    Filters user-requested languages to only include those supported
+    by BridgeDB.
+    :type list
+    :param langs: A list of user-requested languages for translation
+    :rtype: list
+    :returns: All requested languages that are supported by BridgeDB
+    """
+    supported_langs = getSupportedLangs()
+    valid_langs = list()
+    for l in langs:
+        if l in supported_langs:
+            valid_langs.append(l)
+    return valid_langs
+
 def installTranslations(langs):
     """Create a ``gettext.translation`` chain for all **langs**.
 
@@ -125,11 +142,11 @@ def installTranslations(langs):
     """
     try:
         language = gettext.translation("bridgedb", localedir=TRANSLATIONS_DIR,
-                                       languages=langs, fallback=True)
-        for lang in langs:
+                                       languages=[langs[0]], fallback=True)
+        for lang in langs[1:]:
             language.add_fallback(
                 gettext.translation("bridgedb", localedir=TRANSLATIONS_DIR,
-                                    languages=langs, fallback=True))
+                                    languages=[lang], fallback=True))
     except IOError as error:
         logging.error(str(error))
 





More information about the tor-commits mailing list