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 |
Tags
- spring dynamic query sql injection
- ec2 scp 파일 전송
- 개발 포지션 변경
- android 타이머
- spring exceptionHandler response cause
- 운영체제 멀티 태스킹
- spring responseEntity response stackTrace
- 운영체제 멀티 프로그래밍
- IT 직무 변경
- 백엔드 포지션 변경
- 운영체제 커널모드
- IT 포지션 변경
- Android Timer
- 개발 직무 변경
- spring exception cause remove
- 운영체제 작동방식
- 운영체제 다중모드
- OS 자원관리
- 운영체제 공룡책
- 백엔드 직무 변경
- spring sql injection
- spring 동적 쿼리 주의사항
- spring paging sort sql injection
- spring responseEntity response cause
- aws ec2 scp 파일 전송
- spring sql injection 방지
- 운영체제 개념
- spring exception stackTrace remove
- spring exceptionHandler reposnse stackTrace
- 운영체제 자원관리
Archives
- Today
- Total
오늘도 삽질중
spring SQL injection 방지 (with. paging sort dynamic query) 본문
반응형
프로젝트에서 동적으로 쿼리를 처리하는 API 에서 SQL Injection이 발생하는 취약점이 확인됬다.
발생 위치는 페이징 처리 API 에서 파라미터로 sort 를 넘겨주는 부분에 임의의 쿼리를 삽입 할 경우 그대로 실행되었다.
직접 테스트해보니 DB 자체에 sleep 을 걸수도 있고, 잘하면 삭제 및 데이터 추가도 가능하다고 판단되었다.
우선 해당 프로젝트는 아래처럼 구조가 되어있다.
getOrderByProperty 는 아래처럼 구성되어 있다.
protected OrderSpecifier<?>[] getOrderByProperty(Sort sort, Class clazz){
return sort.stream().map(x -> {
//문제가 되는 부분
String property = x.getProperty();
Sort.Direction direction = x.getDirection();
boolean isAscending = direction.isAscending();
Order order = isAscending ? Order.ASC : Order.DESC;
if(....)
else if(....)
....
....
....
//동적으로 처리되는 부분
SimplePath<?> filedPath = Expressions.path(clazz, property);
return new OrderSpecifier(order, filedPath, nullHandling);
}).toArray(OrderSpecifier[]::new);
}
첫번째 해결방법으로 각 API 마다 조건에 맞는 별도의 OrderSpecifier 함수를 구현하여 임의의 값이 들어오더라도 동적으로 처리되는게 아니라 Throw 또는 기본 리턴값을 매핑해준다.
사실 이 방법이 가장 깔끔하긴 하지만 시간상의 제약과 고칠 경우 전수 테스트 및 사이드 이펙트를 고려하여 차후 진행하기로 협의하였고,
기존에 쓰고 있는 getOrderByProperty() 함수를 수정하여 SQL Injection 을 방어하는 것으로 진행했다.
우선 문제가 되는 부분은 property 부분이였다. (위 소스 참조)
직접 임의의 DB 명령어를 sort 파라미터에 삽입 후 로그를 찍어보니 그대로 명령문이 출력되고 실행되었다.
그래서 property 에 해당하는 부분에 의도하지 않은 특수문자 및 DB 관련 실행문이 들어갈 경우 Throw 처리를 하도록 수정하였다.
//property 에 의도하지 않은 특수문자 및 DB관련 명령어가 들어가는지 검사한다.
protected boolean isValidProperty(String property){
Pattern specialPattern = Pattern.compile("[`\"\\-#()@;=*/+]");
boolean isFindSpecial = specialPattern.matcher(property).find();
if (isFindSpecial) {
return false;
}
String regex = "(union|select|from|where|null|nulls)";
Pattern stringPattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
boolean isFindString = stringPattern.matcher(property).find();
if (isFindString) {
return false;
}
return true;
}
//property 유효성 검증 추가
protected OrderSpecifier<?>[] getOrderByProperty(Sort sort, Class clazz){
return sort.stream().map(x -> {
//문제가 되는 부분
String property = x.getProperty();
//property 가 유효하지 않으면 Throw 처리
if (!isValidProperty(property)){
throw new BadRequestException(ExceptionMessage.BAD_REQUEST);
}
Sort.Direction direction = x.getDirection();
boolean isAscending = direction.isAscending();
Order order = isAscending ? Order.ASC : Order.DESC;
if(....)
else if(....)
....
....
....
//동적으로 처리되는 부분
SimplePath<?> filedPath = Expressions.path(clazz, property);
return new OrderSpecifier(order, filedPath, nullHandling);
}).toArray(OrderSpecifier[]::new);
}
반응형
'스프링' 카테고리의 다른 글
spring ExceptionHandler Response remove stackTrace, cause (0) | 2023.09.10 |
---|
Comments