通过Load<>?文档嗅探

时间:2013-05-09 11:24:41

标签: c# asp.net-web-api ravendb

我正在使用RavenDb与ASP.NET Web Api,我注意到,可以使用Load<Type>方法查询其他文档。

例如:

public class Person
{
    public string Id { get; set; }
    public string FullName { get; set; }
    /* Other properties */
}

public class Pet
{
    public string Id { get; set; }
    public string FullName { get; set; }
}

[HttpGet]
public Person FindById(string id)
{
    using (IDocumentSession session = _docStore.OpenSession())
    {
        return session.Load<Person>(id);
    }
}

如果我通过web api方法上的ajax调用FindById(“pets / 13”),我会收到带有Pet实体数据的Person对象,因为它们共享公共属性。我怎么能避免这种情况?这可能会将机密数据暴露给攻击者。

即使属性不匹配,也会返回一个具有null属性的对象,从而暴露具有给定id的实体的存在。

我目前的解决方法是:

[HttpGet]
public Person FindById(string id)
{
    using (IDocumentSession session = _docStore.OpenSession())
    {
        return session.Load<Person>("people/" + id.Split('/')[1]);
    }
}

2 个答案:

答案 0 :(得分:1)

ID在文档中是唯一的。不要滥用:你正在调用session.Load&lt; Person&gt ;,但是你传递了一个宠物的ID。不要那样做。

在内部,Raven可能会做这样的事情:

  1. “找到id ='pets / 13'的JSON文档”
  2. 知道了!现在,把那个JSON文档变成......呃......开发人员要求一个人。
  3. 它有点像一个人。返回,因为开发人员告诉我们。
  4. 基本上,你告诉Raven返回一个Person,并且通过将Pet JSON文档转换为Person对象,它尽力而为,这正是你告诉它的。

    如果您担心恶意使用FindById方法,如果ID不是Person对象,则抛出异常:

    [HttpGet]
    public Person FindById(string id)
    {
        // We're concerned someone might call FindById and fish for non-Person objects.
        if (!id.StartsWith("people/"))
        {
            throw new ArgumentException("Naughty!");
        }
    
        using (IDocumentSession session = _docStore.OpenSession())
        {
            return session.Load<Person>(id);
        }
    }
    

答案 1 :(得分:1)

来自http://ravendb.net/kb/3/using-ravendb-in-an-asp-net-mvc-website部分'路线':

  

解决此问题的最简单方法是让您的控制器使用session.Load&lt;&gt;()接受整数的版本。此函数将自动将整数值转换为完全限定的文档ID,然后使用它来执行加载操作。

public ActionResult Read(int id)
{
    var obj = RavenSession.Load<MyClass>(id);
    return View(obj);
}