본문 바로가기

포트폴리오 개발일지

2024-06-13 검색어 공백 제한하기 1

현재 문제점

1. 공백 검색 및 sql 인젝션에 취약함

해결해보기

현재 사용자가 입력하지 못하도록 해야 하는것이 무엇인지 생각해봤다.
1. null
2. ""
3. " "
위 세가지가 가장 기본적인게 아닐까 한다.

필터를 구현하거나, 바인딩 과정에서 하나씩 체크하는 방법도 있을것 같은데 지금 hibernate 라이브러리를 사용하고 있기 때문에 어노테이션을 사용해서 해보려 한다.


어노테이션 중 관련있는걸 세가지 찾았는데

어노테이션 설명
@NotNull Null 불가능
@NotEmpty Null , 빈 문자열 불가능
@NotBlank Null, 빈 문자열, 공백만 있는 문자열 불가능

이 중에서 Null, 빈 문자열, 공백만 있는 문자열은 검색에 전혀 필요가 없기 때문에 @NotBlank를 사용하기로 했다.

SearchDTO를 수정했다.


@Data  
@ToString  
@Builder  
@NoArgsConstructor  
@AllArgsConstructor  
public class SearchDTO {  

    private List types;  

    @NotBlank  
    private String keyword;  

    public boolean checkType(String type) {  
        if(types != null) {  
            for (int i = 0; i < types.size(); i++) {  
                if (types.get(i).equals(type)) {  
                    return true;  
                }  
            }  
        }  
        return false;  
    }  
  }

그리고 바로 톰캣을 실행해서 keyword 값을 공백으로 하고 list요청을 했는데 전체 리스트가 전부 나왔다. 뭔가 이상해서 고민해봤는데 너무 어노테이션에만 집중해서 BindingResult 처리를 깜빡하고 바로 테스트 했던 것이었다..

컨트롤러도 수정해주었다.

@GetMapping("/list")  
public String list(@Valid SearchDTO searchDTO, BindingResult bindingResult, Model model) {  

log.info("노트 컨트롤러 list(검색 테스트용) 호출");  
log.info(searchDTO);  

if(bindingResult.hasErrors()) {  
    log.info(bindingResult.getAllErrors());  
    return "redirect:/";  
}  
model.addAttribute("searchDTO", searchDTO);  
model.addAttribute("dtoList", noteService.getSearchList(searchDTO));  

return "/note/list";  

}




우선 반환형을 String으로 바꿔주고 매개변수로 BindingResult추가,정상적으로 작동하는지 확인을 위해 우선은 keyword가 null,""," " 일 경우 localhost:8080/ 으로 return 될수 있도록 수정했다.


톰캣 실행후 localhost:8080/note/list를 요청하여 바로 localhost:8080으로 리다이렉트 되는걸 확인했다.


우선 valid가 잘 작동되는건 확인 했으나, 검색이 아닌 list 의 첫 호출도 keyword의 값이 없어 바로 리다이렉트가 되는 부분을 수정 해야한다.

막상 수정하려고 이리저리 생각해보니 고민이 많아졌다.


현재 프로젝트의 상황이

  1. @NotBlank로 검색어를 값으로 가지는 SearchDTO의 변수 keyword의 유효성을 검사하려 함
  2. notes table의 전체 데이터 확인 가능한 getList() 있음(getSearchList()로 인해 지금은 사용 안함)
  3. SearchDTO(검색 조건, 검색어)를 매개변수로 받는 getSearchList() 있음
    1. mybatis로 구현 <where>를 사용해서 SearchDTO의 types에 값이 없으면 전체 조회를 함

BindingResult의 결과에 따라 에러가 있으면(keyword가 없으면) getList()를 실행하고, 없으면 getSearchList()를 실행하면 간단하게 해결될것 같았는데 그러면 getSearchList() 메소드 한개로 검색어가 있을때, 없을때를 모두 처리하기 위해 사용한 <where>를 사용한 의미가 없어진다


각 방법의 중요도나 목적등을 다시 한번 알아보면서 어떤 과정으로 검색 기능을 완성해 갈지 깊게 고민해봐야 할것 같다.


포트폴리오의 진도가 좀 걱정되지만 지금 과정을 내가 납득할수 있는 이유로 해결하고 넘어가는게 더 중요한것 같다.