【问题标题】:How to access to an external database securely?如何安全地访问外部数据库?
【发布时间】:2014-09-22 06:35:44
【问题描述】:

我正在开发一个移动应用程序,它必须访问外部 web 应用程序(PHP + Codeigniter)来管理 ajax 查询的操作。

所以这样一来,就有问题了。如果有人看到使用的 url,可以删除行,或修改数据库中的用户信息。所以我想在这个系统中避免这种情况:

成功登录后,我会这样做:

// getToken : https://stackoverflow.com/a/13733588/2154101

$this->session->set_userdata('private_token', getToken(50));
$public_token = getToken(50);
$this->session->set_userdata('secure_token', md5("$private_token:$public_token"));
$data['token'] = $public_token;
// some stuff ...
// send $data in JSON

然后客户端将在下一个查询中使用公共令牌我将在服务器上执行此操作:

$public_token  = $this->input->post('token');
$data['token'] = get_public_token($public_token);
// some stuff ...
// send $data in JSON

get_public_token 在此代码的助手中的位置:

public get_public_token($public_token) {

    $last_secure_token = $this->session->userdata('secure_token');
    $private_token = $this->session->userdata('private_token');
    $actual_token = md5("$private_token:$public_token");

    if ($actual_token === $last_secure_token) {
        $public_token = getToken(50);
        $this->session->set_data('private_token', getToken(50));
        $this->session->set_data('secure_token', md5("$private_token:$public_token"));
        return $public_token;
    } else { // you are cheating me ...
        $this->session->sess_destroy();
        redirect('/');
    }
}

所以只有这个会话的用户才能修改数据库的数据。

我只是尝试做与此处解释的相同操作:https://stackoverflow.com/a/17371101/2154101

会话是加密的,我也将它们存储在数据库中。 你认为这种方法行得通吗?我错过了什么重要的东西吗?

【问题讨论】:

  • 应用程序是远程访问数据库还是远程访问某种隐藏数据库的web应用程序?巨大的差异。如果是 Web 应用程序,该应用程序的身份验证和授权机制是什么?它如何识别发出请求的用户?显然,任何请求修改他不允许修改的数据的用户都应该只收到一条错误消息,实际上不能修改数据。从代码中并不清楚应用程序是如何排列的或如何跟踪身份验证/授权。
  • 我已经修改了问题。请再读一遍。谢谢! :)
  • 访问 Web 服务的移动应用程序听起来像是使用 OAuth 之类的东西进行授权的一个非常好的用例。最好使用经过行业测试的标准,而不是实施自己的标准。

标签: php codeigniter optimization cross-domain


【解决方案1】:

您应该为您的移动应用程序创建一个 API。创建身份验证机制。

如果您的数据库包含特定于用户的数据,那么您应该为每个用户创建帐户。所以如果用户嗅探网络并尝试手动调用api,那么他只能更改自己的数据。

那里有一些用于 php 的 API 库,你应该看看。

【讨论】:

  • github.com/chriskacerguis/codeigniter-restserver => 用 codeigniter 制作的 API,因为你有以前的经验,它应该会更容易。
  • 但是用我的实际方法我可以防止用户修改任何不属于你的东西。请检查一下。
【解决方案2】:

实际上,您的解决方案做得比必要的多。唯一感兴趣的令牌是来回发送的public_token。所以你可以从会话数据中丢弃private_tokensecure_token,只保留public_token 用于检查。当您可以简化为 X == 14 时,您当前的检查类似于 (X + 5)/2 == (14 + 5)/2([received_token + 5]/2 等于 [14 + 5]/2 吗?)。

但是,如果有人在嗅探网络,他可以获取发送给客户端的最后一个令牌并使用它来劫持该会话。他可以在原始客户端不发送带有过期令牌的请求时执行任何操作,从而终止会话。

更好的解决方案是在登录后创建一个secure_key 并将其保存在两端(客户端和服务器)。然后服务器会在每次响应时继续发送一个新的public_token,但客户端会在请求时发送一​​个md5(secure_key + public_token)。这会将劫持窗口进一步缩小到会话开始的确切位置。没有原始密钥,攻击者无法创建有效的 md5。

但是,我们在这里谈论的是小黑客粉丝。无论如何,任何更热心的人都可以破解它。如果您对此感到担心,那么请扔掉所有这些东西并简单地使用 HTTPS 连接。通过受信任的连接,您的会话和访问控制规则受到保护。

【讨论】:

  • 为什么客户端也会拥有安全的 ley?我已经更新了方法,检查一下,给我你的意见。最后一个问题:用我的实际方法,怎么会有人为用户获取密钥?每次查询时,私钥和公钥都会发生变化,会话变量完全加密并保存在我的数据库中。太感谢了。 :-)
  • 好吧,对我的实际方法有疑问(在你的第二段中):假设有人偷了我的最后一个public_token。然后他尝试用它像我一样进行查询,但服务器会将其与存储在他的会话中的secure_token 进行检查/比较,并且由于它与我的不匹配,因此他将被踢出。 (如果你能解释我为什么这行不通,我会给你 50 分;))。非常感谢!
  • 使用spoofing,任何机器都可以通过HTTP 标头发送(phpSessionID, updated public_token) 对并赢得该会话。它将匹配存储在服务器中的(phpSessionID, expected public_token)
【解决方案3】:

更好的方法是使用 SOAP 或 SAML2 创建 API。

【讨论】:

    【解决方案4】:

    OAuth 可能是一个非常好的解决方案:http://oauth.net/。它负责令牌并具有非常安全的 API!如果您希望支持 Web 应用程序 + 移动应用程序的安全身份验证,那么它可能是一个很好/经过验证的解决方案!

    另一方面,这实际上取决于您当前系统的复杂程度以及系统将来的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      相关资源
      最近更新 更多