实施 Google 身份服务弹出代码模型时如何处理 CSRF?
How to handle the CSRF when implementing Google Identity Services popup code model?
在我的网站上,我使用 popup code model.
实现了 Google 身份服务
为了防止 CSRF 攻击,文档是这样说的:
With Popup mode, you add a custom HTTP header to your requests, and
then on your server confirm it matches the expected value and origin.
这是文档中提供的弹出示例代码:
const client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: (response) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', code_receiver_uri, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Set custom header for CRSF
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
xhr.onload = function() {
console.log('Auth code response: ' + xhr.responseText);
};
xhr.send('code=' + code);
},
});
我的理解是我需要在上面的代码中添加一个随机的CSRF代码字符串,然后在我的服务器上进行验证。
但是我应该把 CSRF 代码放在哪里呢?
我认为也许它应该像这样进入 code
变量 xhr.send('code=' + 'MY_CSRF_STRING')
但是当我这样做时我的 headers 看起来像这样(MY_CSRF_STRING
丢失了所以我无法在服务器上验证它):
{
"host":"localhost:5001",
"connection":"keep-alive",
"accept":"*/*",
"access-control-request-method":"POST",
"access-control-request-headers":"x-requested-with",
"origin":"http://localhost:8080",
"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36",
"sec-fetch-mode":"cors",
"sec-fetch-site":"same-site",
"sec-fetch-dest":"empty",
"referer":"http://localhost:8080/",
"accept-encoding":"gzip, deflate, br",
"accept-language":"en-US,en;q=0.9",
"severity":"INFO",
"message":"googleAuthorization req.headers"
}
如果 CSRF 代码没有放在那里,code
变量中还应该放什么?
我想我明白了。
但我仍然很想听听其他人的意见,以确保这是正确的。
简而言之,this answer 概述了 csrf 保护来自检查自定义 X-Requested-With
header 是否存在。无需创造自己的独特价值。
Google 代码示例中还有一个拼写错误造成了这种混淆。
行 xhr.send('code=' + code);
应该是 xhr.send('code=' + response.code);
。因为我们从响应中获取授权码并将其传递给服务器。
在我的网站上,我使用 popup code model.
实现了 Google 身份服务为了防止 CSRF 攻击,文档是这样说的:
With Popup mode, you add a custom HTTP header to your requests, and then on your server confirm it matches the expected value and origin.
这是文档中提供的弹出示例代码:
const client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: (response) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', code_receiver_uri, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Set custom header for CRSF
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
xhr.onload = function() {
console.log('Auth code response: ' + xhr.responseText);
};
xhr.send('code=' + code);
},
});
我的理解是我需要在上面的代码中添加一个随机的CSRF代码字符串,然后在我的服务器上进行验证。
但是我应该把 CSRF 代码放在哪里呢?
我认为也许它应该像这样进入 code
变量 xhr.send('code=' + 'MY_CSRF_STRING')
但是当我这样做时我的 headers 看起来像这样(MY_CSRF_STRING
丢失了所以我无法在服务器上验证它):
{
"host":"localhost:5001",
"connection":"keep-alive",
"accept":"*/*",
"access-control-request-method":"POST",
"access-control-request-headers":"x-requested-with",
"origin":"http://localhost:8080",
"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36",
"sec-fetch-mode":"cors",
"sec-fetch-site":"same-site",
"sec-fetch-dest":"empty",
"referer":"http://localhost:8080/",
"accept-encoding":"gzip, deflate, br",
"accept-language":"en-US,en;q=0.9",
"severity":"INFO",
"message":"googleAuthorization req.headers"
}
如果 CSRF 代码没有放在那里,code
变量中还应该放什么?
我想我明白了。
但我仍然很想听听其他人的意见,以确保这是正确的。
简而言之,this answer 概述了 csrf 保护来自检查自定义 X-Requested-With
header 是否存在。无需创造自己的独特价值。
Google 代码示例中还有一个拼写错误造成了这种混淆。
行 xhr.send('code=' + code);
应该是 xhr.send('code=' + response.code);
。因为我们从响应中获取授权码并将其传递给服务器。