2017-09-26 10 views
0

BreezeJS를 사용하고 있으며 데이터 저장 방법과 관련하여 질문이 있습니다. 여기 내 코드는 다음과 사용자를 위해 다소 불가능하고, 내가 먼저 access_token과 USER_ID에서 추출 된 데이터를 검색하고 where 절에서이 포함 내 모든 쿼리를 제한하는 호출자의 기능에 대한 액세스를 제한하기 위해BreezeJS SaveChanges() 보안 문제

[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을 가진 불법 사용자가 증분 객체 ID가있는 무차별 대입 루프에서 SaveChanges()를 호출하는 것을 막지는 못합니다.

나는 이것에 관해 떨어져 있냐? 어쩌면 내가 뭔가를 놓친 것 같아.

도움 주셔서 감사합니다.

마이크

+0

breeze에 익숙하지 않지만 올바른 액세스 제어를 구현하는 것처럼 들릴 수 있습니다. 또한 객체 ID 생성시 암호화 임의성을 사용하는 것이 좋지만 실제로는 적절한 액세스 제어를 구현하는 것보다 우선적입니다. SaveChanges()와 관련하여 사용자가 수행 할 수있는 저장 작업의 수를 제한하고 싶지 않을 수도 있습니다. 그렇지 않으면 DB를 정크로 채울 수 있습니다. – TheGreatContini

답변

2

SaveChanges 방법은 불투명하고 사용하기 어려운에 클라이언트가 전달하는 JObject saveBundle. Breeze ContextProvider은 엔티티의지도로 변환하고 BeforeSaveEntities 메소드로 전달합니다. 당신의 BeforeSaveEntities 또는 위임 방법에

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

, 당신은 실체가 저장 될 수 있는지 확인합니다 : BeforeSaveEntities 당신이 당신의 ContextProvider 서브 클래스에 구현하는 것, 또는 당신이 ContextProvider에 연결 대리인, 예를 들면 방법이다 현재 사용자가 당신은 저장되지해야 엔티티를 발견하면, 당신은 변경 세트에서 제거하거나, 오류가 발생하고 중단 할 수 있습니다 저장 :

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에 속한 Client 레코드 만 저장할 수 있습니다.

+0

감사합니다. 이것은 정확하게 내가 알아야 할 필요가있는 것입니다. 도움에 감사드립니다! – Mike