BreezeJS SaveChanges()安全问题

时间:2017-09-26 21:25:44

标签: security breeze

我正在使用BreezeJS,并对如何保存数据有疑问。这是我的代码和评论

    [Authorize]
    /*
     * I want to point out the security hole here.  Any Authorized user is able to pass to this method
     * a saveBundle which will be saved to the DB.  This saveBundle can contain anything, for any user,
     * or any table. 
     * 
     * This cannot be stopped at the client level as this method can be called from Postman, curl, or whatever.
     * 
     * The only way I can see to subvert this attack would be to examine the saveBundle and verify
     * no data is being impacted that is not owned or related directly to the calling user.
     * 
     * Brute force could be applied here because SaveResult contains Errors and impacted Entities.
     * 
     */

    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        return _efContext.SaveChanges(saveBundle);
    }

要限制对调用者检索数据的访问权限,我首先从access_token中提取user_id并限制我的所有查询以将其包含在where子句中,这使得用户无法检索其他用户数据。

但是,这不会阻止具有有效access_token的流氓用户在具有增量对象ID的暴力循环中调用SaveChanges()。

我离开这个吗?也许我错过了什么。

感谢您的帮助。

麦克

1 个答案:

答案 0 :(得分:2)

客户端传递给JObject saveBundle方法的SaveChanges是不透明的,难以使用。 Breeze ContextProvider将其转换为实体地图并将其传递给BeforeSaveEntities方法。 BeforeSaveEntities是您在ContextProvider子类或您附加到ContextProvider的委托中实现的方法,例如:

  var cp = new MyContextProvider();
  cp.BeforeSaveEntitiesDelegate += MySaveValidator;

BeforeSaveEntities或委托方法中,您将检查当前用户是否可以保存实体。如果您发现一个不应该保存的实体,您可以将其从更改集中删除,或者抛出错误并中止保存:

protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(
                Dictionary<Type, List<EntityInfo>> saveMap)
{
  var user = GetCurrentUser();
  var entityErrors = new List<EFEntityError>();
  foreach (Type type in saveMap.Keys)
  {
    foreach (EntityInfo entityInfo in saveMap[type])
    {
      if (!UserCanSave(entityInfo, user))
      {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden)
          { ReasonPhrase = "Not authorized to make these changes" });
      }
    }
  }
  return saveMap;
}

您需要确定是否允许用户保存特定实体。这可以基于用户的角色和/或一些其他属性,例如, Sales角色中的用户只能保存属于他们自己的SalesRegion的客户端记录。