Back to blog
caption

How I Won $2,000 in the Notion Bug Bounty Program

TLDR

The bug allowed downloading paid Notion Templates for free, if they were listed on the Notion Template Marketplace (https://www.notion.com/templates).

Disclaimer

The bug was reported to the Notion Team via the HackerOne platform on May 1, 2024. The issue was resolved within 24 hours, and it can no longer be reproduced. 🎉

caption
Proof of Notion's bug bounty contributions from the HackerOne platform.

Although this article is somewhat technical, I hope non-tech readers will still find it interesting. Now, let's delve into the roots of the issue:

The problem

The Notion app is built with React, and the desktop app is essentially a web application wrapped by Electron.js.

A few months ago, while exploring the Notion desktop app's source code, I noticed something intriguing.

When you open Chrome's Developer Tools (either for notion.so or the desktop app) and scroll down to the root HTML file markup, you'll see something like this:

caption
HTML markup fragment from the Notion app, showcasing the application configuration.

Note a window.CONFIG object. As the name suggests, this is a configuration set for the app. It includes several third-party tool API keys, such as:

  • Google Captcha,
  • Facebook Pixel (ads-related software from Meta),
  • Embedly / Iframely (to allow fancy previews of embeded content)

…among other configuration-related entries that Notion utilizes internally, like:

  • app version,
  • yearly price per member for given plan,
  • images proxy base url.

If you look closer you’ll spot a Contentful service configuration.

Contentful is a headless Content Management System (CMS) that enables developers and content creators to manage, deliver, and scale digital content across platforms via APIs.

In a nutshell - it holds all the marketing content used across Notion online presence, including website, apps and so on.

To be even more specific, with the Contentful, we can design content types, like Call to Action Button, Hero Component, Navigation item, Pricing Plan Feature or Image, and then utilize them to compose higher-level content types (like whole Product Pages, Wiki Pages, Developer Pages) tailored specifically for product team needs.

Ok, so what? Nothing special about it, right?

If you take a look again below, you ‘ll see that the Contentful configuration contains a single field, spaceId:

caption
The application configuration, with a Contentful configuration details highlighted

The screenshot was taken recently, but a few months back, it included additional details that clearly shouldn't have been exposed.

Apart from the spaceId, there was also a ACCESS_TOKEN included, which posed a security risk. What could we do with such an API key?

According to the Contentful documentation, you can retrieve all available content types using the REST API with the following query:

https://
cdn.contentful.com
/spaces/{
SPACE_ID
}/environments/master/content_types?access_token={
ACCESS_TOKEN
}

By reviewing the complete list of content types defined by the Notion Team, you can identify various product-related types, including:

  • person (e.g., a Notion template author like yourself)
  • category (the category of your Notion template)

There was also something that grab my attention. A content type, named: template. Notion is known from having a marketplace, full of Notion templates, including paid ones.

This particular content type had quite a few parameters associated to it, including, title, category, price (for paid ones) and… a direct link url to the template, even if the template was paid one.

With this in mind, we can implement an additional Contentful API call to retrieve an exhaustive list of Notion templates available in the Notion Templates Marketplace, specifically those priced at a minimum of 100 USD.

https://
cdn.contentful.com
/spaces/{
SPACE_ID
}/environments/master/entries?access_token={
ACCESS_TOKEN
}&content_type=template&fields.price[gte]=
100

And that’s it! We could access all the paid Notion templates published to the Notion’s marketplace page. Below is a sample of the actual API result, with a legendary Thomas Frank template details:

caption
Contentful API output, with an example paid Notion template details, including direct link to a paid template

Wrapping up

Thanks to the Notion Team for resolving the issue promptly!

No software is entirely free of bugs that can compromise our information; it is an inherent reality.

Here’s a link to the Notion Bug Bounty program (https://www.notion.so/Responsible-Disclosure-Policy-5f18bb6b86804eaf989c006131778b9c?pvs=4) if you would like to utilize your White Hat skills.

PS: If you have to manage your local files in Notion, consider using the Files to Notion app, which provides a secure way to handle files privately inside Notion. You can find more information about security background in here.

Ready to synchronise your local files? Get started for free.
Back to blog
2024 © All rights reserved