Ionic+ngCookies+PHP身份验证,它有多安全


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

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

所以我的问题是,这些保存此类数据的方法有多安全?应用程序用户有能力访问和修改吗?比如说。。。会话存储,从应用程序本身?因为它在网上确实很容易。

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

TLDR应假定Cookie和存储以纯文本形式存储,并可由来自同一域的客户端脚本访问。假设最坏的情况;由于bug或XSS攻击,脚本可能会出现任何问题。如果客户端和服务器都将再次使用数据,请对其进行最明确的签名。如果数据仅与服务器端代码相关,则对其进行签名和加密。如果数据只用于打印要筛选的内容或DOM评估,则将其保留为纯文本。


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

Cookie是由服务器或客户端创建的数据,由浏览器以纯文本形式存储,如果路径匹配,则在每次http请求时发送给服务器。它们非常适合存储身份验证令牌、有关跟踪、分析、网站界面偏好、购物车和许多其他的元数据。

正如其名称所示,存储空间是分配给您的域的存储空间,只有域中的脚本和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()。不过,这对于一个饼干标志来说已经足够了。

您可以使用AES加密或您选择的某种同等安全的算法来编写自己的encrypt()/decrypt()对。下面是这个网站的一个例子。

现在我们的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的一种方式。