Search Unity

MySQL, PHP and Unity security question.

Discussion in 'Multiplayer' started by reviyee, Jun 17, 2019.

  1. reviyee

    reviyee

    Joined:
    Apr 4, 2018
    Posts:
    18
    Hello everyone, I've made a few mistakes developing, as everyone who's just starting, until finally realizing the "most secure" way to connect my Unity game to my MySQL database to upload and download data was using PHP code stored on a secure server to manage the queries. I have made a login script using C# for the client side and PHP for the server side validations

    My question is: Can someone alter the information sent, or received?

    Can someone inject code on my queries from the client side? Not talking about SQL Injection, as I intend to manage those, but, for example, my Unity client queries the server, sends it the username and password and the server checks if the information received matches the information stored on the database, if it is, it should send something back, right?

    Should it send an ok?
    Should it send the user's id to start managing the account?

    Don't mind the fact that I'm still not managing the inputs for SQL injection, is this secure?

    Client side (Unity, C#):
    Code (CSharp):
    1. // CREATE A FORM TO SEND THE USER'S INPUT
    2.         string userName = "user";
    3.         string password = "password";
    4.         WWWForm form = new WWWForm();
    5.         form.AddField("accountUser", userName);
    6.         form.AddField("accountPwd", password);
    7.  
    8.         // CREATE A UNITYWEBREQUEST WITH THE SERVER'S URL AND THE FORM WITH THE USER'S INPUT
    9.         using (UnityWebRequest request = UnityWebRequest.Post(url, form))
    10.         {
    11.             request.downloadHandler = new DownloadHandlerBuffer();
    12.             yield return request.SendWebRequest();
    13.  
    14.             // CHECK IF UNITY CAN CONNECT WITH THE SERVER
    15.             if (!request.isNetworkError || !request.isHttpError)
    16.             {
    17.                 if (request.downloadHandler.text != "ERROR")
    18.                 {
    19.  
    20.                     Debug.Log($"Login successful, your ID is {request.downloadHandler.text}");
    21.                 }
    22.                 else
    23.                 {
    24.                     Debug.Log("Check your credentials.");
    25.                 }
    26.             }
    27.             else
    28.             {
    29.                 Debug.Log(request.error);
    30.             }
    31.         }
    Server side (Server, PHP):

    Code (Boo):
    1. $server = "127.0.0.1";
    2.     $user = "root";
    3.     $password = "password";
    4.     $database = "game";
    5.  
    6.     $user = $_POST["accountUser"];
    7.     $pass = $_POST["accountPwd"];
    8.  
    9.     $conn = mysqli_connect($server,$user,$password,$database);
    10.  
    11.     if(!$conn){
    12.         die("MySQL connection failed: " . mysqli_connect_error());
    13.     }
    14.  
    15.     $query = "select id, password from accounts where name = '".$user."'";
    16.  
    17.     $result = mysqli_query($conn,$query);
    18.  
    19.     if(mysqli_num_rows($result) > 0){
    20.         $row = mysqli_fetch_assoc($result);
    21.         if($pass == $row['password']){
    22.             echo $row['id'];
    23.         }
    24.         else{
    25.             echo "ERROR";
    26.         }
    27.     }
    28.     else{
    29.         echo "ERROR";
    30.     }
    31.  
    32.     mysqli_close($conn);
    Should I be sending something other than the user's account id back?
    Can someone input incorrect information and change the server response from 'ERROR' to a random id and login into said player's account?
     
    Last edited: Jun 17, 2019
    Eug3ne likes this.
  2. Whippets

    Whippets

    Joined:
    Feb 28, 2013
    Posts:
    1,775
    Don't send unencrypted data. Always use https protocol. Ensure there is a php sleep command of 1 second to slow down brute force attacks. Make sure you use mysql_escape_string() and remove any non alphanumeric chars from the username and encrypted password, so there can be no injection. Put all failures into another table along with IP, so you can monitor and block IPs and/or users as required.

    That would be for starters. I'm sure other people will come up with more.
     
  3. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    That does not help. You can just leave the TCP connection lignering and you have bypassed it. Use rate limiting.

    As for password storage, there is a reason why you shouldnt do it yourself. But if you have to, encrypting it is really stupid. You want to hash it using a really slow algo with many iterations, with salts and preferably peppers included. Bcrypt is one very common hashing algo for storing passwords.

    But its always recommended to not do this yourself.


    When I used to deal with passwords I ensured that it took ~800 ms to hash a password on my server machines. Thats reasonable stength given the machines are fast enough.
     
    LukeDawn likes this.
  4. reviyee

    reviyee

    Joined:
    Apr 4, 2018
    Posts:
    18
    I'm using MySQL's hashing procedure. As far as I know I shouldn't do one myself, since I kinda don't know what I'm doing. I guess MySQL's isn't safe enough? Should I get a script to do it on the server-side and run it whenever a new account signs up?