Closed woctezuma closed 2 years ago
I don't know if this is what you're searching for, but if you didn't you could take a look here: https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions
To answer some of my questions to the best of my current knowledge:
code
as a query parameter is likely incorrect. I believe the code
is an authorization code (despite the pretty URL), and thus the code is only helpful to ask for an access token (if you know the client secret).eg1
, as shown in derrod/legendary/api/egs.py
. These tokens are much longer (length of 1075 base-64 digits instead of 32 hexadecimal digits), and look more secure based on the base64 decoding of some parts of the token: PS256 algorithm, JTI, etc.I don't know if this is what you're searching for, but if you didn't you could take a look here: https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions
Thank you! I know this page, but it is not exhaustive. It is only the visible part of the iceberg database.
For instance, Salt & Sanctuary will be given away later today, but it will appear at your link roughly half an hour before the giveaway. Once its entry appears in the public database (with at least an offer ID and at least an item ID), you will be able to find the game on the official EGS store, at EGData or at ScreamDB. Then you will be able to see the creation date of the database entry, and see that it has been in the invisible part of the database for a while, with an automatic set-up to reveal the entry for today's giveaway, likely planned on December 7 or 8, 2021.
It doesn't have a secret as it would just authorize with the client id.
The thing is I don't even need the client ID to have access to a response for this kind of query, e.g. within Firefox:
https://graphql.epicgames.com/graphql?query={%20Catalog%20{%20searchStore(namespace:%20%22d5241c76f178492ea1540fce45616757%22,%20start:0,%20count:3)%20{%20paging%20{total}%20elements%20{title%20id}%20}%20}%20}
By adding the authorization code as a parameter &code=XXX
, I am not sure whether I get access to more info. It looks like the parameter is omitted, and I get the same response, no matter the different queries which I try.
I think the proper way would be to get an Access Token. However, when I do this with clients with known ID and SECRET, then I get an empty response to my query with an error telling me that I don't have permissions to access this data. I believe that this happens because these clients are not the ones which are supposed to have access to the hidden part of the database.
The fact that I get this error message is interesting though, because that means that the GraphQL API properly understood the Authorization
header with the OAuth Access Token (of type eg1
). When I posted my first message, my Access Tokens were not of type eg1
, so I would not get a proper response from the server, and I would get instead a 504 Gateway Timeout
error.
graphqlWebsite never ever had a secret it would just generate a token sorry if i'm not understanding but there is no "hidden part of the database"
btw &code=XXX won't do anything due to it not being a authorization endpoint, it only works for requests that need it
sorry if i'm not understanding but there is no "hidden part of the database"
There is a hidden part of the database. For instance, let us look at "Moving Out", which was given away yesterday.
---> linked to the item ID: e54d8bf3a451400189159b03231794f7
On Database.EGData.app, one can find 2 entries:
id: "0a8b32256f374cf4998c3ecf44c31db9"
namespace: "f919a1262081444fb28f0fdef68d6b14"
title: "Moving Out"
productSlug: "moving-out"
urlSlug: "moving-out"
creationDate: "2021-08-10T00:00:34.019Z"
lastModifiedDate: "2021-12-28T14:52:08.774Z"
effectiveDate: "2021-12-28T16:00:00.000Z"
viewableDate: "2021-12-28T16:00:00.000Z"
---> linked to the item ID: e54d8bf3a451400189159b03231794f7
We can recognize the item ID which is mentioned on ScreamDB: e54d8bf3a451400189159b03231794f7
.
We can also see that the entry was:
id: "2cbc0241b606499cb4608ef3711a4bb7"
namespace: "d5241c76f178492ea1540fce45616757"
title: "Moving Out"
productSlug: "moving-out"
urlSlug: "28mysterygame"
creationDate: "2021-12-07T23:37:01.520Z"
lastModifiedDate: "2021-12-28T14:57:42.495Z"
effectiveDate: "2099-01-01T00:00:00.000Z"
viewableDate: "2021-12-27T15:25:02.000Z"
---> linked to the item ID: 8341d7c7e4534db7848cc428aa4cbe5a
We can see that the entry is some kind of wrapper for the giveaway:
d5241c76f178492ea1540fce45616757
is used for every giveaway at the end of the year,28mysterygame
instead of being equal to the product slug moving-out
.We can also see that the entry was:
47PADO47
: roughly half an hour before the hint goes officially live on the store, on the day before the giveaway.These entries were not created on the day of the giveaway. They must have been in a private part of a database. I believe this could be one way that the leakers get their info early.
For instance, the leaker called billbil-kun
at dealabs.com posted his leak on December 9, so roughly 2 days after most entries for giveaways (including the second entry mentioned above) were created. One explanation would be that he had access to the entry created on December 7 and whose urlSlug
was set to 28mysterygame
. This way, he would know that the game given away on December 28 would be "Moving Out".
Tomorrow, the Tomb Raider trilogy will be given away. A Chinese leaker at bilibili.com knew it on December 25 or earlier. However, the French leaker at dealabs.com did not know it on December 9, and claims he still does not know it today. My guess is that:
urlSlug
set to an obvious entry like 30mystery
.If the game given away tomorrow fulfills these conditions, then I will be surprised, and then that is more food for thought. We will see tomorrow. Ultimately, I would like to gain the same permissions to read the complete database as one of these leakers.
They.. have some kind of source giving them this information, I highly doubt they got permissions to access the information by themselves.
You are certainly right.
Indeed, I realize that we know the id of tomorrow's game:
https://graphql.epicgames.com/graphql?query={%20Catalog%20{%20searchStore(namespace:%20%22d5241c76f178492ea1540fce45616757%22,%20start:0,%20count:100)%20{%20paging%20{total}%20elements%20{title%20id}%20}%20}%20}
So the ID is ce021049651345c9b0e2aa1f295f437f
, and there is more info at Database.EGData.app:
id: "ce021049651345c9b0e2aa1f295f437f"
namespace: "d5241c76f178492ea1540fce45616757"
title: "Mystery Game"
productSlug: "[]"
urlSlug: "30mysterygame"
creationDate: "2021-12-07T23:39:09.677Z"
lastModifiedDate: "2021-12-19T16:23:56.660Z"
effectiveDate: "2099-01-01T00:00:00.000Z"
viewableDate: "2021-12-29T15:25:00.000Z"
---> linked to the item ID: 8341d7c7e4534db7848cc428aa4cbe5a
Therefore, even if we could have accessed this entry before it appeared publicly earlier today, which we could not, then the fields of interest (title
, productSlug
) would have been obfuscated.
This would explain the lastModifiedDate
, which was set to December 28 for the game given away on December 28. In contrast, the lastModifiedDate
is currently set to December 19 for the game to be given away tomorrow (on December 30). I would expect the entry to be modified on the day of the giveaway to de-obfuscate the title
and productSlug
.
In summary, there are two issues with my approach:
viewableDate
set in the future,title
or productSlug
, which is likely impossible if the info is actually absent.Interestingly:
urlSlug
is cleared indicated as 30mysterygame
.So, if the French leaker could have accessed the database to read the entries for previous giveaways, then he should have been able to read this entry. However, he claimed that he could not read this entry. This points towards another mean of obtaining his pieces of information, most likely through a human being, or third-party companies which work with Epic Games.
As for the Chinese leaker, everything is possible. :)
- Otherwise, is there any other client (with known secret) that I could use to get higher permissions to read data from the API with GraphQL? With the few which I have tried, the POST request times out when I submit the access token in the headers like:
import requests access_token = "MY_TOKEN" r = requests.post( url="https://graphql.epicgames.com/graphql", json={"query": "{ Catalog { searchStore(count:3, start: 1617) { paging {total} elements {title} } } }"}, headers={"Authorization": f'Bearer {access_token}'}, )
If you're trying to authenticate your account to graphql, you need to add a
Cookie
header to the request with theEPIC_BEARER_TOKEN
cookie set to any token that belongs to your account. graphql will internally exchange that token with one belonging to the graphqlWebsiteClient.
If you're trying to authenticate your account to graphql, you need to add a
Cookie
header to the request with theEPIC_BEARER_TOKEN
cookie set to any token that belongs to your account. graphql will internally exchange that token with one belonging to the graphqlWebsiteClient.
Thank you! I will try that!
Edit:
In Auth Clients, the client called
graphqlWebsite
has an ID, but its secret is unknown.1) Does that mean that I can authenticate neither by authorization code, nor using client credentials, because both methods would require a secret?
2) Or can I work directly with the authorization code returned by visiting the following URL?
Indeed, I notice that the redirectURL looks like:
So it is enticing to use that XXX code along my queries, but I am not sure whether I would get higher permissions by doing so.
3) Otherwise, is there any other client (with known secret) that I could use to get higher permissions to read data from the API with GraphQL? With the few which I have tried, the POST request times out when I submit the access token in the headers like:
whereas this works, but without any higher permission:
At the end of the day, my goal would be to figure out the way the Chinese leaker fetched the upcoming free games: These games were not present in the public database, as can be seen on ScreamDB, so I am very surprised.
or the way the French leaker at dealabs.com achieved roughly the same. It has to be a different way, because he has access to less data: he is missing the game to be given away on December 30.
4) Any piece of advice towards this objective?