1

In the online game "Cookie Clicker", there is an achievement called "Cheated Cookies Taste Awful". The way to earn this badge is to use DevTools Console to spawn in as many cookies as you want. I am trying to replicate this behavior.

However, the only way that Cookie Clicker could award someone this badge is to listen to the actual console and detect when a command gets sent. Furthermore, it is able to recognize when you are spawning in cookies specifically to award you the badge. How did they manage to pull this off?

coderman1234
  • 210
  • 3
  • 12
  • Does it necessarily have to be listening to what you type in the console? Could it not maybe just detect usual changes in cookie count? – ripytide Feb 23 '21 at 01:12
  • @Ripytide True, but in Cookie Clicker, there are a lot of ways to get cookies. I don't think it would be reasonable to have to use a key every time. Also, if by "unusual" you mean a lot at once, at a very high level, you could make BILLIONS of cookies per click – coderman1234 Feb 23 '21 at 01:12

1 Answers1

2

The general idea would be to deliberately expose a global function that, when called, spawns a cookie in addition to carrying out anti-cheat logic.

For example, you could have something like:

(() => {
  const makeCookie = () => {
    // This function creates the cookie for real
  };

  // This function is the honeypot
  window.makeCookie = () => {
    alertUserThatTheyHaveCheated();
    makeCookie();
  };
})();

Or you could keep track of the timestamps when the function is called:

let timeCookieWasLastSpawned = 0;
const makeCookie = () => {
  const now = Date.now();
  if (now - timeCookieWasLastSpawned < 180_000) {
    // makeCookie cannot be called from elsewhere in the code
    // more than once in a 3-minute period
    // so the user must have typed in makeCookie() into the console
    alertUserThatTheyHaveCheated();
  }
  timeCookieWasLastSpawned = now;
  // proceed with logic that makes the cookie
};

Users can usually only call functions via the console if the page script has been designed to permit such a thing to happen. (This sort of global pollution is generally considered bad practice, but it's not uncommon.) So, the script-writer can specifically design things such that the functions that are exposed can easily detect that they're being called via the console, rather than from other parts of the page's original code.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I'm sort of confused what is happening on the first example. @CertainPerformance. Are you using the function to spawn cookies? – coderman1234 Feb 23 '21 at 01:17
  • With the first example, calling `window.makeCookie` from the console will result in `alertUserThatTheyHaveCheated();` being called. It'll also happen to call the *private* `makeCookie` function that actually spawns/makes the cookie. – CertainPerformance Feb 23 '21 at 01:19
  • ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh... but how would you prevent the user from just executing the private function? – coderman1234 Feb 23 '21 at 01:19
  • Because it's very difficult to gain access to the inside of a closure. It's [not completely impossible](https://stackoverflow.com/a/59424277), but it's beyond the reach of most casual users. – CertainPerformance Feb 23 '21 at 01:20
  • Actually, is fairly simple to hijack the closure with a debugger. Just use a breakpoint and set the function to a property in the global object. – MinusFour Feb 23 '21 at 01:45