Project

sung eon·2022년 7월 25일
0

미니프로젝트

목록 보기
17/21

피드백 후 개선 사항

우리 팀은 오늘 스크럼을 통해 받은 피드백을 정리해봤다. 정말 우리의 예상에서 한참 벗어난 에러들이 많아서 그 부분을 조금 더 집중적으로 봤다.
일단 우리는 피드백을 나열한 후, 보안과 관련된 급한것과 추가로 개발될 기능, 그리고 지금 당장 고치기 쉬운것 으로 정리했다.
그리고 보안과 관련된 급한 부분 먼저 처리하고 쉬운거, 그리고 내일부터 추가 기능을 시작하기로 했다!

  • xss 보완
  • File 확장자 필터
  • Enter 이벤트 추가
  • a 태그 새창으로 열기

XSS 보안

누군가 우리 프로젝트에 계속 alert창을 띄웠다!! 정말 열받았는데 그 상황을 예상못하고 개발 못한 내 탓하며 팀원들과 같이 하나씩 고치기로! A-1팀 팀장님인 철진님이 도와주셨는데, 우리팀이 금요일부터 헤맨거치고는 아주 명쾌한 방법이었다! 우리가 너무 어렵게 생각했던걸까? 여튼, 아침이라 졸리셨을 텐데 기꺼이 도와주러 오셔서 명쾌하게 도와주고 가신 철진님께 감사를 : )

| build.gradle

implementation 'com.navercorp.lucy:lucy-xss:1.6.3'

먼저 우리는 gradle을 사용하므로 build.gradle 에 위와 같은 의존성을 추가해줬다.

그 후, 텍스트로 값을 받는 부분에 XssPreventer.escape()를 통해 받아주기로 했다.

| MemberService.java

member.updateNickname(memberUpdateRequestDto.getNickname());
member.updateGithubUrl(memberUpdateRequestDto.getGithubUrl());
member.updatePortfolioUrl(memberUpdateRequestDto.getPortfolioUrl());
member.updateIntroduction(memberUpdateRequestDto.getIntroduction());

원래 그냥 Dto통해 받아 오던 부분을 XssPreventer.escape()로 감싸준 것을 볼 수 있다.

member.updateNickname(XssPreventer.escape(memberUpdateRequestDto.getNickname()));
member.updateGithubUrl(XssPreventer.escape(memberUpdateRequestDto.getGithubUrl()));
member.updatePortfolioUrl(XssPreventer.escape(memberUpdateRequestDto.getPortfolioUrl()));
member.updateIntroduction(XssPreventer.escape(memberUpdateRequestDto.getIntroduction()));

File 확장자 필터

처음에는 프론트 단에서도 해줬었다! accept="image/*" 속성을 사용했는데, 이 때
사진 선택 시 모든 파일보기로 아무 확장자나 선택해도 수정이 잘 되었다 ㅠㅠ 그래서 백엔드단에서도 처리를 해줘야 한다는걸 깨달았다

| profile.hbs

<input type="file" class="custom-file-input" name="image" accept="image/*">

그래서 백엔드 단에서도 필터를 추가를 해주기로 했다.

| build.gradle

implementation group: 'org.apache.tika', name: 'tika-core', version: '1.24'

apache.tika에 대한 의존성을 추가해주고,
나는 util이라는 pakage를 만들어서 그 안에 아래 링크로 걸어둔 내용을 참고하여 FileUtils라는 class 파일을 만들고 거기다 확장자 체크 기능을 만들어주었다.

| FileUtils.java

import org.apache.tika.Tika;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

public class FileUtils {

    private static final Tika tika = new Tika();

    public static boolean validImgFile(InputStream inputStream) {
        try {
            List<String> notValidTypeList = Arrays.asList("image/jpeg", "image/pjpeg", "image/png", "image/gif", "image/bmp", "image/x-windows-bmp");

            String mimeType = tika.detect(inputStream);
            System.out.println("MimeType : " + mimeType);

            boolean isValid = notValidTypeList.stream().anyMatch(notValidType -> notValidType.equalsIgnoreCase(mimeType));

            return isValid;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}

FileUtils에 tika를 이용하여 mime type을 체크해준다.
우리 생각보다 우리가 모르는 확장자는 정말 많으므로, 확장자를 체크할 때는 업로드 할 수 없는 확장자를 체크하는 것보다 업로드가 가능한 파일의 확장자를 체크하는 것이 더 좋다고 한다.

그리고 우리팀은 이미지가 S3에 업로드 될 때 사용하므로 해당 로직도 FileUtils를 이용해 확장자 체크를 해주는 로직으로 바꿔줘야 했다.

|MemberService.java

//회원정보 수정
MultipartFile file = memberUpdateRequestDto.getFile();
if (file != null) {
        String fileUrl = s3Service.upload(file, "profileImage", memberDetails);
        member.updateProfileImage(fileUrl);

원래 기존에는 file이 null이 아니면 S3에 업로드 되는 로직이었는데, FileUtils를 사용 후 아래처럼 수정해주었다.

//회원정보 수정
MultipartFile file = memberUpdateRequestDto.getFile();
if (file != null) {
	InputStream inputStream = file.getInputStream();

	boolean isValid = FileUtils.validImgFile(inputStream);
    if(!isValid) {
    	// exception 처리
        return new ResponseEntity<>(
                        MemberUpdateResponseDto.builder().status(StatusMessage.BAD_REQUEST).build(),
                        HttpStatus.valueOf(StatusCode.BAD_REQUEST));
	}
	else {
		String fileUrl = s3Service.upload(file, "profileImage", memberDetails);
		member.updateProfileImage(fileUrl);
	}
}

(file이 null인 것과, empty인것과는 다르다!) 처음에는 isEmpty로도 if문이 있었는데 if문이 세개나 되어버려서 위와같이 최종이 되었다.

참고 자료 : Java 업로드할때 파일 타입 확인하기
참고 자료 : Apache Tika 사용
참고 자료 : 파일 첨부시 확장자 선택


Enter 이벤트

우리가 받은 피드백 중 가장 많은 부분이 로그인 할 때 enter치면 로그인 되게 해달라는 거였다! ㅠㅠ 왜 기능 구현할 때는 불편할거란 생각을 못했는지...그래서 지금이라고 추가하기로!

먼저, 비밀번호를 입력하는 input 태그에 onkeyup="enterkey()" 함수를 먼저 넣어주고,

<input type="password" class="input" onkeyup="enterkey()">

Javascript로 enter를 쳤을 때 requestLogin() 함수가 실행되게 했다.
여기서 keyCode == 13인 이유는 키보드 아스키코드 표에서 enter가 13이기 때문이다!

window.enterkey = () => {
    if (window.event.keyCode == 13) {
        requestLogin();
    }
};

참고 자료 : enter event


Achor 태그 새창열기

피드백 중, 게시글에서 작성자 프로필 모달을 볼 때 Github 주소나, 포트폴리오 주소 링크가 눌렀을 때 새창으로 열렸으면 좋겠다는 글이 있었다. 기본적으로 바로 이동기능이기에, target="_blank"를 이용하여 새창에서 열리게 해줬다.

<a href="${portfolio}" target="_blank">${portfolio}</a><br>

참고 자료 : a태그 하이퍼링크 속성

profile
코베베

1개의 댓글

comment-user-thumbnail
2022년 7월 26일

예 맞습니다 제가 박철진입니다.

답글 달기