我正在开发一个移动应用程序,我希望实现一个简单的用户身份验证,而且由于我对混合移动开发及其前端限制不熟悉,我非常害怕以localStorage / sessionStorage / ngCookies的形式持有任何后端相关数据的想法(正如我所看到的那样)。
所以我的问题是,这些方法对于保存此类数据有多么安全?应用程序用户是否能够从应用程序本身访问和修改说... sessionStorage?因为它确实在网上很容易。
很抱歉,如果这是一个愚蠢的问题,我不希望在此问题上承担任何安全风险。非常感谢任何帮助!
答案 0 :(得分:2)
TLDR; 应假设Cookie和存储以纯文本格式存储,并且可以由来自同一域的客户端脚本访问。假设最坏的;由于错误或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()
。但是,对于一个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的方法。