保护服务器上的Breeze以防止恶意更新外键 问题

保护服务器上的Breeze以防止恶意更新外键 问题,breeze,Breeze,我只是想弄清楚,在Breeze中保存更改时,需要在服务器端实现多少安全性。特别是,我正在考虑恶意用户如何手动破解SaveChanges请求,或破解客户端中的javascript,以绕过我的正常业务规则——例如,恶意更改实体上的外键ID 我想确切地了解我需要把我的安全工作重点放在哪里;我不想浪费时间实现不需要的安全层 我正在服务器端使用Breeze和.net以及实体框架 例子 这里有一个简单的例子ObjectA引用了一个ObjectB,而ObjectA属于特定的用户。因此,我的数据库如下所示: O

我只是想弄清楚,在Breeze中保存更改时,需要在服务器端实现多少安全性。特别是,我正在考虑恶意用户如何手动破解SaveChanges请求,或破解客户端中的javascript,以绕过我的正常业务规则——例如,恶意更改实体上的外键ID

我想确切地了解我需要把我的安全工作重点放在哪里;我不想浪费时间实现不需要的安全层

我正在服务器端使用Breeze和.net以及实体框架

例子 这里有一个简单的例子
ObjectA
引用了一个
ObjectB
,而
ObjectA
属于特定的
用户
。因此,我的数据库如下所示:

ObjectA:

Id    ObjectB_Id    SomeField          User_Id
1     1             Alice's ObjectA    1
2     2             Bob's ObjectA      2

ObjectB:

Id    SomeOtherField
1     Foo
2     Bar

User:

Id    Name
1     Alice
2     Bob
从这个模型中,我考虑的安全问题是:

  • 我不希望未经验证的用户更改任何数据
  • 我不希望Bob能够对Alice的
    ObjectA
  • 我不想让Alice把她
    ObjectA
    指向Bob的
    ObjectB
  • 我不希望Bob试图将其
    ObjectA
    上的
    User\u Id
    更改为Alice
  • (1)的解是平凡的;我将确保我的SaveChanges方法具有
    [Authorize]
    属性

    我可以很容易地使用Fiddler构建一个SaveChanges请求来重现问题2到4——例如,我可以构建一个请求,该请求将Alice的ObjectA更改为指向Bob的ObjectB。这就是消息内容的外观:

    "entities":
    [
        {
            "Id":1,
            "ObjectB_Id":2,
            "SomeField":"Alice's ObjectA",
            "User_Id":1,
            "entityAspect":
            {
                "entityTypeName":"ObjectA:#MyNamespace",
                "defaultResourceName":"ObjectAs",
                "entityState":"Modified",
                "originalValuesMap":
                {
                    "ObjectB_Id":"1"
                },
                "autoGeneratedKey":
                {
                    "propertyName":"Id",
                    "autoGeneratedKeyType":"Identity"
                }
            }
        }
    ],
    
    正如我所期望的,当服务器端没有实现安全性时,这会将
    ObjectB_Id
    的更新值持久化到数据库中

    但是,我还确认,如果
    originalValuesMap
    中没有
    ObjectB\u Id
    的条目,那么即使我更改了消息主体中
    ObjectB\u Id
    的值,它也不会在数据库中更新

    一般规则? 因此,我认为这意味着我需要在服务器上遵循的一般安全规则是:

    [2013年7月4日编辑-为清晰起见重写]

    一般而言:

    • 消息中没有任何内容是可信的:既不是原始值映射中的值,也不是假定的“未更改”值
      • 唯一的例外是实体的标识,我们可以假设它是正确的
      • 假定“未更改”的属性可能已被篡改,即使它们不在原始值映射中
    对于“未更改”属性(不在原始值映射上的属性):

    • 当“使用”任何“未更改”属性时,我们不能使用消息中的值;我们必须从数据库中检索对象并使用其中的值。
      • 例如,当检查对象的owenership以确保允许用户更改它时,我们不能信任消息中的用户标识;我们必须从数据库中检索实体,并使用该实体中的UserId值
    • 对于我们不以任何方式使用的任何其他“未更改”属性,我们不需要担心它是否被篡改,因为即使被篡改,被篡改的值也不会保留到数据库中
    对于更改的属性(也位于原始值映射上的属性):

    • 业务规则可能会阻止更改特定属性。如果是这种情况,我们应该对每个规则进行检查。

    • 如果允许更改某个值,并且该值是外键,我们可能应该执行安全检查,以确保会话标识允许使用新值

    • 我们不能使用原始值映射中的任何原始值,因为这些值可能已被篡改

    [编辑结束]

    执行规则 假设这些规则是正确的,我想有几个选项可以围绕更改的外键实现安全性:

    • 如果业务规则不允许更改特定字段,我将拒绝SaveChanges请求
    • 如果业务规则允许更改特定字段,我将检查是否允许使用新值。执行此操作时,不能使用
      原始值映射
      ;我需要转到数据库(或其他受信任的源,例如会话Cookie)
    将这些规则应用于我上面提到的安全问题

    • 安全问题(2)。我需要对照数据库中当前的
      ObjectA
      上的
      user\u ID
      检查会话中的用户身份。这是因为我不能信任请求中的用户ID,即使它不在
      原始值映射中

    • 安全问题(3)。如果业务规则允许更改
      ObjectB
      ,我需要检查谁拥有
      ObjectB\u Id
      的新值;我将通过从数据库检索指定的ObjectB来实现这一点。如果此
      ObjectB
      不属于
      ObjectA
      的所有者,我可能希望拒绝更改

    • 安全问题(4)。如果业务规则允许更改
      用户
      ,则这已包含在(2)中

    问题 所以,真的,我想确认我的想法是正确的

  • 我的一般规则正确吗?
  • 我对规则的执行听起来合理吗?
  • 我遗漏了什么吗
  • 我把事情复杂化了吗

  • 菲尔。。。你在这里走的绝对正确。您已经很好地阐述了问题、威胁以及缓解这些威胁的一般方法