2009-10-01 1 views
5

나는 캘린더와 유사한 ASP.NET MVC 애플리케이션을 가지고있다. NerdDinner 예제에 따라 UpdateMethod()를 사용하여 편집 페이지의 결과를 업데이트합니다.ASP.NET MVC UpdateModel이 해킹에 취약합니까?

내 앱에서 특정 이벤트는 완벽하게 사용자 정의 가능하며 특정 이벤트는 부분적으로 만 사용자 정의 할 수 있습니다. 부분적으로 사용자 정의 가능한 이벤트를 편집하기위한 편집 양식은 해당 필드 만 사용할 수 있지만 분명히 누락 된 데이터로 자신의 양식을 만들고 내 사이트에 게시 할 수 있습니다. 그렇다면 누군가가 어떤/모든 분야를 변경하지 못하게해야합니까? 더 나쁜 경우, id (기본 키)를 변경하려고하면 어떻게 될까요?

UpdateModel()은 매우 기본적인 해킹에 취약합니다. 내 두려움이 합법적인가요, 아니면 제가 빠진 것이 있습니까?

// POST: /MyEvents/Edit/2 
[AcceptVerbs(HttpVerbs.Post), Authorize] 
public ActionResult Edit(int id, FormCollection formValues) 
{ 
    MyEvent myevent = eventRepository.GetMyEvent(id); 

    try 
    { 
     UpdateModel(myevent); 
     eventRepository.Save(); 
     return RedirectToAction("Details", new { id = myevent.MyEventId }); 
    } 
    catch 
    { 
     ModelState.AddRuleViolations(myevent.GetRuleViolations()); 
     return View(new MyEventFormViewModel(myevent)); 
    } 
} 
+0

쉽고 안전 모드 = 양식 (in) 모델을 만든 다음 Automapper를 통해 해당 모델을 귀하의 엔티티에 매핑하십시오. – mxmissile

답변

9

"모델 바인딩 보안"섹션이 누락되었습니다. 사용자 입력 방법으로 업데이트 할 수있는 속성의 화이트리스트를 항상 포함해야합니다. NerdDinner에서 예를 들어

:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Include="Title, Address")] Dinner dinner) 
{ 

} 

을하거나 UpdateModel를 호출하는 경우, 허용 된 속성의 문자열 배열을 생성하고, 할 수있는

UpdateModel(myObject, allowedProperties); 

당신은 클래스를 잠글 수 있습니다 따라서 특정 속성 만 업데이트 할 수 있습니다.

[Bind(Include="MyProp1,MyProp2,MyProp3")] 
public partial class MyEntity { } 
+0

데이터 입력 화면에 20 또는 30 개의 요소가있을 때까지는 고통이됩니다.) –

+2

블랙리스트를 사용할 수도 있습니다 :) – womp

7

두려움이 옳습니다. 이것을 질량 할당이라고합니다. 수업을 BindAttribute으로 표시하고 Exclude/Include 속성으로 설정하여 코드를 보호 할 수 있습니다.

1

UpdateModel의 오버로드는 업데이트 할 문자열 명명 속성의 배열을 사용합니다. 이러한 오버로드는 명명 된 속성 만 업데이트합니다.

MVC 데이터 바인딩에 대한 전문가가 아니기 때문에 더 쉽고 선언적 방법으로이를 수행 할 수 있습니다.

1

업데이트로 무시해야하는 모델의 필드를 표시하거나 다른 UpdateModel 오버로드 중 하나를 사용하여 포함/제외 필드 목록을 전달할 수 있습니다.

4

진취적인/악의적 인 사람이 필드를 모델의 모든 속성에 매핑하는 것이 완벽하게 가능합니다. 여기에 몇 가지 방법이 있습니다.

가장 간단한 방법은 앞서 언급 한 UpdateModel의 exclude/include 속성 오버로드를 사용하는 것입니다. 이 단점은 메서드가 문자열 배열을 받아들이는데, 이는 문자열의 배열을 받아들이는데, 이는 이름을 바꿀 때 코드가 동기화되지 않을 수도 있음을 의미 할 수 있습니다.

또 다른 방법은 바인딩 된 필드를 보유하고있는 간단한 DTO를 사용하는 것입니다. 그러면 DTO를 가져 와서 이벤트 객체로 원하는대로 처리 할 수 ​​있습니다. 이것은 분명히 다른 클래스를 추가하고 훨씬 더 수동이지만 더 많은 것을 제공합니다. 컨트롤

또 다른 방법은 원하는 필드 만 바인딩하는 MyEvent 클래스의 고객 모델 바인더를 사용하는 것입니다. 아마도 과장 될 수 있습니다.