👨‍💻
Home
CTFsPlaygroundOSCPBuy Me a Flag 🚩
  • Zeyu's Infosec Blog
  • CTF Writeups
  • Playground
  • OSCP
  • 2023
    • DEF CON 31 CTF && Midnight Sun CTF Finals 2023
    • From XS-Leaks to SS-Leaks Using object
    • Regular Expressions Are Hard
    • ReadiumJS Cloud Reader — Everybody Gets an XSS!
  • 2022
    • HTTP Request Smuggling in the Multiverse of Parsing Flaws
    • Hosting a CTF — SEETF 2022 Organizational and Infrastructure Review
Powered by GitBook
On this page
  • Introduction
  • What is an EPUB? What is a Readium?
  • Popping Alerts
  • Stored XSS
  • Reflected XSS
  • Who Uses Readium?
  • Known Issue?
  • Remediation
  • Disclosure Timeline

Was this helpful?

  1. 2023

ReadiumJS Cloud Reader — Everybody Gets an XSS!

Stumbling upon an XSS paradise.

PreviousRegular Expressions Are HardNextHTTP Request Smuggling in the Multiverse of Parsing Flaws

Last updated 1 year ago

Was this helpful?

Introduction

Late last year, I participated in a bug bounty programme organized by Singapore's where I received the (yay!).

Finding these bugs required a deep dive into the targets and their underlying technologies. This meant that, among other things, I learnt about the existence of the and the world of EPUB cloud readers.

This led me to discover a (surprisingly, somewhat known) XSS vulnerability in the cloud reader that affects many university websites and online libraries.

I have attempted to get in touch with the maintainers to remediate the issue, but have not yet received any response. Going by the conventional 90-day disclosure timeline, I am now sharing details on this vulnerability.

What is an EPUB? What is a Readium?

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=1200, height=1577" />
        <title>La Page Blanche</title>
        <link href="../Style/style.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <div class="page" epub:type="frontmatter titlepage"><img
                src="../Image/PageBlanche_Page_001.jpg" alt="page 1" /></div>
    </body>
</html>

Popping Alerts

First of all, we could see that the iframe does not have the sandbox attribute present. This means that any scripts firing within the iframe would execute on the same origin as its src.

// prefer BlobBuilder as some browser supports Blob constructor but fails using it
if (window.BlobBuilder) {
    var builder = new BlobBuilder();
    builder.append(contentDocumentData);
    blob = builder.getBlob(contentType);
} else {
    blob = new Blob([contentDocumentData], {'type': contentType});
}
documentDataUri = window.URL.createObjectURL(blob);

...

if (isBlobHandled) {
    iframe.setAttribute("src", documentDataUri);

Unfortunately, this means that the iframe's origin will always be that of the parent page.

Stored XSS

Suppose we are able to upload an ebook to an online library using Readium. We might upload a malicious EPUB that runs some evil JavaScript. Any user that opens our ebook would then have their account compromised.

Note that we are using x:script to make the payload work with XHTML parsers.

<!DOCTYPE html>

<html>
    <body>
        Hello world!
    </body>
    <x:script xmlns:x="http://www.w3.org/1999/xhtml">alert(document.domain)</x:script>
</html>

Reflected XSS

The above scenario requires us to have privileges on the target site to upload arbitrary EPUBs and serve them to other users. It turns out, however, that the cloud reader is able to load remote EPUBs as well.

ebookURL = new URI(ebookURL).absoluteTo(thisRootUrl).toString();

However, when ebookURL is an absolute URL, absoluteTo retains the original base URL.

This means that by simply passing our hosted exploit URL to the epub query parameter, we have a reflected XSS! This does not require us to have any permissions on the target site.

Using the example PoC on the Readium demo should pop an alert:

https://readium.firebaseapp.com/?epub=https://zeyu2001.github.io/readium-xss/

Who Uses Readium?

The Readium cloud reader is a rather old project. While more recent and popular cloud readers have been developed, some sites still use the Readium cloud reader, including the IDPF's own website and several university sites.

I have made best effort attempts at identifying these sites (e.g. through Google dorking) and reaching out to the responsible teams to remediate this vulnerability before the release of this post.

Known Issue?

One should note that if a cloud reader aims to support JavaScript, all publications will at least share the same database, which means it is possible for an author to access data that originated in a different publication.

However, it leaves only the following suggestions to mitigate the vulnerability.

Currently, the only options to protect against attacks (see "Security Concerns" section) are:

  • iframe sandboxing;

  • the Content Security Policy;

  • the Feature Policy.

Remediation

Since this is quite an old project, the best remediation might be to move to a more modern cloud reader. If Readium needs to be used, the iframes on the page should have the sandbox attribute set.

Additionally, the page's Content Security Policy can be used to restrict where scripts can be loaded from.

Disclosure Timeline

  • 16 December 2022: Contacted maintainers through GitHub issue

  • 27 January 2022: This blog post is released

  • 12 April 2023: CVE-2023-24720 assigned

The EPUB format is an XML-based ebook format created by the . It is one of the major ebook formats around today. Unlike other proprietary formats such as Amazon's Kindle KF8, the EPUB format is vendor-independent.

The project was started by IDPF, and is one of the cited EPUB readers on the .

To see it in action, we can visit the Readium cloud reader . We can quickly see that the cloud reader renders iframes containing pages of the ebook.

Each page is fetched from the location indicated in data-src and converted into the final rendered HTML. The pages are XHTML files and are called EPUB . For example, page 1 of La Page Blanche contains the following content.

Readium will create a Blob containing the page data and create a new blob: URL for it (). This is the URL that the frame src is set to ().

To create such an EPUB, I copied an example EPUB from the Readium demo and changed the home page. An example PoC can be found .

The cloud reader uses to normalize the epub query parameter, which is a relative URL ().

The sites that have since remediated the vulnerability include the , which no longer contains the cloud reader page.

Interestingly, after doing some digging, I found that this was somewhat of a known issue. documentation explains the issue.

These suggestions are not implemented in the default installation of .

11 October 2022: Contacted maintainers through OSS platform

International Digital Publishing Forum (IDPF)
Readium
W3 website
demo
content documents
source
source
here
medialize/URI.js
source
University of Minnesota's College of Education and Human Development website
This
readium-js-viewer
huntr.dev
Ministry of Defence (MINDEF)
Top Bug Bounty Hunter award
EPUB format
Readium
Page cover image