如何保护 asp.net mvc5 应用程序?
How to secure asp.net mvc5 applications?
<authentication mode="Forms"/>
<forms loginUrl="~/Login/Login" defaultUrl="~/Login/Something" protection="All"></forms>
</authentication>
一种方法是向每个控制器添加授权标签以保护应用程序免受未经授权的 user.Other 方法是使用会话变量来存储用户信息。所以,我的问题是从黑客的角度来看,我们如何保护我们的应用程序免受黑客攻击?是还有其他方法来保护应用程序吗?
注意:无论如何都不应将此答案视为完整,安全总是很难,如果它对您很重要 - 请始终咨询第三方安全和渗透测试公司。这只是让您的 MVC 应用程序更安全(不一定安全)应该考虑的几件事。
保护控制器
第一步是将 [Authorize]
应用到您的控制器,以确保在访问方法之前存在某种有效的身份验证。最好将 Authorize
添加到所有控制器,并使用 [AllowAnonymous]
进行例外处理,使其成为 secure-by-default.
授权用户
即使您已将 [Authorize]
添加到控制器,这仅意味着用户已登录,而不是用户应该有权访问正在访问的任何方法。第一步是通过为方法指定一组角色来扩展属性:[Authorize(Roles = "Administrator"]
根据应用程序,您可能还必须检查当前用户是否属于 company/group 或任何正在编辑的用户,以防止有人修改不属于他们的数据。
不要将数据泄露到模型中
如果您将实际数据模型用作视图模型,您将面临允许用户输入比预期更多数据的风险。考虑这个例子:
class Employee {
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
}
假设我们出于某种原因允许我们的员工更改姓名,我们为此使用 Employee
模型。但是当然,我们只为 Name
创建一个编辑字段,而不是 Salary
,因为那样会很愚蠢 :D。然而,由于 model-binding 的工作原理,聪明的员工可以在更改姓名时将 <input type="text" name="Salary" value="2147483647">
添加到表单中,而我们易受骗的 db.Entry(employee).State = EntityState.Added;
后跟 db.SaveChanges()
会更新他们的工资也一样。
解决方案?要么制作一个仅包含 Id
和 Name
属性 的视图模型,使其无法更改薪水,要么使用 Bind
属性仅包含我们允许的属性: public IActionResult Update([Bind(Include="Id,Name")]Employee model)
.
XSS
一个非常重要的部分是保护您的用户免受不良动态内容的影响。例如,如果我可以输入显示给其他用户的 HTML 和 Javascript,我就可以滥用它来窃取他们的身份验证令牌。永远不要将 user-entered 数据呈现为 HTML 是防止这种情况发生的第一步。您还应该确保在表单中也始终使用 anti-forgery 标记。添加 CSP headers 是一种很好的做法,可以防止有人注入不应该存在的脚本。
<authentication mode="Forms"/>
<forms loginUrl="~/Login/Login" defaultUrl="~/Login/Something" protection="All"></forms>
</authentication>
一种方法是向每个控制器添加授权标签以保护应用程序免受未经授权的 user.Other 方法是使用会话变量来存储用户信息。所以,我的问题是从黑客的角度来看,我们如何保护我们的应用程序免受黑客攻击?是还有其他方法来保护应用程序吗?
注意:无论如何都不应将此答案视为完整,安全总是很难,如果它对您很重要 - 请始终咨询第三方安全和渗透测试公司。这只是让您的 MVC 应用程序更安全(不一定安全)应该考虑的几件事。
保护控制器
第一步是将 [Authorize]
应用到您的控制器,以确保在访问方法之前存在某种有效的身份验证。最好将 Authorize
添加到所有控制器,并使用 [AllowAnonymous]
进行例外处理,使其成为 secure-by-default.
授权用户
即使您已将 [Authorize]
添加到控制器,这仅意味着用户已登录,而不是用户应该有权访问正在访问的任何方法。第一步是通过为方法指定一组角色来扩展属性:[Authorize(Roles = "Administrator"]
根据应用程序,您可能还必须检查当前用户是否属于 company/group 或任何正在编辑的用户,以防止有人修改不属于他们的数据。
不要将数据泄露到模型中
如果您将实际数据模型用作视图模型,您将面临允许用户输入比预期更多数据的风险。考虑这个例子:
class Employee {
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
}
假设我们出于某种原因允许我们的员工更改姓名,我们为此使用 Employee
模型。但是当然,我们只为 Name
创建一个编辑字段,而不是 Salary
,因为那样会很愚蠢 :D。然而,由于 model-binding 的工作原理,聪明的员工可以在更改姓名时将 <input type="text" name="Salary" value="2147483647">
添加到表单中,而我们易受骗的 db.Entry(employee).State = EntityState.Added;
后跟 db.SaveChanges()
会更新他们的工资也一样。
解决方案?要么制作一个仅包含 Id
和 Name
属性 的视图模型,使其无法更改薪水,要么使用 Bind
属性仅包含我们允许的属性: public IActionResult Update([Bind(Include="Id,Name")]Employee model)
.
XSS
一个非常重要的部分是保护您的用户免受不良动态内容的影响。例如,如果我可以输入显示给其他用户的 HTML 和 Javascript,我就可以滥用它来窃取他们的身份验证令牌。永远不要将 user-entered 数据呈现为 HTML 是防止这种情况发生的第一步。您还应该确保在表单中也始终使用 anti-forgery 标记。添加 CSP headers 是一种很好的做法,可以防止有人注入不应该存在的脚本。