Repository: internetarchive/openlibrary
Issue category: Security Vulnerability

Issue:
XSS issues on books page
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->
XSS issues

### Evidence / Screenshot (if possible)

### Relevant url?

https://openlibrary.org/books/OL27912983M/'_script_alert(_Ultra_Security_)_script
https://twitter.com/BugsBun75181771/status/1228314510563385346

### Details

- **Logged in (Y/N)?** 
- **Browser type/version?** 
- **Operating system?** 
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Hints:
https://openlibrary.org/people/darkscanner this is the corresponding patron who reported the XSS vectors
Should I fix this issue or somebody is already working?
@cYph3r1337 Go for it! Let us know if you have any questions; https://github.com/internetarchive/openlibrary/wiki/Frontend-Guide has a good summary of how templates work on openlibrary. My guess would be that the template is using `$:` (which includes HTML tags) instead of `$` (which escapes them).
Yes please @cYph3r1337, we'd really appreciate your help. I'm happy to point you in the right direction.

Here's our getting started guide:
https://github.com/internetarchive/openlibrary/blob/master/CONTRIBUTING.md

Here's how to setup Open Library dev environment:
https://github.com/internetarchive/openlibrary/blob/master/docker/README.md

Here's a file to start in. The problem is likely (as @cdrini says) where `$:` is being used to render items as html, instead of `$` which renders as text. Which is happening all over the place :)
https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/type/edition/view.html

cc: @mord123321
I am trying to set up dev environment but getting this error

> _ERROR: Service 'web' failed to build: pull access denied for olbase, repository does not exist or may require 'docker login'_

and i am already logged in so probably the repository does not exists
did you managed to fix it?

No, I am still getting the error. Can someone help me set up this locally?
Re-run this command from the README: 

```sh
docker build -t olbase:latest -f docker/Dockerfile.olbase .
```

But _don't forget the dot at the end_! That's gotten a lot of us 😅 

Patch:
diff --git a/openlibrary/plugins/upstream/utils.py b/openlibrary/plugins/upstream/utils.py
index 24ab1af95e9..d9773e1c4c9 100644
--- a/openlibrary/plugins/upstream/utils.py
+++ b/openlibrary/plugins/upstream/utils.py
@@ -761,7 +761,8 @@ def setup():
         'request': Request(),
         'logger': logging.getLogger("openlibrary.template"),
         'sum': sum,
-        'get_donation_include': get_donation_include
+        'get_donation_include': get_donation_include,
+        'websafe': web.websafe,
     })
 
     from openlibrary.core import helpers as h
diff --git a/openlibrary/templates/lists/widget.html b/openlibrary/templates/lists/widget.html
index 4a00ad43734..9c885f1454f 100644
--- a/openlibrary/templates/lists/widget.html
+++ b/openlibrary/templates/lists/widget.html
@@ -370,7 +370,7 @@ <h2>$_('Create a new list')</h2>
     <script type="text/javascript">
     var seed = $:json_encode(seed);
     var seed_type = $:json_encode(seed_type);
-    var title = $:json_encode(title);
+    var title = $:json_encode(websafe(title));
 
     var user_lists = $:json_encode(user_lists);
     var page_lists = $:json_encode(page_lists);
diff --git a/openlibrary/templates/type/edition/view.html b/openlibrary/templates/type/edition/view.html
index 8e5afbc94b1..1ba7ec370ac 100644
--- a/openlibrary/templates/type/edition/view.html
+++ b/openlibrary/templates/type/edition/view.html
@@ -141,7 +141,7 @@
     <div class="navEdition sansserif">
         $ edition_count = work.edition_count if work and work.edition_count else 1
         $ url = work.url() if work else ''
-        $:ungettext('<a href="%(url)s"><strong>1 edition</strong></a> of <strong class="booktitle">%(title)s</strong> found in the catalog.','<a href="%(url)s"><strong>%(count)d editions</strong></a> of <strong class="booktitle">%(title)s</strong> found in the catalog.', edition_count, url=url,count=edition_count, title=truncate(work_title, 60))
+        $:ungettext('<a href="%(url)s"><strong>1 edition</strong></a> of <strong class="booktitle">%(title)s</strong> found in the catalog.','<a href="%(url)s"><strong>%(count)d editions</strong></a> of <strong class="booktitle">%(title)s</strong> found in the catalog.', edition_count, url=url,count=edition_count, title=websafe(truncate(work_title, 60)))
         $if work:
             <span><a href="/books/add?work=$work.key" title="$_('Add another edition of') $book_title">$_("Add another edition")</a>?</span>
     </div>


Test patch: