action=edit&id=lee&name=
파라미터 조작과 잘못된 접근제어 취약점
관리자 페이지와 같이 인가된 특정 사용자만 사용 가능한 페이지에 대해 올바른 접근권한 레벨을 정의하고 점검하는 프로세스가 제대로 적용되지 않은 경우에 발생하는 취약점이다.
네트워크 접근이 가능한 내부/외부 사용자는 모두 공격자가 될 수 있다. 인증을 통해 시스템 접근이 허락된 공격자는 URL이나 파라미터를 조작해 권한(Authorization)이 필요한 기능에 접근할 수 있다. 이 경우 시스템이 인가된 사용자에 대한 접근권한을 제대로 체크하지 않는다면 허가되지 않은 기능을 수행할 수 있게 된다.
애플리케이션의 특정 기능에 대한 접근 권한에 대한 체크가 제대로 이루어지지 않은 경우에 인가되지 않은 기능 접근 및 관리자 기능이 주요 공격 목표가 된다.
발생원인
파라미터나 URL을 조작하여 허가되지 않은 작업 요청을 하는 경우, 공격자가 제공한 정보에 대한 인증이나 인가에 대한 유효성 검증 작업이 서버상에서 수행되지 않는 경우에 취약점이 발생한다.
공격기법
1. 파라미터를 조작하여 리소스에 직접 접근 가능한지 체크
>> 요청에 사용되는 URL, 파라미터 정보 확인
lee 이름으로 사용자 등록 확인
admin 계정으로 lee 정보 삭제
>> 로컬 프록시를 이용한 위조된 요청 전송
test계정으로 로그인후 paros로 파라미터를 "action=edit&id=lee&name=" 로 조작하여 위조된 요청 전송
lee 계정 생성 확인
방어기법
1. 기능별 허가된 사용자인지 확인한 뒤 요청이 수행되도록 코드 수정
TestController.java
// 접근제어
@RequestMapping(value="/test/access_control_test.do", method = RequestMethod.POST)
@ResponseBody
public String testAccessControlPost(HttpServletRequest request,HttpServletResponse response,
HttpSession session){
StringBuffer buffer=new StringBuffer();
MemberModel m=null;
String id=request.getParameter("id");
String name = request.getParameter("name");
String action=request.getParameter("action");
// 사용자정보 조회 요청인 경우 DB에서 해당 사용자 정보를 조회한 결과를 응답
if( "view".equals(action)) {
if( id != null && ! "".equals(id)) {
m=service.findMember(id);
if(m==null) {
buffer.append("등록되지 않은 사용자입니다. ");
} else {
// 조회한 사용자 정보는 세션에 저장
session.setAttribute("member", m);
buffer.append("사용자ID: "+m.getUserId()+"<br/>");
buffer.append("고객명: "+m.getUserName()+"<br/>");
buffer.append("전화번호: "+m.getPinNo()+"<br/>");
buffer.append("가입일자: "+m.getJoinDate()+"<br/>");
}
}else{
buffer.append("userId가 입력되지 않았습니다.");
}
// 실행결과 사용자에 대한 고객 정보 수정
} else if( "modify".equals(action)) {
m=(MemberModel)session.getAttribute("member");
if(m==null) {
buffer.append("사용자정보 조회부터 실행하세요");
} else {
m.setPinNo(name);
service.modifyMember(m);
session.setAttribute("member", m);
buffer.append(m.getUserId()+"님의 고객번호 수정을 완료하였습니다.<br/>");
buffer.append("사용자ID: "+m.getUserId()+"<br/>");
buffer.append("고객명: "+m.getUserName()+"<br/>");
buffer.append("전화번호: "+m.getPinNo()+"<br/>");
buffer.append("가입일자: "+m.getJoinDate()+"<br/>");
}
// 실행결과 사용자에 대한 고객정보 삭제
}else if ( "delete".equals(action)) {
m=(MemberModel)session.getAttribute("member");
if(m==null) {
buffer.append("사용자정보 조회부터 실행하세요");
} else {
service.deleteMember(m);
session.removeAttribute("member");
buffer.append(m.getUserId()+"님의 정보를 삭제하였습니다.");
}
// 새로운 고객 정보 등록
}else if ( "edit".equals(action)) {
if( id != null && ! "".equals(id)) {
m=new MemberModel(0,id,id,name,"","");
int result=service.addMember(m);
if ( result == 3) {
m=service.findMember(id);
if ( m != null) {
session.setAttribute("member", m);
buffer.append(m.getUserId()+" 사용자 등록을 완료하였습니다.<br/>");
buffer.append("사용자ID: "+m.getUserId()+"<br/>");
buffer.append("고객명: "+m.getUserName()+"<br/>");
buffer.append("전화번호: "+m.getPinNo()+"<br/>");
buffer.append("가입일자: "+m.getJoinDate()+"<br/>");
} else {
buffer.append("사용자 등록 실패: "+result);
}
} else {
buffer.append("사용자 등록 실패: "+result);
}
}else {
buffer.append("userId가 입력되지 않았습니다.");
}
}
return buffer.toString();
}
사용자 구분 없이 수신된 action파라미터값에 따라 작업을 수행하도록 구현되어 있어 접근제어 취약점을 가진다.
수정 TestController.java
// 고객정보 삭제 요청 처리
}else if ( "delete".equals(action) && "admin".equals(session.getAttribute("userId"))) {
....
// 새로운 고객 정보 등록 요청 처리
}else if ( "edit".equals(action) && "admin".equals(session.getAttribute("userId"))) {
....
}
admin 계정만 고객등록과 고객삭제를 수행할 수 있도록 취약점 제거
방어결과
test계정에서 파라미터를 조작하여 요청하여도 lee사용자를 등록할 수 없는 것을 확인할 수 있다.
참고: 해킹 방어를 위한 JAVA 시큐어코딩(실무에 바로 적용하는)(개정판 4판) 김영숙
'CS > 시큐어 코딩' 카테고리의 다른 글
[시큐어 코딩] 파일 업로드/다운로드 취약점 (1) | 2024.06.02 |
---|---|
[시큐어 코딩] XSS(크로스 사이트 스크립팅) (0) | 2024.05.26 |
[시큐어 코딩] XPath 삽입(Injection) (0) | 2024.05.26 |
[시큐어 코딩] OS 명령어 삽입(Injection) (0) | 2024.05.24 |
[시큐어코딩] SQL 삽입(Injection) (0) | 2024.05.17 |
댓글