来自 angular 个应用的每个请求的防伪令牌
Anti-forgery token on each request from angular app
我有一个应该非常安全的网站,因为大多数活动都是金融交易。这个网站有很多安全机制,我怀疑其中一个是不够的。
此 Web 应用程序基于 AngularJS 1.4 和 ASP.NET MVC 4。使用 angular 登录系统后,我正在调用控制器操作来设置防伪令牌.所有后续请求都具有相同的令牌,并且服务器在每个请求上验证相同的令牌。
现在是问题。
由于我们不会在每个请求上更改令牌,登录用户只需查看 Fiddler 或 Chrome 网络选项卡即可使用请求中的令牌,并尝试请求修改请求的资源。
是否需要在每次请求时重置令牌?是否有助于防止此类攻击?
令牌并不意味着阻止授权用户手动制作请求。该令牌确保除了他们用户之外的其他人不能使用 csrf 请求伪造来自用户的请求。
您可以重复使用相同的令牌,因为如果实施得当,潜在的 CSRF 攻击者应该无法读取该值。这依赖于浏览器的同源策略来确保第三方站点无法读取或提交相同的值。
如果您有任何漏洞,例如返回令牌的 json GET(最佳做法是 JSON 返回的数据仍应与 post 一起提交)那么令牌可能会被泄露。
授权
关于来自经过身份验证的用户的潜在欺诈请求
您需要进行服务器端检查以确保他只post编辑他有权编辑的帐户。例如,如果我拥有账户 A,并且我想向账户 B 汇款,那么服务器端检查将确保我拥有账户 A,因此有权将其资金发送到其他地方。如果我手工制作一个从 B 向 A 发送资金的请求,服务器端检查应该通过查看帐户和所有者的数据库关系来确定我不是 B 的所有者。这称为授权。授权确保用户有权执行操作。这通常由业务规则决定,这些规则定义表之间的关系,说明谁有权访问什么。
身份验证
唯一的其他问题是确保我是我所说的那个人,因为如果我只是 post 在请求中输入一个用户 ID,我可以很容易地在浏览器中更改它。
当用户证明他是他所说的人时,通常是通过提供 userid/password,然后我们生成一个身份验证令牌。在 ASP.NET 中,此令牌是加密安全的,因此只有服务器具有生成和验证令牌所需的密钥信息。通常此令牌作为 cookie 保留。
身份验证和授权的组合确保我们知道用户是谁,并且在每次请求时使用我们定义授权的业务规则来检查操作是否有效。他可以手工制作无效请求并不重要,因为这些请求将无法通过服务器端授权。
想象一下这个简化的服务器端代码:
public void TransferFunds(TransferFundsRequest request)
{
var account = Database.GetAccount(request.SourceAccountId);
if(account.OwnerUserId != session.UserId)
{
throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
}
// continue with logic to transfer funds
}
CSRF
跨站点请求伪造是一个完全不同的问题。这是当授权用户的浏览器中加载的另一个站点以某种方式尝试从用户的浏览器发送请求时。我访问的恶意第三方站点使用 javascript 或其他方法使我的浏览器发出从帐户 A 到帐户 C 的 TransferFunds 请求。现在如果我是帐户 A 的所有者,从服务器的角度来看是一个有效的请求。 CSRF 令牌确保我们可以检测到用户没有从我们的服务器生成的表单发送请求,而是某个第三方站点的表单或 URL.
例如,如果请求的所有参数都可以在查询字符串中编码,我可以为 TransferFunds 请求制作一个 URL 并将其通过电子邮件发送给帐户 A 所有者并尝试诱骗他们进入单击 link。如果用户碰巧登录到站点,那么我们的服务器认为用户发送了请求。但是,如果我们在生成 HTML 输入表单时包含反 CSRF 令牌,那么令牌的缺失向我们证明请求来自表单或 URL 由第三方制作。
我有一个应该非常安全的网站,因为大多数活动都是金融交易。这个网站有很多安全机制,我怀疑其中一个是不够的。
此 Web 应用程序基于 AngularJS 1.4 和 ASP.NET MVC 4。使用 angular 登录系统后,我正在调用控制器操作来设置防伪令牌.所有后续请求都具有相同的令牌,并且服务器在每个请求上验证相同的令牌。
现在是问题。
由于我们不会在每个请求上更改令牌,登录用户只需查看 Fiddler 或 Chrome 网络选项卡即可使用请求中的令牌,并尝试请求修改请求的资源。
是否需要在每次请求时重置令牌?是否有助于防止此类攻击?
令牌并不意味着阻止授权用户手动制作请求。该令牌确保除了他们用户之外的其他人不能使用 csrf 请求伪造来自用户的请求。
您可以重复使用相同的令牌,因为如果实施得当,潜在的 CSRF 攻击者应该无法读取该值。这依赖于浏览器的同源策略来确保第三方站点无法读取或提交相同的值。
如果您有任何漏洞,例如返回令牌的 json GET(最佳做法是 JSON 返回的数据仍应与 post 一起提交)那么令牌可能会被泄露。
授权 关于来自经过身份验证的用户的潜在欺诈请求
您需要进行服务器端检查以确保他只post编辑他有权编辑的帐户。例如,如果我拥有账户 A,并且我想向账户 B 汇款,那么服务器端检查将确保我拥有账户 A,因此有权将其资金发送到其他地方。如果我手工制作一个从 B 向 A 发送资金的请求,服务器端检查应该通过查看帐户和所有者的数据库关系来确定我不是 B 的所有者。这称为授权。授权确保用户有权执行操作。这通常由业务规则决定,这些规则定义表之间的关系,说明谁有权访问什么。
身份验证 唯一的其他问题是确保我是我所说的那个人,因为如果我只是 post 在请求中输入一个用户 ID,我可以很容易地在浏览器中更改它。
当用户证明他是他所说的人时,通常是通过提供 userid/password,然后我们生成一个身份验证令牌。在 ASP.NET 中,此令牌是加密安全的,因此只有服务器具有生成和验证令牌所需的密钥信息。通常此令牌作为 cookie 保留。
身份验证和授权的组合确保我们知道用户是谁,并且在每次请求时使用我们定义授权的业务规则来检查操作是否有效。他可以手工制作无效请求并不重要,因为这些请求将无法通过服务器端授权。
想象一下这个简化的服务器端代码:
public void TransferFunds(TransferFundsRequest request)
{
var account = Database.GetAccount(request.SourceAccountId);
if(account.OwnerUserId != session.UserId)
{
throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
}
// continue with logic to transfer funds
}
CSRF 跨站点请求伪造是一个完全不同的问题。这是当授权用户的浏览器中加载的另一个站点以某种方式尝试从用户的浏览器发送请求时。我访问的恶意第三方站点使用 javascript 或其他方法使我的浏览器发出从帐户 A 到帐户 C 的 TransferFunds 请求。现在如果我是帐户 A 的所有者,从服务器的角度来看是一个有效的请求。 CSRF 令牌确保我们可以检测到用户没有从我们的服务器生成的表单发送请求,而是某个第三方站点的表单或 URL.
例如,如果请求的所有参数都可以在查询字符串中编码,我可以为 TransferFunds 请求制作一个 URL 并将其通过电子邮件发送给帐户 A 所有者并尝试诱骗他们进入单击 link。如果用户碰巧登录到站点,那么我们的服务器认为用户发送了请求。但是,如果我们在生成 HTML 输入表单时包含反 CSRF 令牌,那么令牌的缺失向我们证明请求来自表单或 URL 由第三方制作。