CSRF 란?
Cross Site Request Forgery(사이트 간 요청 위조)
웹 취약점 중 하나!
해커가 CSRF를 통해 일반유저의 권한을 도용하여 중요 기능을 실행하는 것이 가능한 것!
해커가 만든 피싱 사이트를 일반유저가 사용하지 않더라도 해커가 정상 사이트를 통해 CSRF 공격이 수행될 수 도 있다.
간단하게 예를 들어보자면 네이버와 동일해보이는 폼을 해커가 희생자에게 보내 아이디와 비번을 가로채어
희생자의 계정을 이용해 광고성, 이상한 게시글을 올릴 수 있게되는 수법.
CSRF 대응 방법
1. CAPCHA 사용
이미지,문자.. 를 이용해 사람인지 로봇인지를 구분하는 인증방식.
2. Referrer 검증법
3. CSRF 토큰사용 (나는 이 방법을 사용)
스프링 시큐리티를 사용시 자동으로 csrf 방지기능이 적용된다.
[ SecurityConfig]
form 태그에 직접 hidden _csrf 필드 집어 넣어 주는 방법도 있으나
Thymeleaf 2.1, @EnableWebSecurity를 사용하는 경우 CsrfRequestDataValueProcessor가 적용되어
form 에 CSRF 토큰이 자동적으로 들어간다.
관리자 권한으로 페이지 추가하는 화면
그래서 페이지 추가할때 csrf 자동 생성됨
form 주소 th:action="@{/주소} 는 _csrf 값을 자동 생성해서 붙여준다.
_csrf 값이 아닌 다른곳에서의 요청은 막아줌.
- 카테고리 위치 바꾸면 에러. 새로고침해도 본 위치대로 돌아감
AJAX=자바스크립트에 바로 요청을 해서 에러가 난 것
해결
☆ AJAX 에 csrf가 필요하다!!
form 태그는 CSRF 토큰이 자동으로 들어가 따로 코드를 작성할 필요가 없지만
AJAX는 토근값을 header 에 보내줘야한다.
- 관리자 [ head.html] head태그 사이에 meta 태그에 토큰 집어 넣어 주기
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}">
<!-- 관리자용 head -->
<head th:fragment="home-admin">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}">
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}">
<title>👩💻관리자 페이지</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<!-- 커스텀 CSS -->
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
- AJAX 가 사용 된 카테고리와 페이지 에 추가하기 (categories/index , pages/index)
let token = $("meta[name='_csrf']").attr("content");
let header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function (e, xhr, options) {
xhr.setRequestHeader(header, token);
});
= 관리자 모드에 페이지나 카테고리 순서를 바꾸면 유저모드에 순서가 바뀐채로 나오도록 성공.
관리자 모드에서 카테고리 순서 변경했을 때 → 아까 관리자 모드에서는 순서가 바뀌도록 해결했으나
이번에는 고객페이지에는 카테고리 순서 안바뀌어 있는 경우
해결
[ Common ]
List<Page> cpages = pageRepo.findAllByOrderBySortingAsc();
List<Category> categories = categoryRepo.findAll();
findAll를 findAllByOrderBySortingAsc로 바꿔줘야함
리스트를 sorting 순으로 가져오도록 메서드 이름을 findAllByOrderBySortingAsc 로 변경한다.
'Spring boot | 쇼핑몰 만들기 | 어글리 마켓 > security | 로그인' 카테고리의 다른 글
Login 로그인 페이지 (0) | 2022.05.13 |
---|---|
인증(유저,관리자) 하는 클래스 UserDetailsServiceImpl (0) | 2022.05.12 |
가입하는 컨트롤러 RegistrationController (0) | 2022.05.12 |
Entity User, Admin 클래스 생성 (0) | 2022.05.12 |
스프링 시큐리티 적용하기 | 유저,관리자 테이블 생성 (0) | 2022.05.12 |