【问题标题】:How to secure requesting post - C# and PHP如何保护请求帖子 - C# 和 PHP
【发布时间】:2019-06-01 23:15:22
【问题描述】:

我对 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# 中做过一些事情。

【问题讨论】:

    标签: c# php unity3d


    【解决方案1】:

    一目了然,我可以发现您的代码中的一些弱点:

    • 您没有使用 HTTPS。客户端和服务器之间的流量可以被拦截并清楚地看到。
    • 您没有使用准备好的语句。虽然real_escape_string 可能没问题,但要知道:1)它正在改变数据。 2) 这取决于为数据库连接配置的字符集(您似乎没有设置)。
    • 您没有验证用户注册(即发送带有代码的电子邮件并等待其确认)。这意味着创建大量虚假帐户很容易。

    您要求的似乎是向服务器验证您的应用程序。服务器不知道客户端是否有效(可能是第三方软件在做请求),所以你想找到一种方法来确保。

    不,没有办法做到这一点。如果用户控制客户端并且可以对其进行逆向工程,则不会。

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

    请记住,您的客户端可能会被修改,或者 apikey 被盗,因为它正在客户端计算机上运行。

    您可以向客户端添加数字签名(在您的客户端上添加完整性检查,以便它可以验证它没有被修改),但这也可以被规避。

    在这一点上,一切都是缓解措施。没有办法。


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

    永远不要相信客户

    不应该有 API 来做这些。客户应该没有办法设置分数(或设置任何其他形式的奖励)。相反,客户端将事件发送到服务器(它们可以像每个用户输入一样精细,这就是你在多人客户端-服务器游戏中所做的事情),然后服务器决定分数、奖励等。

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

    删除流程是保证您消除风险的唯一方法。否则,一切都是缓解措施。


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


    附录

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

    我们想要的不是阻止第三方自定义客户端的创建,也不是让它变得无用。而是确保它最多只能做合法客户端可以做的事情。

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

    【讨论】:

    • 非常感谢@Theraot 的回答。我能理解你,但这不是我的实际代码:) 我的实际代码很长,我只是为这个问题编写这段代码。我的问题是,今天我发现了一个名为(DevXUnity-Unpacker Magic Tools)的工具,这个工具会像代码一样解压统一游戏人员:(这样黑客就可以查看我所有的代码他们会找到注册链接(localhost/registrar.php) 或其他链接,如插入分数数据,因此他们可以制作自己的表格并使用我的代码,如插入分数数据。如果可以破解我的分数,但我不喜欢使用 php 链接.
    • @Mr.Ali php 并非天生不安全——尽管有些人可能会说——但默认情况下它也不安全。如果您不希望 rouge 客户端插入分数数据,请不要在服务器 API 上提供。客户端必须只告诉服务器用户做了什么,服务器必须计算给你多少分数作为奖励,更新它,然后发送给客户端。在任何时候,客户端都必须有一个选项来告诉服务器你得到多少分数,那个 API 不应该存在。
    • @Mr.Ali 你给我的印象是你担心黑客会以某种方式改变你的 PHP。我假设 PHP 代码在远程服务器中。不在 Unity 游戏中,不在客户端计算机中。除非服务器通过其他方式易受攻击,否则黑客无法看到它,也无法对其进行编辑。这应该是,如果它是 PHP 与否。
    • 对不起,如果我打扰你先生,但使命召唤或其他大型游戏如何保存数据。你知道我为什么要处理这个。因为我想在玩家删除手机上的游戏并重新安装游戏时保存并加载他们的数据。
    • @Mr.Ali 当然是在服务器上。我不建议没有服务器。只是没有服务器可以选择让客户端(合法与否)告诉它奖励(分数等)。所有这些都必须由服务器决定。我在How do I avoid users hacking my network games from the client side? 对此主题进行了更详细的介绍,您可能也对The state that is synced when a window is broken in a FPS game 感兴趣(您会在那里找到更详细的链接)。
    【解决方案2】:

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

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

    或者类似的东西。

    【讨论】:

    • 感谢您回答我。但我很抱歉我不明白你在做什么,我已经编辑了我的问题并添加了我的 PHP 代码,请你为我编辑代码,以便我理解你的意思(api 密钥)。跨度>
    • 如果您直接向您的客户推出您的 C# 应用程序,那么您不会通过 api-key 获得更高的安全性。
    • @user6537157 hanks for answe,但黑客可以解压缩统一游戏并查看所有 c# 代码,可以像 scroe 一样破解我的游戏,但我不喜欢在 php 链接中这样做:(
    • @Mr.Ali 是的,您的代码始终可以保留。这就是为什么 apikey 不能提供更多安全性的原因。
    【解决方案3】:

    您无法确保黑客不会发布虚假分数。

    您可以尝试在服务器端验证数据(例如“这个分数是否可以用于播放时间?”)。
    或者您可以在服务器端做尽可能多的事情(您的 C# 应用程序在用户开始游戏时调用您的 php 后端并返回一个令牌(= 随机字符串)并测量时间)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-03
      • 2014-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      相关资源
      最近更新 更多