Ionic + ngCookies + PHP 认证,到底有多安全?

Ionic + ngCookies + PHP authentication, how secure can it be?

我正在开发一个移动应用程序,我希望在其中实现简单的用户身份验证,并且由于我是混合移动开发的新手,它的前端限制,我对持有任何东西的想法感到非常害怕localStorage / sessionStorage / ngCookies 形式的后端相关数据(正如我看到有些人所做的那样)。

所以我的问题是,这些方法保存此类数据的安全性如何?应用程序用户是否能够从应用程序本身访问和修改比方说... sessionStorage?因为它在网络上确实很容易。

抱歉,如果这是一个愚蠢的问题,我只是不想在这个问题上冒任何安全风险。非常感谢您的帮助!

TLDR; 应假设 Cookie 和存储以纯文本形式存储,并且可由来自同一域的客户端脚本访问。做最坏的打算;由于错误或 XSS 攻击,您的脚本可能出现任何问题。如果数据将被客户端和服务器再次使用,则最明确地对其进行签名。如果数据仅与服务器端代码相关,请对其进行签名和加密。如果数据仅用于将内容打印到屏幕或 DOM 评估,请保留纯文本。


在开始示例实现之前,让我们先弄清楚什么是 cookie、会话存储和本地存储。

Cookie 是由服务器或客户端创建的数据,由浏览器以纯文本形式存储,如果路径匹配,它会在每次向服务器发出 http 请求时发送。它们适用于存储身份验证令牌、有关跟踪、分析、网站界面首选项、购物车等的元数据。

存储 - 如其名称所示 - 存储 space 分配给您的域,只有来自您域的 脚本和 XSS 攻击 可以更改它。这意味着,如果您将它们用于我上面列出的目的,您必须手动将存储在它们中的数据附加到您的 HTTP 请求中。如果您的站点依赖于许多异步 HTTP 调用,那么使用 cookie 之类的存储并没有错。否则它们可用于缓存模板数据和站点资源等内容。


如果您使用 cookie 来存储服务器所需的用户相关数据,则可以在将这些 cookie 发送到客户端之前在服务器端对其进行加密。您仍然可以使用 ngCookies 访问此类 cookie,但唯一的危害是某些注入的代码可能会使它们无效。如果您的加密方案以某种方式被泄露并且攻击者可以读取它们,您可以通过在每个存储上附加签名(使用安全哈希算法创建)来使对它们的修改无效,并在每次检索时检查您的签名。让我们来说明这个过程。

$userState = json_encode($yourStateObjectOrAnAssociativeArray);
$sign = my_hash($userState);
$encryptedState = encrypt($userState);
setcookie("user" , $encryptedState);
setcookie("sign" , $sign);

这里我们将状态编码为JSON,然后首先生成一个散列。您可以使用一些 SHA1、SHA256 等与您选择的存储密钥一起使用 my_hash() 函数。下面是一个正确的例子,但你不应该使用它,因为即使我不应该知道你的算法。

// hash() is reserved so use something else
function my_hash($object) {
    return sha1(md5($object) . "some giberish key that is stored as config data or in a db" . sha1($object))
}

请注意,my_hash() 不是非常安全,因为它使用静态字符串作为密钥和不复杂的生成结构。最后,它是一些随机结构字符串的 sha1()。不过对于 cookie 标志来说已经足够了。

您可以使用 AES 加密或您选择的一些同等安全的算法编写自己的 encrypt() / decrypt() 对。 Here is an example from this site.

现在我们的 cookie 已存储并准备好在下一个请求时发送。以下是您如何解密和验证上述示例中的 cookie。

$sign = $_COOKIE["sign"];
$encryptedState = $_COOKIE["user"];

$userState = decrypt($encryptedState); //If this fails, it indicates someone tried to replace your cookie by hand, it is a failed attack

$assoc = true; //If true, json_decode returns array, otherwise it returns an object
$yourStateObjectOrAnAssociativeArray = json_decode($userState, $assoc); //If this fails, it indicates someone tried to replace your cookie by hand, it is a failed attack

if($sign == my_hash($yourStateObjectOrAnAssociativeArray)) {
    //Noone modified your cookie, you are safe
    //Do something with it
}
else {
    // Someone tried to replace your sign cookie to imitate your server but he failed
    // or
    // Someone managed to decrypt your cookie and modified it but failed to generate a valid sign (very unlikely)
    // You are still safe
    // Log this line and check every once in a while to detect unsuccessful hackers
}

使用状态对象的好处是它可以用来实现多种限制和跟踪机制。例如,在创建 cookie 期间存储系统时间让您有机会在以后使其过期。嵌入客户端 IP 是一种限制跨网络共享 cookie 的方法。