请参考我对格雷格答案的评论,以了解与他的答案相关的更多细节,这些答案也与此相关
我通过Controller
, 这是一个简单地本地化端点并进一步调用它的类,因此,它是某种路由器,它首先进行一些检查:
这个Controller
, 初始化时,为相关用户创建一个nonce。此nonce是全局的。端点本身没有nonce,也没有注册为AJAX端点(因此,攻击者不能简单地绕过必须通过Controller
, 因此,nonce检查只执行一次运行访问回调函数,如can_user( \'administrator\' )
每次有人叫它因此,我的Controller
有两个安全层:一个用于检查请求是否代表Controller
将该nonce设置为,并再次检查是否有调用方和端点的权限(因为默认情况下,所有端点都对所有人开放)。
我在这里的目的是使端点创建无缝,如果没有必要,也不要有太多的样板。因此,我不希望那些扩展系统的人必须为每个操作创建一个nonce,而是依赖访问回调来查看是否应该发生某个操作
我的问题是wp_create_nonce
采用的参数为$action
, 也就是说,它试图将一个nonce上下文化为一个特定的动作(我的Controller
不是。是Controller
只要简单地调用一个操作,如果该操作不是由同一个用户调用的,它就会退出),这就足够了吗?
旁注。
我已经测试了经典:访问链接/填写我网站的表单,从理论上讲,这会做一个管理员不想做的操作,例如,我试图欺骗自己。给出的错误是“403:禁止”,因为nonce无效。
My question is, then: why did the WP Core team have a need to try to bind a nonce to an action? Just for the sake of clarity?
如果是这样的话,那肯定是因为WP核心没有编写AJAX端点,系统也没有置于类似路由器的花式裤子结构之下,因此,他们试图用上下文来挑选端点,以便理解它们。在像我这样的系统中,我拥有
Container
,
Provider
以及有用的功能来告诉您
Endpoint
对象。
SO网友:Greg Winiarski
对于基于用户名的nonce,我认为您正在试图保护自己免受CSRF攻击,这应该在某种程度上起作用(如果没有完整的源代码,很难说),也就是说,nonce应该分配给specific action (不仅仅是一个操作),因此,例如,您不会将其分配给“delete item”操作,而是分配给delete item with ID=X“行动。
这就是为什么你应该这样做。
假设您有两个用户,一个登录名为“john”,另一个登录名为“hacker”。
如果仅为每个用户生成nonce,则可以为每个用户生成一个nonce,如“{$user_name}-delete-item“。任何登录的用户都会生成此nonce,通过查看源代码,他们可以找到他们的nonce代码是什么。
现在想象一下“黑客”用户有一个如下所示的删除链接https://example.com/?delete-item=1000&nonce=qwertyuiop 其中(qwertyuiop是他生成的nonce代码)。
“黑客”用户可以操纵链接并将1000替换为2000,然后在浏览器中打开链接。nonce将进行验证,“黑客”将能够删除id为2000的项目,即使“john”用户拥有该项目。
为了提高安全性,您应该生成一个nonce名称,如“my-delete-item-{$id}“(在这种情况下”my-delete-item-1000),则将为特定操作生成nonce,如果“黑客”将ID从1000更改为2000,则不会验证nonce,因为他没有仅为“my-delete-item-1000”为“my-delete-item-2000”生成nonce。
当然,我假设您有一些额外的代码来检查用户是否拥有2000个项目,这样您就可以不用像这样使用nonce了。在这种情况下,我的观点是,如果没有为特定操作生成nonce,可能会产生错误的安全感。
最后一点要注意的是,即使在可能的情况下为每个特定操作生成nonce,您也应该有额外的代码来检查用户是否可以执行给定的操作。正如nonces文档中所指出的https://codex.wordpress.org/WordPress_Nonces
不应依赖nonce进行身份验证或授权、访问控制。使用current\\u user\\u can()保护您的函数,始终假定nonce可能会受到危害。