跨站点伪造 (CSRF) 和 Public 应用程序接口
Cross-Site Forgeries (CSRF) and Public Application Interface
希望加强安全性并防止跨站点请求伪造攻击。了解表单的标记化,但不太清楚对象实例。
根据 OWASP 利用标准包括 1. Web 用户需要进行身份验证和 2. CSRF 攻击专门针对状态更改请求。
问题:
我有一个 public 面向数据库驱动内容的照片库。应用程序通过数据库进行身份验证,但不是 Web 用户。
在初始页面加载(初始状态)时,查看器 (HTML) 从应用程序请求缩略图灯箱。 Web 用户单击缩略图以加载与图库关联的图像。单击事件重新加载页面,将 GET 变量(画廊 ID)传递给控制器脚本。控制器创建 params 数组的新实例。
应用程序启动会话,而不是查看器 html。
这是应用程序的 public 界面,其他所有内容都是受保护或私有的。
viewer.php
/*
* class params
*/
if( isset($gid) && $gid!=null ) {
/* show project gallery images */
$params['ticket'] = "gallery";
$params['active'] = "Y";
$params['gid'] = $gid;
} else {
/* show lightbox thumbnails */
$params['ticket'] = "lightbox";
$params['active'] = "Y";
}
/* later in html body, instance object */
$cObj = accesswrapper::factory($params);
$cObj->jobrequest();
unset($params);
unset($cObj);
factory.php
/**
* @api
* @return void
* instantiates the sub class passed from viewer
*
* @param array $params, [ticket] subclass name
* pforeman, object interface
*/
class accesswrapper {
public static function factory($params) {
$ticket = $params['ticket'];
switch($ticket) { //route to appropriate sub class
case $ticket=="lightbox":
$inst = new lightbox($params);
break;
case $ticket=="gallery";
$inst = new gallery($params);
break;
}
if ($inst instanceof pforeman) {
return $inst;
} else {
return void;
}
}
}
问题:
这个过程需要令牌吗?
这足以阻止 CSRF 吗?
如果请求仅进行微不足道的更新(更多关于下面 "trivial updates" 的定义),则无需担心 CSRF。在典型的 CSRF 攻击中,您有:
- 用户使用网站 cookie 登录网站 A。
- 在同一个浏览器会话中,用户访问网站 B。
- 网站 B 导致浏览器访问网站 A 上的某些 URL。
- 网站 A 认为请求来自用户而响应。
由于同源策略,B站看不到访问的响应;它只能导致访问发生。因此,如果请求仅进行微不足道的更新,则用户的浏览器将在访问站点 B 时显示站点 A 的内容,但我们知道用户无论如何都有权查看该数据,否则站点 A 会拒绝该请求。
用户可能有点害怕,打电话给网站 A 的支持,无论如何,但没有数据泄露。
如果请求不仅仅是简单的更新,那么网站 B 已经导致用户在网站 A 上采取行动,而这并不是他们的意图。对用户和站点 A 非常不利。
所以在没有 CSRF 保护的情况下,只有琐碎的更新是安全的。其他一切都需要保护。
"Trivial updates" 对不同的网站意味着不同的东西。例如,更新某人的银行余额显然不是一件小事。但是,在数据库中记录获取余额请求是微不足道的更新吗?如何执行耗时的查询?您站点的技术和业务模型将决定您认为哪些更新是微不足道的,哪些可以不受 CSRF 保护,哪些是您认为必须保护的。
在您的应用程序身份验证而非用户身份验证模型中,您无需担心 CSRF,因为所有访问都是 public。
最后一点,在注销功能上不添加 CSRF 保护通常是个好主意。这有助于确保用户始终可以注销,即使在 CSRF 验证中出现错误也是如此。也就是说,这样做的风险是站点 B 可以强制用户从站点 A 注销。您必须选择最适合您的方式。
希望加强安全性并防止跨站点请求伪造攻击。了解表单的标记化,但不太清楚对象实例。
根据 OWASP 利用标准包括 1. Web 用户需要进行身份验证和 2. CSRF 攻击专门针对状态更改请求。
问题: 我有一个 public 面向数据库驱动内容的照片库。应用程序通过数据库进行身份验证,但不是 Web 用户。
在初始页面加载(初始状态)时,查看器 (HTML) 从应用程序请求缩略图灯箱。 Web 用户单击缩略图以加载与图库关联的图像。单击事件重新加载页面,将 GET 变量(画廊 ID)传递给控制器脚本。控制器创建 params 数组的新实例。
应用程序启动会话,而不是查看器 html。
这是应用程序的 public 界面,其他所有内容都是受保护或私有的。
viewer.php
/*
* class params
*/
if( isset($gid) && $gid!=null ) {
/* show project gallery images */
$params['ticket'] = "gallery";
$params['active'] = "Y";
$params['gid'] = $gid;
} else {
/* show lightbox thumbnails */
$params['ticket'] = "lightbox";
$params['active'] = "Y";
}
/* later in html body, instance object */
$cObj = accesswrapper::factory($params);
$cObj->jobrequest();
unset($params);
unset($cObj);
factory.php
/**
* @api
* @return void
* instantiates the sub class passed from viewer
*
* @param array $params, [ticket] subclass name
* pforeman, object interface
*/
class accesswrapper {
public static function factory($params) {
$ticket = $params['ticket'];
switch($ticket) { //route to appropriate sub class
case $ticket=="lightbox":
$inst = new lightbox($params);
break;
case $ticket=="gallery";
$inst = new gallery($params);
break;
}
if ($inst instanceof pforeman) {
return $inst;
} else {
return void;
}
}
}
问题: 这个过程需要令牌吗? 这足以阻止 CSRF 吗?
如果请求仅进行微不足道的更新(更多关于下面 "trivial updates" 的定义),则无需担心 CSRF。在典型的 CSRF 攻击中,您有:
- 用户使用网站 cookie 登录网站 A。
- 在同一个浏览器会话中,用户访问网站 B。
- 网站 B 导致浏览器访问网站 A 上的某些 URL。
- 网站 A 认为请求来自用户而响应。
由于同源策略,B站看不到访问的响应;它只能导致访问发生。因此,如果请求仅进行微不足道的更新,则用户的浏览器将在访问站点 B 时显示站点 A 的内容,但我们知道用户无论如何都有权查看该数据,否则站点 A 会拒绝该请求。
用户可能有点害怕,打电话给网站 A 的支持,无论如何,但没有数据泄露。
如果请求不仅仅是简单的更新,那么网站 B 已经导致用户在网站 A 上采取行动,而这并不是他们的意图。对用户和站点 A 非常不利。
所以在没有 CSRF 保护的情况下,只有琐碎的更新是安全的。其他一切都需要保护。
"Trivial updates" 对不同的网站意味着不同的东西。例如,更新某人的银行余额显然不是一件小事。但是,在数据库中记录获取余额请求是微不足道的更新吗?如何执行耗时的查询?您站点的技术和业务模型将决定您认为哪些更新是微不足道的,哪些可以不受 CSRF 保护,哪些是您认为必须保护的。
在您的应用程序身份验证而非用户身份验证模型中,您无需担心 CSRF,因为所有访问都是 public。
最后一点,在注销功能上不添加 CSRF 保护通常是个好主意。这有助于确保用户始终可以注销,即使在 CSRF 验证中出现错误也是如此。也就是说,这样做的风险是站点 B 可以强制用户从站点 A 注销。您必须选择最适合您的方式。