CodeQL 文档

不安全的直接对象引用

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

点击查看 CodeQL 存储库中的查询

可以通过操作方法访问和修改评论或用户个人资料等资源。为了定位到某个资源,操作方法接受一个指向该特定资源的 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();
    }
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私