gpt4 book ai didi

angularjs - 请求中的请求头和 cookie 中的 CSRF token 不匹配

转载 作者:行者123 更新时间:2023-12-04 21:40:14 28 4
gpt4 key购买 nike

我正在实现一个无状态 API,我的组织说我需要防止 CSRF 攻击。

我在网上找到了这个人的解决方案,并决定尝试实现仅客户端的方法:http://blog.jdriven.com/2014/10/stateless-spring-security-part-1-stateless-csrf-protection/

以下是该网站对无状态解决方案的说明(以防网站出现故障):

  1. CLIENT-SIDE GENERATED CSRF-TOKENS. Have the clients generate and send the same unique secret value in both a Cookie and a custom HTTP header. Considering a website is only allowed to read/write a Cookie for its own domain, only the real site can send the same value in both headers. Using this approach all your server has to do is check if both values are equal, on a stateless per request basis!


不幸的是它不起作用。我的 header 值永远不会匹配我的 cookie 值,并且在某些情况下,我的 header 似乎只是匹配 cookie 值之后的一个请求。

这是我的 Angular 代码:
 app.config(['$httpProvider', function ($httpProvider) {
//fancy random token
function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e16]+1e16).replace(/[01]/g,b)};

$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-TOKEN';
$httpProvider.defaults.xsrfCookieName = 'CSRF-TOKEN';

$httpProvider.interceptors.push(function () {
return {
'request': function (config) {
document.cookie = 'CSRF-TOKEN=' + b();
return config
}
};
});
}]);

以下是正在发送的 CSRF 值的一些示例。
 CSRF-TOKEN=d25cf03a985d575ad48a863eac91467666
X-CSRF-TOKEN:fa1f165df8b27195a90f5e7841108f4e42

CSRF-TOKEN=d25cf03a985d575ad48a863eac91467666
X-CSRF-TOKEN:fa1f165df8b27195a90f5e7841108f4e42

CSRF-TOKEN=9c8dd46ed06c250b707ac0cb80a08a23ac
X-CSRF-TOKEN:d25cf03a985d575ad48a863eac91467666

CSRF-TOKEN=eb407a0303c21173fe4d0ae03c97eaea6d
X-CSRF-TOKEN:0cf066bf83e50b5c74cb932ab8a47c94e8

CSRF-TOKEN=506355a940a2ac5b48f363712b34570d73
X-CSRF-TOKEN:eb407a0303c21173fe4d0ae03c97eaea6d

这里发生了什么?我觉得我正在做那个人的解决方案中的所有事情,但最终得到了奇怪的结果。

最佳答案

我最终没有发送由客户端在每个请求中创建的随机 token 。我无法让它工作。

所以这就是我解决我的问题的方法(有点):

(1) 在每个请求(包括第一个)上,我从我的 API 发送回响应 header 中的 cookie,名称为“XSRF-TOKEN”以及与之关联的随机值。这是 AngularJS 在使用 CSRF 保护时默认寻找的名称。

(2) 在收到该 token 后的请求中会发生什么,AngularJS 使用该 token 的值在名为“XSRF-TOKEN”的请求 header 中发送 cookie 以及带有该 token 值的名为“X-XSRF-TOKEN”的 header 以及。

所以我的 API 正在处理随机化 XSRF token ,而我的应用程序仍然是无状态的。我正在使用 Web API,并且正在使用全局过滤器来处理此 XSRF token 创建。下面是我执行此操作的代码(在 C# 中)。我不再有任何代码在 UI 中处理此问题(因为它似乎不需要):

public class ValidateAntiForgeryToken : ActionFilterAttribute
{
private const string XsrfCookieName = "XSRF-TOKEN";

private const string XsrfHeaderName = "X-XSRF-TOKEN";

private const string CsrfTokenSalt = "RANDOM SALT";


public override void OnActionExecuting(HttpActionContext filterContext)
{
string requestMethod = filterContext.Request.Method.Method;

Boolean isValid = true;

if (requestMethod != "GET")
{
var headerToken = filterContext.Request.Headers.Where(x => x.Key.Equals(XsrfHeaderName, StringComparison.OrdinalIgnoreCase))
.Select(x => x.Value).SelectMany(x => x).FirstOrDefault();

var cookieToken = filterContext.Request.Headers.GetCookies().Select(x => x[XsrfCookieName]).FirstOrDefault();

// check for missing cookie or header
if (cookieToken == null || headerToken == null)
{
isValid = false;
}

// ensure that the cookie matches the header
if (isValid && !String.Equals(headerToken, cookieToken.Value, StringComparison.OrdinalIgnoreCase))
{
isValid = false;
}

if (!isValid)
{
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
filterContext.Response.ReasonPhrase = "Unauthorized to make that request.";
return;
}
}

base.OnActionExecuting(filterContext);
}


public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
string textToHash = RandomStringGeneration();
string cookieText = HashService.HashText(textToHash, CsrfTokenSalt);

var cookie = new CookieHeaderValue(XsrfCookieName, HttpUtility.UrlEncode(cookieText));

/* don't use this flag if you're not using HTTPS */
cookie.Secure = true;
cookie.HttpOnly = false; // javascript needs to be able to get this in order to pass it back in the headers in the next request

/* if you have different environments on the same domain (which I did in one application using this code) make sure you set the path to be ApplicationPath of the request. Case sensitivity does matter in Chrome and IE, so be wary of that. */
cookie.Path = "/";

actionExecutedContext.Response.Headers.AddCookies(new[] { cookie });

base.OnActionExecuted(actionExecutedContext);
}
}

这是我的 HashService.HashText() 代码:
public class HashService
{
public static string HashText(string text, string salt)
{
SHA512Managed hashString = new SHA512Managed();

byte[] textWithSaltBytes = Encoding.UTF8.GetBytes(string.Concat(text, salt));
byte[] hashedBytes = hashString.ComputeHash(textWithSaltBytes);

hashString.Clear();

return Convert.ToBase64String(hashedBytes);
}
}

希望这对将来使用无状态应用程序的人有所帮助。不幸的是,发回的 token 仅在 cookie 值和 header 值中与自身进行比较。这是我现在能够验证它的唯一方法(我觉得这很安全)。我可能会为 XSRF 保护创建一个全新的表,并使用它来验证 token 确实是用户应该使用的 token 。这是让我的 API 保持无状态的唯一方法。

在阅读了 AngularJS 的 $http 文档后,我偶然发现了这个解决方案,其中规定:

Cross Site Request Forgery (XSRF) Protection: XSRF is a technique by which an unauthorized site can gain your user's private data. Angular provides a mechanism to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie (by default, XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN). Since only JavaScript that runs on your domain could read the cookie, your server can be assured that the XHR came from JavaScript running on your domain. The header will not be set for cross-domain requests.

To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called XSRF-TOKEN on the first HTTP GET request. On subsequent XHR requests the server can verify that the cookie matches X-XSRF-TOKEN HTTP header, and therefore be sure that only JavaScript running on your domain could have sent the request. The token must be unique for each user and must be verifiable by the server (to prevent the JavaScript from making up its own tokens). We recommend that the token is a digest of your site's authentication cookie with a salt for added security.

The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName properties of either $httpProvider.defaults at config-time, $http.defaults at run-time, or the per-request config object.

关于angularjs - 请求中的请求头和 cookie 中的 CSRF token 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28508848/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com