title: Unity WebGL PHP database manipulation
body: <p>I am trying to have a WebGL unity game update a MySQL database, basically, I want to make it so when a user logs into the website and beats the unity game they unlock a badge on their profile on the website. </p>
  
  <p>So I wrote a PHP script that updates the database to unlock the badge, then I wrote a C# script for the unity game to send a post request to the PHP script. My issue with this solution is that any external website like postman can just send the same post request and the player doesn't need to actually beat the game to unlock the badge.</p>
  
  <p>Then I thought that maybe I should just put the database credentials in the C# script and edit the database directly from there, but I read online that that was a security concern since players can decompile the game and get the login credentials to the database. </p>
  
  <p>So I did some research and figured that maybe my solution would be CSRF on the PHP page, then maybe I could pass the token to the unity game? I was able to get the PHP to work with the CSRF added to it, but I could not figure out how to then get the unity game to be able to send the post request with the token to unlock the badge on the site.</p>
  
  <p>Would it be a security concern to have the unity game directly edit the database? Any advice on how to solve this problem would be appreciated, below I have posted the relevant files if that is any help, but I think this is more of a conceptual question.</p>
  
  <p>unlockcard2.php</p>
  
  <pre><code>&lt;?php
   require "header.php";
  
   //check if user is logged in
   if(isset($_SESSION['userId'])){
  
      //create key for hash_hmac function
      if(empty($_SESSION['key']))
          $_SESSION['key'] = bin2hex(random_bytes(32));
  
      //create CSRF token
      $csrf = hash_hmac('sha256', 'some random string', $_SESSION['key']);
      if (isset($_POST['submit'])) {
  
          if(hash_equals($csrf, $_POST['csrf'])) {
              echo '&lt;form action="includes/unlockcard.inc.php" method="post"&gt;
              &lt;button type="submit" name="unlock-submit"&gt;unlock card&lt;/button&gt;
              &lt;/form&gt;';
          }
          else{
              echo 'CSRF Token Failed';
          }
      }
   }
   ?&gt;
  
   &lt;html&gt;
   &lt;form method="POST" action ="unlockcard2.php"&gt;
   &lt;input type="hidden" name="csrf" value="&lt;?php echo $csrf ?&gt;" &gt;
   &lt;input type="submit" name="submit" value="SUBMIT"&gt;
   &lt;/form&gt;
   &lt;/html&gt;
  </code></pre>
  
  <p>unlockcard.inc.php</p>
  
  <pre><code>&lt;?php
  
  $servername = "localhost";
  $dBUsername = "root";
  $dBPassword = "";
  $dBName = "loginsystem";
  
  mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); //error reporting
  $conn = mysqli_connect($servername, $dBUsername, $dBPassword, $dBName);
  
  session_start();    
  $sql = "UPDATE users SET card1 =? WHERE idUsers =?";
  $stmt = $conn-&gt;prepare($sql);
  
  $c = '1';
  $i = $_SESSION['userId'];
  
  $stmt-&gt;bind_param("ii", $c, $i); //bind variables
  $stmt-&gt;execute(); //execute prepared statement
  
  
  $stmt-&gt;close();
  $conn-&gt;close();
  </code></pre>
  
  <p>cardunlocker.cs</p>
  
  <pre><code>using System.Collections;
  using System.Collections.Generic;
  using UnityEngine;
  using UnityEngine.Networking;
  
  public class cardUnlocker : MonoBehaviour
  {
      string unlockCardURL = "http://localhost/phpstuff/includes/unlockcard.inc.php";
  
      // Start is called before the first frame update
      void Start()
      {
          StartCoroutine(PostRequest(unlockCardURL));
      }
  
      // Update is called once per frame
      void Update()
      {
  
      }
  
      IEnumerator PostRequest(string url)
      {
          WWWForm form = new WWWForm();
          UnityWebRequest uwr = UnityWebRequest.Post(unlockCardURL, form);
          yield return uwr.SendWebRequest();
  
          if (uwr.isNetworkError)
          {
              Debug.Log("Error while sending: " + uwr.error);
          }
          else
          {
              Debug.Log("Received: " + uwr.downloadHandler.text);
          }
      }
  }
  </code></pre>