- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试为我网站上的表单添加一些安全性。其中一种形式使用 AJAX,另一种是直接的“联系我们”形式。我正在尝试添加一个 CSRF token 。我遇到的问题是 token 有时只出现在 HTML“值”中。其余时间,该值为空。这是我在 AJAX 表单上使用的代码:
PHP:
if (!isset($_SESSION)) {
session_start();
$_SESSION['formStarted'] = true;
}
if (!isset($_SESSION['token'])) {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
HTML:
<input type="hidden" name="token" value="<?php echo $token; ?>" />
有什么建议吗?
最佳答案
对于安全码,请不要这样生成 token :$token = md5(uniqid(rand(), TRUE));
rand()
is predictable uniqid()
only adds up to 29 bits of entropy md5()
不添加熵,它只是确定性地混合它试试这个:
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
旁注:my employer's open source projects 之一是一项将 random_bytes()
和 random_int()
反向移植到 PHP 5 项目中的倡议。它是 MIT 许可的,在 Github 和 Composer 上可用 paragonie/random_compat .
session_start();
if (empty($_SESSION['token'])) {
if (function_exists('mcrypt_create_iv')) {
$_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
} else {
$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
}
}
$token = $_SESSION['token'];
不要只使用==
甚至===
,使用hash_equals()
(仅限 PHP 5.6+,但可用于带有 hash-compat 库的早期版本。
if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) {
// Proceed to process the form data
} else {
// Log this as a warning and keep an eye on these attempts
}
}
您可以使用 hash_hmac()
进一步限制 token 仅可用于特定表单. HMAC 是一种特殊的键控散列函数,即使使用较弱的散列函数(例如 MD5),也可以安全使用。不过,我建议改用 SHA-2 系列哈希函数。
首先,生成第二个 token 用作 HMAC key ,然后使用如下逻辑来呈现它:
<input type="hidden" name="token" value="<?php
echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />
然后在验证 token 时使用全等运算:
$calc = hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
if (hash_equals($calc, $_POST['token'])) {
// Continue...
}
在不知道 $_SESSION['second_token']
的情况下,无法在另一个上下文中重复使用为一个表单生成的 token 。 重要的是您使用单独的 token 作为 HMAC key ,而不是您刚刚放在页面上的那个。
任何使用 Twig templating engine 的人通过将此过滤器添加到他们的 Twig 环境中,可以从简化的双重策略中受益:
$twigEnv->addFunction(
new \Twig_SimpleFunction(
'form_token',
function($lock_to = null) {
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
if (empty($_SESSION['token2'])) {
$_SESSION['token2'] = random_bytes(32);
}
if (empty($lock_to)) {
return $_SESSION['token'];
}
return hash_hmac('sha256', $lock_to, $_SESSION['token2']);
}
)
);
使用这个 Twig 函数,您可以像这样使用这两种通用标记:
<input type="hidden" name="token" value="{{ form_token() }}" />
或锁定变体:
<input type="hidden" name="token" value="{{ form_token('/my_form.php') }}" />
Twig 只关心模板渲染;您仍然必须正确验证 token 。在我看来,Twig 策略提供了更大的灵 active 和简单性,同时保持了最大安全性的可能性。
如果您有一个安全要求,即每个 CSRF token 只能使用一次,那么最简单的策略是在每次成功验证后重新生成它。但是,这样做会使之前的每一个 token 都失效,这与同时浏览多个标签的人不能很好地混合。
Paragon Initiative Enterprises 维护着 Anti-CSRF library对于这些极端情况。它仅适用于一次性使用的 per-form token 。当 session 数据中存储了足够的 token 时(默认配置:65535),它将首先循环出最旧的未兑换 token 。
关于php - 如何使用 PHP 正确添加跨站请求伪造 (CSRF) token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6287903/
我对 FakeItEasy(或其他模拟对象,因为我相信它们非常相似)有疑问。以下是我的 puesdocode: public class Service { public void Check
我想使用鼠标/键盘伪造操作(或触摸)事件。当我尝试使用以下方法引发事件时: RoutedEventArgs e = new RoutedEventArgs(ManipulationStartedEve
出于某种原因,我的 SVN 存储库的本地副本停止将父目录识别为工作副本。我通常会通过再次 checkout 到另一个文件夹并用我更改的文件覆盖新的工作副本来解决此问题。然后我会从新文件夹中进行提交。
我正在尝试设置我的开发实例,以便我可以伪造一些我拥有的网址。我的网站有许多网址,根据您访问的网址,我的网站的行为会因域的不同而有所不同。 我编辑了我的 C:\WINDOWS\system32\driv
当用户登录并选中“记住我”框时,我会为它生成一个 key (md5 上非常随机的数字)并保存在它的 cookie 上。如果用户未登录,我的代码会检查“记住我的 key ”cookie,如果它与用户匹配
有没有办法强制 Oracle 也“看到”一个表和相关索引比它们实际更大? 换句话说,有没有办法“伪造”数据库统计信息,因此基于成本的优化器会在几乎为空的数据库上做出决策,这更接近于在真实的大型生产数据
这是我使用 tsqlt 的第一天,所以你可能会看到一些含糊的陈述。 我正在尝试测试一个具有 Try Catch Block 的存储过程,但测试中的实际语句是插入和更新命令。 现在我想测试如果出现 Er
我从mockito开始,想知道如何假装添加观察者。我想编写一个测试来确保观察者计数在函数调用后增加。 示例测试代码: MyClassUnderTest instance = new MyClassUn
我是一名 C# 游戏开发人员,我有一个安全功能,我的服务器动态创建一个包含一些 key 的 DLL,并将这个 DLL 上传到 amazon s3,然后向人们提出挑战随机的。当客户收到此质询时,他们有
我正在尝试“伪造”一个 Canvas ,目的是将这个伪造的 Canvas 交给一个可能是任意的框架,以对所有直线、曲线和 moveTo 进行后处理。 为了解决这个问题,我尝试了这段代码,它确实有效,但
我的应用程序需要 SQL Server 2000 作为数据库存储。我真的不想使用 SQL Server 2000,但我可以改用 MySQL Server。 应用程序使用 ODBC 连接到 SQL Se
我有一个下拉菜单,需要一个带有左右边距的滚动条。我正在使用-webkit-scrollbar,但据我所知,它只支持沿滚动轴的边距,所以我一直在用容器内元素的右边距来近似水平边距,并在外部 div,如您
作为我学生小组业余项目的一部分,我正在创建微 Controller 有线网络的模拟,以测试我们编写的算法。每个 Controller 都连接到多个数据端口,每个端口都有一个输入和输出流。我通过给每个端
我已经在 Forge 中安装了自定义 SSL 证书。现在我的网站宕机了 -_-。 Site is not available connection refused 我已经重新启动了我的服务器,但没有任
我正在开发具有 ListView 和详细 View 的应用程序,并且我从 ListView 到详细 View 设置动画。在执行此操作时,我想在某个阶段隐藏状态栏(最好同时在后台显示 ListView
我想用它在 MS-Test 单元测试中伪造 System.Net.Mail.SmtpClient。为此,我添加了一个 System.dll 的 Fakes Assembmly。然后我创建一个 Shim
在我的 Playframework 2.4 项目中,我有这样的方法: public static Result resetValue(int client) { String received
这是我渲染场景的过程: 绑定(bind) MSAA x4 GBuffer(4 种颜色附件、位置、法线、颜色和无光照颜色(仅天空盒。我还有一个深度组件/纹理)。 绘制天空盒 绘制地理 将所有颜色和深度分
我不太确定 $_SESSION 在 PHP 中是如何工作的。我假设它是浏览器上的 cookie 与服务器上的唯一 key 匹配。是否可以伪造并绕过仅使用 session 来识别用户的登录。 如果 $_
大家好,我是沙漠尽头的狼。 本文首发于 Dotnet9 ,介绍使用 Lib.Harmony 库拦截第三方 .NET 库方法,达到不修改其源码并能实现修改方法逻辑、预期行为的效果,并
我是一名优秀的程序员,十分优秀!