Search code examples
javascripthtmlcanvashidesecure-coding

Hiding content to prevent cheating in JavaScript-made game


I know it's impossible to completely prevent users from cheating and/or cracking a web application, but this hole I found is so easy to find that it really should be plugged up.

https://mcthompsonatl.github.io/

I didn't actually code any of this. I was given this very basic "find all 6 objects" (in this case, keys) guessing game that a former employee, who wasn't a programmer by trade, wrote for a promotion for one of our clients. The logic is sound, and it needs some formatting work, but while testing it out in developer mode, it took me very little time to find that the game can easily be won just by inspecting each <div> of the card class. Because this is being used for a promotional contest, I've been trying to figure out a way to either hide or change the game-breaking code to where inspecting any of the cards in developer mode doesn't reveal any hints.

The one solution I could find was to change the card elements to multiple HTML5 Canvas elements. The two problems with that is 1. I have zero experience working with Canvas and 2. Even if I did, it seems to be an extremely long and painful task, and I'm not sure if I'll be allowed the time I'd need to learn just enough to remedy the problem. Is this something that can be hidden with PHP? I'm a bit stumped here finding a sensible solution. Any help is appreciated.


Solution

  • Too long for a comment.

    Based on what I understood from the game. You have 36 boxes, you need to click on random boxes. If you click on the X number of the correct boxes, you win.

    I was able to cheat by inspecting the HTML and searching for the image that indicates the winning key. The image name was images/keytowin/frontImage.png

    A solution may be to not pre-assign the image that indicates "correct" choice to the HTML div. Rather, assign the image only after it's being clicked. This will make it harder to find since the HTML alone won't give it away.

    The idea y here is Random. Using Javascript, generate 3 random number between 1 and 36. These three random numbers indicate the winning boxes. If the user clicks on a box, and it has the same number (I noticed the div are numbered data-id="1" ) then use JS to add an image the inner div on the fly.

    The three random numbers, however, will be determined when the game starts. Therefore, obscuring the variables is important.

    I have provided a sample code to demonstrate the concept.

    var luckyNumbers = getUniqueNumbers();
    var winImg = "<img  src='https://mcthompsonatl.github.io/images/keytowin/frontImage.png' alt='X LOGO'>";
    var loseImg = "<img  src='https://mcthompsonatl.github.io/images/keytowin/TryAgain.png' alt='X LOGO'>";
    
    console.log(luckyNumbers);
    
    $(".card").on("click", function() {
    
      if (!$(this).hasClass("clicked")) {
        $(this).addClass("clicked");
    
        selected = Number($(this).attr("data-id"));
        if (luckyNumbers.indexOf(selected) > -1) {
          //code to put a key image     
          $(this).find(".back").append(winImg);
        } else {
          console.log("wrong: " + selected);
          //code to put not-winning image     
          $(this).find(".back").append(loseImg);
        }
    
      }
    
    });
    
    
    
    function getUniqueNumbers() {
      var arr = []
      while (arr.length < 3) {
        var someRand = Math.ceil(Math.random() * 36)
        if (arr.indexOf(someRand) > -1) continue;
        arr[arr.length] = someRand;
      }
      return arr;
    }
    img {
      width: 50px;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta content="width=device-width" name="viewport">
      <title>JS Bin</title>
    </head>
    
    <body>
      <div class="game">
    
    
        <div class="card" data-id="5">
          <div class="inside">
            <div class="front">
              <img src="image/someimage.jpg" alt="keytowin">
            </div>
            <div class="back">
            </div>
          </div>
        </div>
    
        <div class="card" data-id="6">
          <div class="inside">
            <div class="front">
              <img src="image/someimage.jpg" alt="keytowin">
            </div>
            <div class="back">
            </div>
          </div>
        </div>
    
    
        <div class="card" data-id="7">
          <div class="inside">
            <div class="front">
              <img src="image/someimage.jpg" alt="keytowin">
            </div>
            <div class="back">
            </div>
          </div>
        </div>
    
    
      </div>
      <script src="https://code.jquery.com/jquery-2.2.4.js">
      </script>
    </body>
    
    </html>