# WebGoat URL로 HTTP 요청을 보내는 명령어
$ curl -v http://victim:8080/WebGoat
상호 합의 하에 연결을 하고, 4whs을 통해 연결을 종료한다.
# WebGoat URL로 HTTP 요청을 보내는 명령어
$ curl -v http://victim:8080/WebGoat
# WebGoat URL로 HTTP 요청을 보내는 명령어
# Basic 인증을 사용하여 WebGoat 리소스 정보를 요청
$ curl -v http://victim:8080/WebGoat/ -H "Authorization: basic d2ViZ29hdDp3ZWJnb2F0"
WWW-Authenticate: Basic realm="WebGoat Application"
secure
속성 활성화secure
속성이란? 보안 통신을 할 때만 쿠키 전달하도록 제한HttpOnly
속성 설정HttpOnly
속성이란? 클라이언트에서 쿠키에 JavaScript나 개발자 도구를 이용해 직접 접근을 제한하는 것<Context>
태그에 useHttpOnly="false"
를 추가해줘야 한다. HttpOnly 속성이 true면 클라이언트에서 접근 시 " "
만 나온다.로그인한 브라우저의 쿠키값을 추출해서 로그인하지 않은 브라우저에 설정 후 새로고침 ⇒ 서버는 세션 ID를 이용해서 사용자를 식별하는데, 세션 ID가 포함되어 있는 쿠키를 탈취 당하게 되면, 서버를 속여서 접근이 가능하게 됨
WebGoat > Access Control Flaws > LAB:Role Based Access Control
Employee Tom으로 Staff Listing Page에서 Tom의 프로필 삭제하기
Tom(pw : tom) 로그인한 경우
Jerry(pw: jerry) 로그인한 경우
ViewProfile > Tom employee_id=106 확인
SearchStaff 클릭 후 패킷 Intercept
employee_id, action을 변경
요청한 사용자의 권한 여부를 체크하는 로직을 추가하기
RoleBasedAccessContol.java
public void handleRequest(WebSession s)
{
// Here is where dispatching to the various action handlers happens.
// It would be a good place verify authorization to use an action.
// System.out.println("RoleBasedAccessControl.handleRequest()");
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{
// action 요청 파라미터 값을 추출
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
// System.out.println("Requested lesson action: " + requestedActionName);
try
{
DefaultLessonAction action = (DefaultLessonAction) getAction(requestedActionName);
if (action != null)
{
// System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " +
// action.getActionName());
if (!action.requiresAuthentication())
{
// Access to Login does not require authentication.
action.handleRequest(s);
}
else
{
// ***************CODE HERE*************************
// *************************************************
// 인증 여부 확인
if (action.isAuthenticated(s))
{
// 요청 처리
action.handleRequest(s);
}
else
// 인증 오류 반환
throw new UnauthenticatedException();
}
}
...(생략)...
요청한 사용자의 권한 여부를 확인하지 않고, 인증 여부만 확인하고 요청을 처리하고 있다는 것을 확인할 수 있다.
//
public void handleRequest(WebSession s)
{
// Here is where dispatching to the various action handlers happens.
// It would be a good place verify authorization to use an action.
// System.out.println("RoleBasedAccessControl.handleRequest()");
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
// System.out.println("Requested lesson action: " + requestedActionName);
try
{
DefaultLessonAction action = (DefaultLessonAction) getAction(requestedActionName);
if (action != null)
{
// System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " +
// action.getActionName());
if (!action.requiresAuthentication())
{
// Access to Login does not require authentication.
action.handleRequest(s);
}
else
{
// ***************CODE HERE*************************
// *************************************************
/* 기존 코드 주석처리
if (action.isAuthenticated(s))
{
action.handleRequest(s);
}
else
throw new UnauthenticatedException();
*/
// ********************추가*******************
// 요청 사용자의 인증 여부를 확인
if (action.isAuthenticated(s)) {
// 요청 사용자의 요청 권한 여부를 확인
// isAuthorized(WebSession s, int employeeId, String functionId)
if (action.isAuthorized(s, action.getUserId(s), action.getActionName())) {
action.handleRequest(s);
} else {
// 권한 오류
throw new UnauthorizedException();
}
} else {
// 인증 오류
throw new UnauthenticatedException();
}
}
}
else
setCurrentAction(s, ERROR_ACTION);
// ****************************************
코드 수정 후 Stage 2에서 Stage 1과 동일하게 실습 진행 시 DeleteProfile 요청이 처리되지 않는 것을 확인할 수 있다.
Tom으로 다른 직원의 프로필 조회하기
Stage 4로 이동되어야 한다.
예상 쿼리
SELECT * FROM employee WHERE employee_id=사원번호
😨 유일키만으로 데이터를 조회하는 경우 파라미터를 조작하면 목록에 나오지 않는 데이터의 열람이 가능해진다.
그렇기 때문에 목록 조회 기능을 구현할 때는 다양한 조건절을 추가해야한다.
상세 조회 기능 구현 시 목록 조회에서 적용한 조건과 레코드를 선택하기 위한 조건을 함께 사용해야 한다.
기존에는 hr 소속이 아니었어도 employee_id만 변경하면 프로필 조회가 가능했었다.
hr 소속이 아니면 프로필 조회를 못하게 소스코드 변경하기
WebGoat/src/main/java/org/owasp/webgoat/lessons/RoleBasedAccessControl/ViewProfile.java
ViewProfile.java
현재 로그인한 직원 ID와 조회 대상 직원 ID를 확인하는 코드로 변경