如何在静态站点上防止CSRF?

时间:2017-06-28 17:11:02

标签: ajax security csrf csrf-protection

我有一个静态网站,由CDN提供,通过AJAX与API通信。我如何防范CSRF?

由于我无法控制如何提供静态网站,因此当有人加载我的静态网站(并将令牌插入表单或使用我的AJAX请求发送)时,我无法生成CSRF令牌。我可以创建一个GET端点来检索令牌,但似乎攻击者只能访问该端点并使用它提供的令牌?

有没有一种有效的方法可以防止这个堆栈出现CSRF?

其他详细信息:此处的身份验证完全独立。我希望CSRF保护的一些API请求是经过身份验证的端点,有些是公共POST请求(但我想确认它们来自我的网站,而不是其他人的)

3 个答案:

答案 0 :(得分:4)

  

我可以创建一个GET端点来检索令牌,但似乎攻击者只能访问该端点并使用它提供的令牌?

正确。但CSRF代币并不是秘密。它们仅存在以确认以一个用户期望的顺序执行动作(例如,表单POST仅遵循对表单的GET请求)。即使在动态网站上,攻击者也可以向页面提交自己的GET请求,并解析嵌入在表单中的CSRF令牌。

来自OWASP

  

CSRF是一种欺骗受害者提交恶意请求的攻击。它继承了受害者的身份和特权,以代表受害者执行不受欢迎的功能。

在页面加载时发出初始GET请求以获取新令牌然后在执行操作的请求中提交它是完全有效的。

如果您想确认提出请求的人的身份,您需要进行身份验证,这是CSRF的另一个问题。

答案 1 :(得分:0)

我的解决方法如下

客户端 [静态 html]

 bunny = 0
 turtle = 0
 temp = 0
 sequence = [2, 8, 7, 1, 4]


 def bubblesort():

     for x in sequence:
         turtle = sequence[x]
         for y in sequence:
             bunny = sequence[y]
             if sequence[y] < sequence[x]:
                 temp = sequence[y]
                 sequence[y] = sequence[x]
                 sequence[x] = temp
                 temp = 0
     print(sequence)                
     return sequence

 print("After bubble sorting: ", bubblesort())

可以修改以上内容以针对预先存在的 csrf 字段。我用它来添加带有表单的页面。该脚本假定页面上的第一个表单是目标,因此如果需要,这也需要更改。

在服务器上生成CSRF(使用PHP:假设> 7)

[CSRFTOKEN 在配置文件中定义。示例]

<script>
// Call script to GET Token and add to the form
fetch('https:/mysite/csrf.php')
.then(resp => resp.json())
.then(resp => {
    if (resp.token) {
        const csrf = document.createElement('input');
        csrf.name = "csrf";
        csrf.type = "hidden";
        csrf.value = resp.token;
        document.forms[0].appendChild(csrf);
    }
});
</script>

服务器:

define('CSRFTOKEN','__csrftoken');

最后在处理表单的代码中

$root_domain = $_SERVER['HTTP_HOST'] ?? false;
$referrer = $_SERVER['HTTP_REFERER'] ?? false;

// Check that script was called by page from same origin
// and generate token if valid. Save token in SESSION and
// return to client
$token = false;
if ($root_domain && 
    $referrer && 
    parse_url($referrer, PHP_URL_HOST) == $root_domain) {
  $token = bin2hex(random_bytes(16));
  $_SESSION[CSRFTOKEN] = $token;
}

header('Content-Type: application/json');
die(json_encode(['token' => $token]));

答案 2 :(得分:-2)

对此有很好的解释,请检查
https://cloudunder.io/blog/csrf-token/

根据我的理解,如果我们添加了X-Requested-With标志,由于CORS限制,静态网站似乎不会面临CSRF的任何问题。
还有一个问题我想在此强调,

如何保护从移动应用程序以及静态网站调用的api? <登记/>
由于api被公开曝光,您希望确保只允许用户调用它 我们可以在我们的API服务层添加一些检查,用于相同的

1)对于AJAX请求(来自静态站点)检查请求域,因此只允许站点访问它 2)对于移动请求使用HMAC令牌,请在此处阅读更多内容 http://googleweblight.com/i?u=http://www.9bitstudios.com/2013/07/hmac-rest-api-security/&hl=en-IN