如何保护请求的帖子-C#和PHP

时间:2019-06-01 23:15:23

标签: c# php unity3d mysqli


(对不起我的英语不好)


我在使用C#,PHP,MYSQLi时遇到问题。 我用

制作了用于登录和注册系统的表格

这是用于用户注册的简单C#函数。

IEnumerator注册器(     字符串名称,     字符串用户名,     字符串电子邮件,     字符串密码 ){

// This is what sends messages to our php script
WWWForm form = new WWWForm();

// The fields are the variables we are sending
form.AddField("name", name);
form.AddField("username", username);
form.AddField("email", email);
form.AddField("password", password);

//string url = "http://www.my-server.com/registrar.php";
string url = "http://localhost/registrar.php";

UnityWebRequest www = UnityWebRequest.Post(url, form);

// Wait for php to send something back to unity
yield return www.SendWebRequest();

if (
    www.isNetworkError || www.isHttpError
) {
    Debug.Log("Error!");
} else {
    Debug.Log("Complete!");
}}

__

// Database variables
$db_host        = "localhost";
$db_user        = "root";
$db_password    = "test";
$db_name        = "test";

// Connect to database.
$db = mysqli_connect($db_host, $db_user, $db_password, $db_name);

// User variables
$name           = $db->real_escape_string($_POST["name"]);
$username       = $db->real_escape_string($_POST["username"]);
$email          = $db->real_escape_string($_POST["email"]);
$password       = $db->real_escape_string($_POST["password"]);
$password_hash  = password_hash($password, PASSWORD_DEFAULT);

// E-mail can not be empty
if(
    !empty($email)
    &&
    !empty($username)
    &&
    !empty($password)
) {
    // Insert user data
    $db->query("INSERT INTO `user`(`username`, `name`, `email`, `password`) VALUES ('$username', '$name', '$email', '$password_hash')");

    // Display...
    echo "Success!";
} else {
    // Display an error
    echo "Error!";
}
?>

一切正常,PHP代码可以正常工作。


但是现在我的问题是,如果黑客获得了注册页面的URL,并为自己制作了一个与我的表单一样的表单,并使用我的注册页面的URL并使用,将会发生什么事情。


这是我的问题,此问题会破坏游戏数据(例如得分,总比赛,时间比赛,其他数据)。


那么我该如何保护和保护(请求帖)我是否已在PHP或C#中做某事。


请帮助我:(

3 个答案:

答案 0 :(得分:0)

通过API密钥添加身份验证!您可以根据需要将其设置为高级或简单:

form.AddField("apikey", apikey);
if ($_POST['apikey'] != "<the_api_key>")
    header('HTTP/1.0 403 Forbidden');

或者类似的东西。

答案 1 :(得分:0)

您不能确保黑客不能发布错误的分数。

您可以尝试在服务器端验证数据(例如“此分数是否可以播放?”)。
或者,您可以在服务器端执行尽可能多的操作(当用户启动游戏并返回令牌(=随机字符串)并测量时间时,您的C#应用​​程序将调用php后端)。

您可以在服务器端强制执行https。

答案 2 :(得分:0)

我一眼就能发现您代码中的一些弱点:

  • 您没有使用HTTPS。客户端和服务器之间的流量可以被拦截并清晰可见。
  • 您没有使用准备好的语句。尽管real_escape_string可能还不错,但请知道:1)它正在更改数据。 2)取决于为数据库连接配置的字符集(您似乎没有设置)。
  • 您不验证用户注册(即,发送包含代码的电子邮件并等待其确认)。这意味着创建大量假账户很容易。

您询问的内容似乎正在向服务器验证您的应用程序。服务器不知道客户端是否有效(它可能是第三方软件来执行请求),因此您想找到一种方法来确保该客户端。

不,没有办法。如果用户可以控制客户端并可以对其进行反向工程,则不会。

Fredrik Schön answer提供了在不同上下文中有用的解决方案。想法是会有一个“密码” apikey来标识您的应用程序,服务器将检查它是否正确。如果我要连接两个应用程序,这很有用...但是,当一个应用程序在用户计算机上时,这根本不安全。

请记住,由于客户端在客户端计算机上运行,​​因此可以对其进行修改或apikey被盗。

您可以向客户端添加数字签名(以在客户端上添加完整性检查,以便可以验证它是否已被修改),但是也可以绕开它。

至此,所有这些都是缓解措施。没有办法。


  

hack游戏数据,例如(得分,总比赛,时间比赛,其他数据)。

永远不要信任客户

应该没有API可以执行这些操作。客户应该没有办法设定分数或任何形式的奖励。取而代之的是,客户端将事件发送到服务器(事件的粒度可以与每个用户输入的事件一样细,无论如何,这都是您在多人客户端服务器游戏中要做的事情),然后服务器决定得分,奖励等。

我再说一遍,没有API。客户端无法发送您玩了多少游戏。

删除此过程是唯一保证可以删除风险的方法。否则,都是缓解措施。


搜索Anti-Cheat at gamedev.stackexchange.com可以给您一些想法。


附录

访问Web表单的游戏客户端和创建访问同一表单的自定义客户端的恶意用户的问题...与访问Web表单和恶意软件的Web浏览器的问题没有本质上的区别创建访问相同表单的自定义客户端的用户。 Web的所有服务器端安全措施都适用于该游戏。并且请注意,将这种安全性基于特定的浏览器并不是一个好主意。

我们想要的是不阻止创建第三方自定义客户端,也不使其变得无礼。相反,要确保它最多可以执行合法客户端可以做的相同事情。

客户端和服务器之间有一个API。如果该API中有某些内容可以让客户端执行客户端不应该执行的操作(例如设置假分数),则必须对服务器及其API进行重新设计,以使其不可能。