당신은 시종일관 서버측 검증을 실행해야 합니다!영원히!
지난 몇 년 동안 웹 기술은 서버와 클라이언트에서 매우 큰 발전을 이루었다.많은 웹 프레임워크, UI 도구 패키지, 자바스크립트 라이브러리, 웹 사이트나 웹 응용 프로그램을 쉽게 개발하는 데 필요한 모든 것들이 있습니다.JavaScript 라이브러리는 이미 성숙되고 매우 강력해졌으며, 처리 능력은 비록 저급 컴퓨터에서도 현재 대부분의 웹 응용 프로그램에 문제가 되지 않는다.이 때문에 웹 응용 프로그램은 더욱 복잡해지고 사용자 인터페이스는 더욱 화려해지며 프로그래머도 게으르게 변한다.
JavaScript 프레임워크의 강력한 기능으로 인해 많은 사람들이 응용 프로그램의 클라이언트 부분에서 업무 논리를 작성하는 경향이 있다.이것은 사용자에게 계산 작업을 마운트 해제함으로써 서버의 처리 능력을 절약할 수 있고 가능한 경우 강력하게 권장할 수 있지만, 이것은 약간의 안전 문제를 가져올 수 있다.만약 사용자가 폼이나 다른 입력 방법을 통해 서버에 데이터를 제출할 수 있다면, 특히 그렇다.
따라서 서버와 사용자 사이에 클라이언트가 있어도 모든 요청에 대해 서버 측 검증을 실행합니다.세 가지 상황과 수신된 입력이 어떻게 안전 결함을 구성하는지 검증하지 못한 것을 살펴봅시다.그 밖에 문제가 뻔한 것 같지만 항상 그렇지는 않다. 내가 실제 제품에서 본 세 가지 상황의 변화는 모두 진실한 문제이다.
장면1: 사용자 역할 변경을 통해 권한 승급
첫 번째 장면에 대해 우리는 가입 사용자에게 서로 다른 역할을 가진 응용 프로그램을 연구할 것이다.그것은 모든 인터넷 응용 프로그램이 될 수 있지만, 나는 그것이 WordPress와 같은 내용 관리 시스템이라고 생각한다.여기서 사용자는 관리자, 편집자, 공헌자, 일반 사용자와 다른 역할을 할 수 있다.공헌자나 더 높은 등급의 사용자는 다른 사용자의 역할을 변경할 수 있지만, 그는 그보다 더 높은 권한을 부여할 수 없다.예를 들어 편집자는 다른 사람을 관리자로 만들 수 없다.
이를 실현하기 위해 사용자 편집 페이지에는 사용자 정보를 포함하는 폼과 가능한 사용자 역할을 포함하는 하단 목록이 있다.페이지는 템플릿 엔진을 사용하여 보여집니다. (이 예에서 Twirl from Play Framework를 사용합니다.) 받아들일 수 있는 값은 서버에 의해 제공됩니다.우리의 악의적인 사용자는 공헌자이기 때문에 그는 단지 두 가지 역할을 맡을 수 있을 뿐이다.
<select>
@for(role<-acceptableUserRoles) {
<option value="@role.getIdHash()">@role.getName()</option>
}
</select>
현재, 우리 프로그래머는 그가 매우 똑똑하다고 생각하고, 값에 대해, 그는 이를 ID 해시로 현저하게 설정했다.이것은 데이터베이스에 있는 캐릭터 ID의 산열입니다. 응용 프로그램이 매우 복잡하기 때문에 필요하면 새로운 캐릭터를 추가할 수 있습니다.그는 심지어 사용자가 저장할 때 받은 메시지가 유효하고 실제 역할과 대응하는 것을 확보했다.요청을 처리하는 방법은 다음과 같다.public Result saveUserRole(Http.Request request) {
Form<UserInfoDTO> form = formFactory.form(UserInfoDTO.class).bindFromRequest(request);
if (form.hasErrors()) return badRequest();
List<Role> roles = rolesDao.getRoles();
Role submitedRole = null;
for (Role role:roles) {
if (role.getIdHash() == form.get().role()) {
submitedRole = role;
break;
}
}
if (role == null) return badRequest();
UserDO user = userDao.find(form.get().userId());
if (user == null) return notFound();
user.setRole(role);
userDao.update(user);
return ok();
}
언뜻 보니 모든 것이 다 좋은 것 같다.폼이 검증되고 캐릭터가 검증되며 사용자가 데이터베이스에서 요청됩니다. 우리는 심지어 CSFR 영패가 악의적인 제출을 방지할 수 있다고 가정합니다.너는 문제를 발견할 수 있니?서버는 사용자 인터페이스 코드가 서버에서 생성되기 때문에 받은 역할은 사용자가 제공할 권리가 있는 역할 중의 하나라고 가정한다.귀속할 캐릭터가 현재 사용자의 캐릭터보다 높은지 확인하지 않았습니다.우리의 악성 사용자는 브라우저에서 inspector를 열고 HTML을 편집하기만 하면 브라우저에 새 값을 추가할 수 있습니다
그래, 그는 반드시 산열을 알아야 하지만, 만약 다른 보호 메커니즘이 제대로 갖추어지지 않는다면, 그는 그것을 강제로 사용할 수 있다. 왜냐하면 그는 격식을 알고 있기 때문이다.만약 이것이 기본값이고 설치할 때마다 무작위로 생성되지 않는다면, 작업은 더욱 쉽다. 왜냐하면 사용자는 자신의 컴퓨터에 가상 프로그램을 설치하고 이런 방식으로 산열을 찾을 수 있기 때문이다.
시나리오 2: URL 파악/추측을 통해 기밀 페이지에 액세스
또 다른 흔히 볼 수 있는 오류는 사용자가 페이지에 접근할 수 있는지 확인하지 못했다는 것이다.이 방면에는 여러 가지 변체가 있다. 특정 역할이 특정한 페이지를 방문할 수 있는지 검증할 수 없거나 페이지의 가시성을 검증할 수 없다.우리는 이곳에서 이 두 가지 상황을 연구할 것이다.
이번에 우리는 한 회사의 프레젠테이션 사이트를 처리할 것이다. 그들은 곧 신제품을 내놓을 것이다.편집자들은 필요한 자료를 작성하고 신제품 페이지를 준비하며 며칠 후에 제품이 발표될 때까지 기다렸다.신제품 페이지의 최종 URL을 포함하여 모든 것이 준비되었습니다. 왜냐하면 그것은 반드시 사전에 뉴스 매체에 보내야 하기 때문입니다.
최초의 뉴스 원고에는 이런 회사가 하나도 없었지만, 유명 회사였고, 신제품에 대한 소문이 있었기 때문에 그들은 모든 재미있는 정보를 원했다.그래서 그들은 신제품 페이지의 URL을 추측하기 시작했다.그들은 제품의 이름을 알고 통과된 제품에 따라 새 페이지의 URL이 어떻게 생겼는지 알 수 있다.CMS는 한 문장이 실제로 발표되었는지 검증할 수 없기 때문에 URL을 방문하면 뉴스 매체는 그들이 필요로 하는 모든 정보를 얻을 수 있고 다른 뉴스 사이트보다 더 빨리 자유롭게 이 정보를 발표할 수 있다.
복잡한 시스템에서도 이런 변화가 발생할 수 있다.만약 사용자가 적당한 역할이 없다면 사이트의 일부 기능이나 페이지를 방문할 수 없는 경우는 적지 않다.개발자는 각 사용자에게 표시되는 페이지 목록을 만들고 이 목록과 현재 로그인한 사용자를 바탕으로 HTML 파일에 메뉴를 구성합니다.이것은 첫 번째 장면의 select 폼과 유사한 방식으로 완성된 것이다.개발자가 UI에서 메뉴 항목을 클릭해서만 사용자가 탐색할 수 있다고 판단되면 서버측 유효성 검사를 감독할 수 있습니다.이렇게 하면 사용자는 정확한 URL을 입력하기만 하면 방문하지 말아야 할 페이지에 접근할 수 있다.이것은 아직 성숙하지 않거나 개발 중인 웹 응용 프로그램에서 자주 발생하는 문제이지만, 이미 공공 버전이 발표되었다.
다시 한 번 예를 들면, 너는 Why you should always do server-side validation에서 나의 오리지널 문장을 읽을 수 있다
Reference
이 문제에 관하여(당신은 시종일관 서버측 검증을 실행해야 합니다!영원히!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pazvanti/you-should-always-do-server-side-validation-always-46gf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)