不安全的直接对象引用¶
ID: cs/web/insecure-direct-object-reference
Kind: problem
Security severity: 7.5
Severity: warning
Precision: medium
Tags:
- security
- external/cwe/cwe-639
Query suites:
- csharp-security-extended.qls
- csharp-security-and-quality.qls
可以通过操作方法访问和修改评论或用户个人资料等资源。为了定位到某个资源,操作方法接受一个指向该特定资源的 ID 参数。如果这些方法没有检查当前用户是否有权访问指定的资源,攻击者就可以通过猜测或以其他方式确定链接的 ID 参数来访问资源。
建议¶
确保当前用户有权访问提供的 ID 所指向的资源。
示例¶
在以下示例中,“错误”情况中没有进行授权检查,因此任何用户都可以编辑他们猜到或确定其 ID 参数的任何评论。“正确”情况中包含了检查当前用户是否与评论作者匹配的逻辑,从而防止了未经授权的访问。
// BAD - Any user can access this method.
protected void btn1_Click(object sender, EventArgs e) {
string commentId = Request.QueryString["Id"];
Comment comment = getCommentById(commentId);
comment.Body = inputCommentBody.Text;
}
// GOOD - The user ID is verified.
protected void btn2_Click(object sender, EventArgs e) {
string commentId = Request.QueryString["Id"];
Comment comment = getCommentById(commentId);
if (comment.AuthorName == User.Identity.Name){
comment.Body = inputCommentBody.Text;
}
}
以下示例展示了 ASP.NET Core 框架中的类似场景。如上所述,“错误”情况提供了一个没有授权检查的示例,而第一个“正确”情况提供了一个检查当前用户是否是指定评论的作者的示例。此外,在第二个“正确”情况中,使用 `Authorize` 属性将该方法限制为管理员,因为管理员应该能够访问任意资源。
public class CommentController : Controller {
private readonly IAuthorizationService _authorizationService;
private readonly IDocumentRepository _commentRepository;
public CommentController(IAuthorizationService authorizationService,
ICommentRepository commentRepository)
{
_authorizationService = authorizationService;
_commentRepository = commentRepository;
}
// BAD: Any user can access this.
public async Task<IActionResult> Edit1(int commentId, string text) {
Comment comment = _commentRepository.Find(commentId);
comment.Text = text;
return View();
}
// GOOD: An authorization check is made.
public async Task<IActionResult> Edit2(int commentId, string text) {
Comment comment = _commentRepository.Find(commentId);
var authResult = await _authorizationService.AuthorizeAsync(User, Comment, "EditPolicy");
if (authResult.Succeeded) {
comment.Text = text;
return View();
}
else {
return ForbidResult();
}
}
// GOOD: Only users with the `admin` role can access this method.
[Authorize(Roles="admin")]
public async Task<IActionResult> Edit3(int commentId, string text) {
Comment comment = _commentRepository.Find(commentId);
comment.Text = text;
return View();
}
}
参考¶
OWASP:不安全的直接对象引用。
OWASP:测试不安全的直接对象引用。
Microsoft Learn:ASP.NET Core 中的基于资源的授权。
常见弱点枚举:CWE-639。