250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- poi
- 그리드
- apache.poi
- Javascript
- Jenkins
- 엑셀 업로드
- mssql
- Stream
- 자바8
- stream api
- ORM
- JQuery
- ci/cd
- 스트림
- docker
- jqGrid
- QueryDSL
- 제이쿼리그리드
- sqlserver
- 자동빌드
- spring
- 대용량 업로드
- rabbitmq
- 자동배포
- 보안
- JPA
- java
- mom
- DevOps
- MessageQueue
Archives
- Today
- Total
개발 메모장
[보안] Ajax 요청에 대한 응답값 변조, 프록시 조작 및 우회 방지 본문
728x90
- 문자 인증 및 암호 인증 등을 통해 민감 정보를 수정 및 조회하는 경우가 많을 것 입니다.
- 잘못된 접근 제어 방식으로 인하여 인증 우회 및 공격을 받기도 합니다.
- 잘못된 방식에 대해서 살펴보고 어떻게 처리해야하는지도 알아보도록 하겠습니다.
#. 현 상황
- 입력받은 PW 및 데이터를 Ajax를 통해 서버단으로 보낸 뒤 유효성 검사를 하고 통과가 되면 check라는 Key에 Y라는 값을 넣어 modelMap을 통해 리턴합니다. 통과되지 못할 경우 N을 넣어 리턴합니다.
- ajax의 success 옵션에서 리턴 받은 데이터의 check라는 키의 값이 Y이면 성공처리 후 팝업을 열고, 아니면 실패처리를 하는 방식으로 되어있습니다.
@RequestMapping("/PwCheck.do")
public ModelMap pwCheck(@RequestParam Map<String, Object> param, ModelMap modelMap) {
String pw = service.pwCheck(param);
String paramPw = param.get("password").toString();
String passSecurity = SHA2.encrypt(paramPw);
passSecurity = SHA2.getSHA512(passSecurity);
if(pw != null && pw.equals(passSecurity) ){
return modelMap.addAttribute("check", "Y");
} else {
return modelMap.addAttribute("check", "N");
}
}
$("#test").on("click", ".btnSave", function(event) {
$.getJSON("/PwCheck.do", $("#test form").serialize(), function(returnData, textStatus){
if(textStatus == "success"){
if(returnData.check =="Y"){
$("#testPopup").popup({
loadUrl: "modify.do?UserNo=${user.id}",
follow: [false, false],
position: ["auto", "200"]
, escClose: false
});
return false;
} else {
alert("비밀번호가 일치하지 않습니다.");
}
}
}).error(alertErrorHandler);
return false;
});
728x90
#. 프록시 변조 테스트
- 위와 같은 로직이 적용된 기능을 대상으로 테스트해보도록 하겠습니다.
- 프록시 변조를 위해 Burp Suite을 설치하여 사용하였습니다.
- 상단 탭의 Proxy로 이동하여 Open browser로 크로미움을 열어줍니다.
- 프록시 변조를 위한 인터셉트가 필요한 구간에선 Intercept is on으로 켜줍니다.

- 암호를 변경하는 팝업을 열기 전 기존 암호를 입력하는 입력창입니다.
- Intercept is on 상태에서 입력창에 1234를 입력 후 확인을 누릅니다.

- 아래와 같이 인터셉트 되어 정보를 볼 수 있게 됩니다.

- 보내야하는 URI를 확인 한 뒤 우클릭 하여 Do Intercept Response to this Request를 눌러줍니다.

- 그 후 Forward를 해주면 이전 Request에 대한 Response 값을 인터셉트 할 수 있습니다.
- 입력한 1234는 당연히 틀린 비밀번호이기 때문에 N으로 response 받습니다.

- 하지만 N을 Y로 바꿀 수 있으며 이로 인해 우회가 가능하게 됩니다.
- 수정 후 Forward를 해주어 기능을 종료합니다.

- 개인정보 및 암호를 수정할 수 있는 팝업을 정상적으로 띄우는 모습입니다.

#. 처리방법
- 단순히 생각하면 Ajax 요청 및 서버단에서 modelMap을 만들고 받지 않으면 됩니다.
- 리턴 타입을 변경하여 아래와 같이 처리하였습니다.
- ResponseEntity를 이용해 리턴하고 HTTP 상태값을 이용하여 리턴 받은 후 처리를 해주었습니다.
public ResponseEntity<?> pwCheck(@RequestParam Map<String, Object> param, HttpSession session) {
String pw = userInfoService.pwCheck(param);
String paramPw = param.get("password").toString();
String passSecurity = SHA2.encrypt(paramPw);
passSecurity = SHA2.getSHA512(passSecurity);
if(pw != null && pw.equals(passSecurity) ){
session.setAttribute("authenticated", true);
return new ResponseEntity(null, HttpStatus.OK);
} else {
return new ResponseEntity(null, HttpStatus.UNAUTHORIZED);
}
}
$("#test").on("click", ".btnSave", function (event) {
event.preventDefault();
const formData = $("#test form").serialize();
$.ajax({
type: "GET",
url: "/PwCheck.do",
data: formData,
dataType: "json",
success: function (response) {
$("#testPopup").popup({
loadUrl: "modify.do?UserNo=${user.id}",
follow: [false, false],
position: ["auto", "200"],
escClose: false,
});
},
error: function (xhr) {
if (xhr.status === 401) {
alert("비밀번호가 일치하지 않습니다.");
} else {
alert("에러 발생");
}
},
});
});
#. 수정 후 테스트
- 위와 같이 수정한 후 동일하게 프록시 변조를 위해 인터셉트 하면 아래와 같이 나타나게 됩니다.

- ModelMap에 담은 키값이 없으므로 나오질 않으며, 그렇기에 변조할 값도 없어 우회가 불가하게 됩니다.
- 위 내용은 modelMap에 성공/실패값을 리턴하는 모든 메서드에서 뚫릴 수 있으니 찾아서 모두 변경해주어야 합니다.
- 오래 전부터 사용하고 있던 소스이다보니 보안에 취약한 부분이 많이 있습니다.
- 하나하나 전부 보기엔 여러가지로 한계가 있다보니 틈틈이 찾아보고 테스트해보고 개선될 수 있도록 해야할 것 같습니다.
===========================================================
틀린 내용이 있거나 이견 있으시면 언제든 가감 없이 말씀 부탁드립니다!
===========================================================
728x90
'보안' 카테고리의 다른 글
[CDN] cdn.jsdelivr.net SSL 만료(부트스트랩 오류) (0) | 2024.05.03 |
---|---|
[보안] Jasypt를 이용한 민감정보 암호화 (0) | 2024.03.12 |
[보안] Replay Attack 정의 및 대응 (0) | 2024.01.16 |
[보안] 시큐어 코딩이란? (1) | 2023.12.18 |
[보안] 파일 업로드 시 취약점 사전 대응 방법(Java, Windows) (1) | 2023.11.30 |