웹 개발자, 특히 풀스택 개발자라면 반드시 알고 있어야 할 사이버 공격 종류
- 보안은 “취약점을 막는 것”이 아니라 “공격당해도 피해를 최소화하는 것”
1. XSS (Cross-Site Scripting)
요약
- 사용자의 브라우저에 악성 스크립트를 삽입
- 사용자 쿠키/토큰 탈취, 리디렉션, 키로깅 등 가능
예시
<input value="<script>alert('XSS')</script>">
방어
- dangerouslySetInnerHTML 지양
- 입력값 escape
- Content-Security-Policy 설정
- DOMPurify, xss 필터 사용
XSS 방어 4대 수칙
1. CSP (Content-Security-Policy) 설정
브라우저에게 **"어디서 로드한 스크립트만 실행해!"**라고 알려주는 보안 헤더
적용 방법 (예: Vite + Nginx + Netlify 등)
(1) index.html <head> 안에 추가:
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; object-src 'none';"
/>
(2) 혹은 Nginx에서:
add_header Content-Security-Policy "default-src 'self'; script-src 'self';";
script-src 'self' → 외부 JS 차단
unsafe-inline이나 eval() 같은 위험 코드도 막을 수 있음
Netlify/Cloudflare 등은 보안 헤더 설정 기능 제공
권장 설정
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self' https://api.example.com;
object-src 'none';
2. dangerouslySetInnerHTML 지양
React에서 XSS가 가장 쉽게 발생하는 지점
사용자가 입력한 HTML을 직접 innerHTML로 주입하면, 악성 JS도 함께 들어올 수 있어요.
<div dangerouslySetInnerHTML={{ __html: userInput }} /> // ❌ 위험!
→ 이런 경우는 DOMPurify 같은 HTML Sanitizer를 쓰거나, 아예 쓰지 않는 게 좋습니다.
3. 외부 script 삽입 제한
// ❌ XSS 진입점
- 사용자가 임의로 외부 스크립트를 삽입할 수 있는 구조는 무조건 차단해야 함
- 특히 <textarea>, <input> 같은 필드를 통해 <script>를 저장 → 출력하는 경우 반드시 검증
4. 사용자 입력 값 Escape (필터링)
서버에서 들어온 데이터 or 사용자가 입력한 데이터가 HTML로 랜더링되면, 반드시 이스케이프 처리
예:
<script>alert("XSS")</script>
→ 출력 시:
&lt;script&gt;alert("XSS")&lt;/script&gt;
클라이언트 escape 예시:
function escapeHTML(input: string): string {
return input
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
또는 dompurify 사용:
npm install dompurify
import DOMPurify from 'dompurify';
const safeHtml = DOMPurify.sanitize(userInput);
결론
반드시 설정
✅ CSP 헤더 설정 | 외부 스크립트 차단 |
✅ dangerouslySetInnerHTML 사용 제한 | 또는 DOMPurify 필수 |
✅ 사용자 입력 escape or sanitize | 특히 HTML 주입 가능성이 있는 경우 |
✅ 개발자 도구 + DevSecOps 린트 | 예: eslint-plugin-security 등 도입 가능 |
2. CSRF (Cross-Site Request Forgery)
요약
- 사용자의 인증 상태를 악용해 외부에서 요청을 보내는 공격
- 로그인된 사용자가 의도치 않은 요청을 보내도록 유도
예시
<img src="https://example.com/api/delete-account" />
방어
- SameSite=Strict 쿠키 설정
- CSRF 토큰 적용
- 중요한 요청은 POST + Origin 확인
실전용 CSRF 방어 전략 3가지
1. SameSite=Strict 쿠키 설정
개념
- 브라우저가 다른 사이트에서 요청할 때 쿠키를 안 보내도록 설정
- 즉, evil.com에서
(<img src="에이치티티피://your-site.com/api/delete">)요청을 보내도
→ 쿠키가 안 따라가기 때문에 공격이 실패합니다.
실전 설정
Spring Boot (서버)
ResponseCookie refreshCookie = ResponseCookie.from("refreshToken", token)
.httpOnly(true)
.secure(true)
.sameSite("Strict") // <-- 핵심 설정!
.path("/")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, refreshCookie.toString());
2. CSRF 토큰 적용 (토큰 기반 인증에서는 선택사항)
개념
- 쿠키는 자동으로 전송되니까 요청이 진짜 사용자의 요청인지 확인하는 토큰을 별도로 포함
- 서버는 쿠키만 보고 신뢰하지 않고, 헤더나 body에 담긴 CSRF 토큰과 비교함
적용 방법
프론트: 요청 시 CSRF 토큰 포함
axios.post('/api/protected', data, {
headers: {
'X-CSRF-Token': csrfToken, // 백엔드가 발급한 토큰
},
withCredentials: true,
});
백엔드: 토큰 검증
Spring Security에서 csrf().csrfTokenRepository(...) 방식으로 설정하거나,
커스텀 필터에서 헤더를 검증해도 됩니다.
단, JWT 인증 + 쿠키 방식에서는 대부분 SameSite=Strict + 인증 헤더로 대응하고
CSRF 토큰은 사용하지 않는 경우가 많습니다 (복잡성 증가 때문)
3. 중요 요청은 POST + Origin 헤더 확인
개념
- CSRF는 주로 GET이나 자동으로 보내지는 요청에서 발생
- 따라서 민감한 요청은 반드시 POST, PUT, DELETE 등으로 처리
Origin/Referer 체크
String origin = request.getHeader("Origin");
if (!origin.equals("https://your-domain.com")) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
또는 Spring Security의 CORS 설정에서 origin을 제한
추천 방어 전략
(현재 진행하는 프로젝트는 JWT + 쿠키 구조이다.)
✅ SameSite=Strict 쿠키 | 필수 | 쿠키 자동 전송 방지 |
✅ 모든 민감한 요청은 POST | 필수 | GET으로 위험한 작업 막기 |
✅ Origin 헤더 확인 | 권장 | 위조된 요청 차단 |
❓ CSRF 토큰 방식 | JWT + 쿠키 구조에선 선택사항 | 보안 수준은 높지만 복잡도 증가 |
예시: 완벽한 CSRF 방어 구조 (JWT + HttpOnly 쿠키 방식)
- Refresh Token → HttpOnly + Secure + SameSite=Strict 쿠키
- Access Token → React 메모리 or Header에만 존재 (localStorage ❌)
- 민감 요청은 모두 POST, PUT, DELETE
- Origin 체크 추가 (선택)
- 로그인 상태 확인은 반드시 Authorization or 쿠키 + DB 체크
- 서버 측 CSRF 미들웨어는 생략 가능 (하지만 Spring Security에서 csrf().disable()했는지 확인!)
3. SQL Injection
요약
- SQL 쿼리에 악성 입력을 삽입해 데이터베이스를 조작하는 공격
- 보안 사고 1순위 임으로 반드시 원칙을 지켜야한다
예시
SELECT * FROM users WHERE username = 'admin' --' AND password = ''
🛡️ 방어
- PreparedStatement / ORM 사용
- 입력값 escape
- 절대 문자열로 쿼리 만들지 않기
SQL Injection(쿼리 인젝션) 공격을 막기 위한 핵심 전략 3가지
예시 (취약한 코드)
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
사용자가 username = ' OR 1=1 -- 를 입력하면?
SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = ''
→ 모든 계정에 로그인됨
1. PreparedStatement / ORM 사용
핵심 개념
- 사용자 입력을 문자열로 직접 붙이지 말고,
? 자리로 대체하고 나중에 바인딩하면 안전해요.
Java (JDBC) 예시
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
- 여기서는 username 안에 ' OR 1=1 -- 같은 걸 넣어도
그냥 "문자열"로 취급되기 때문에 공격이 안 됩니다!
Spring JPA / ORM 예시
ORM을 쓰면 보통 JPQL로만 작성하거나 메서드 이름으로 처리해서 안전해요.
User findByUsernameAndPassword(String username, String password);
→ 자동으로 PreparedStatement로 실행됨
혹은:
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
→ 이 역시 바인딩 처리돼서 안전!
2. 입력값 escape
사용자 입력값을 SQL 문법에서 의미 없는 값으로 바꾸는 것
예: ' → \', -- → \- -
- DB에 따라 다르지만 기본적으로 사용자가 따옴표('), 세미콜론(;) 같은 걸
입력값으로 줄 수 없게 필터링하거나 escape 처리하면 일부 방어 가능해요.
하지만 escape 방식은 보완책일 뿐, 주된 방어 수단은 아니에요!
가능하면 항상 PreparedStatement나 ORM을 쓰세요.
3. 문자열로 직접 쿼리 만들지 않기
❌ 이런 건 안 돼요
String query = "DELETE FROM " + tableName + " WHERE id = " + id;
- tableName이나 id를 사용자가 조작할 수 있으면 DB 전체 삭제도 가능
- 문자열 조작이 들어간 쿼리는 거의 항상 위험합니다!
이런 방식이 안전
String sql = "DELETE FROM users WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setLong(1, id);
실제 서비스에서의 안전 전략 요약
✅ PreparedStatement 사용 | DB 레벨에서 입력값을 안전하게 처리 |
✅ JPA / ORM 사용 | 직접 SQL 안 짜도 되니 가장 안전 |
❌ 문자열 조작으로 SQL 만들기 | 절대 금지 (특히 where, delete, insert에) |
⚠️ escape 처리 | 보완책이지만 근본 해결은 아님 |
PreparedStatement 왜 써야 해? | 입력값을 자동으로 안전하게 처리해줌 |
ORM은 안전한가? | 대부분 PreparedStatement 기반이라 기본적으로 안전 |
escape 처리도 필요해? | 최후의 보완책이지만, 원천 차단은 PreparedStatement |
쿼리를 문자열로 만들면 안 되는 이유는? | 조작이 가능해지기 때문 (Injection 가능) |
4. Authentication Bypass
요약
- 인증 절차를 우회해 권한 없이 접근하는 공격
- 로그인 안 한 사용자나, 권한이 없는 사용자가 보호된 API나 페이지에 접근
예시
- JWT 토큰 위조
- 로그인 검증 누락된 API 호출
방어
- 모든 요청에서 Authorization 헤더 검증
- JWT 서명 검증
- 백엔드 권한 체크 철저
공격 예시
GET /admin/dashboard ← 일반 유저가 직접 요청
Authorization: Bearer <다른 사람 토큰>
또는:
GET /api/users/1 ← URL에서 다른 유저 ID로 조작
실전 방어 전략
1. 모든 API에 인증 미들웨어 / 필터 적용
백엔드에서 인증을 우선 확인하지 않으면 무조건 뚫립니다.
Spring Security 예시
http
.authorizeHttpRequests()
.requestMatchers("/api/auth/**").permitAll() // 인증 예외
.anyRequest().authenticated(); // 그 외 모든 요청 인증 필요
→ 이걸 안 하면 /api/secret-data 같은 API도 인증 없이 열려버립니다.
2. 사용자의 소유권 검증 (Authorization)
인증은 "로그인 했냐?",
인가(Authorization)는 "그 리소스를 볼 권한 있냐?"
예시: 현재 로그인한 사용자만 자신의 정보에 접근
@GetMapping("/api/users/{id}")
public User getUser(@PathVariable Long id, @AuthenticationPrincipal UserPrincipal user) {
if (!user.getId().equals(id)) {
throw new ForbiddenException("접근 권한 없음");
}
return userService.getUser(id);
}
→ id를 그냥 믿으면 안 되고, 현재 로그인한 유저와 비교해야 해요.
3. JWT 서명 검증 필수
- 토큰이 있다고 해서 믿으면 안 됩니다.
- 백엔드는 JWT 서명을 항상 검증해서 위조 여부를 확인해야 해요.
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
서명이 일치하지 않으면 바로 예외 발생 → 토큰 위조 방지 가능
4. 역할(Role) 기반 인가
- 관리자만 접근해야 하는 API에는 반드시 권한 체크를 하세요.
Spring Security 예시
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin/dashboard")
public String adminPage() {
return "Admin only";
}
5. 프론트엔드에서 숨겨도, 백엔드에서 차단 못하면 무용지물
- 버튼을 숨겨도 API는 보이기 때문에 백엔드에서 차단이 핵심입니다.
- 항상 백엔드 단에서 "이 사용자가 이 요청을 보낼 자격이 있는가?" 확인해야 합니다.
6. 로그 남기기 + 알림 설정
- 인증 우회 시도(예: JWT 없이 요청, 잘못된 토큰)는 로그로 남기고
- 너무 많은 시도가 감지되면 자동 차단 or 알림
logger.warn("Unauthorized access attempt from IP: {}", request.getRemoteAddr());
인증 우회 방어 체크리스트
✅ 모든 API 인증 필수 | .anyRequest().authenticated() |
✅ 로그인한 사용자 확인 | @AuthenticationPrincipal로 소유자 검증 |
✅ 권한 확인 | @PreAuthorize("hasRole(...)") |
✅ JWT 서명 검증 | JWT 위조 방지 |
✅ 민감한 요청 로깅 | 이상 접근 탐지 |
❌ 프론트 숨김만으로 방어 X | API가 막혀야 진짜 막힌 것 |
5. Directory Traversal
요약
- 경로 조작으로 시스템 내부 파일에 접근
예시
GET /api/files?path=../../../../etc/passwd
방어
- 경로 정규화 (path.normalize)
- 루트 경로 바깥으로 벗어날 수 없도록 제한
공격 시나리오
GET /api/files?path=../../../../etc/passwd
- 원래는 /uploads/user1.jpg만 접근할 수 있어야 하는데,
- ../../../etc/passwd로 시스템 파일을 읽어버리는 거예요
방어 전략 요약
✅ 경로 정규화 (path.normalize) | ../ 같은 경로 조작을 정리해서 비교 |
✅ 루트 경로 밖으로 벗어나는 요청 차단 | 기준 폴더 밖으로 나가면 예외 처리 |
✅ 파일 이름만 받기 | 경로는 서버에서 고정, 사용자에겐 파일 이름만 입력 받기 |
✅ 허용된 확장자만 열기 | .png, .jpg만 등 필터링 |
✅ 파일 존재 여부 체크 + 접근 권한 검사 | 있는 파일인지, 사용자 권한이 맞는지 체크 |
실전 코드(Node.js 기반)
import path from 'path'
import fs from 'fs'
const SAFE_BASE_DIR = path.join(process.cwd(), 'uploads')
function getSafeFilePath(userInput: string) {
const resolved = path.resolve(SAFE_BASE_DIR, userInput)
// 🔐 기준 디렉토리 밖이면 막기
if (!resolved.startsWith(SAFE_BASE_DIR)) {
throw new Error('Unauthorized file access')
}
return resolved
}
사용 예시
const filePath = getSafeFilePath(req.query.path as string)
const fileContent = fs.readFileSync(filePath, 'utf-8')
Spring Boot에서 방어 전략
@GetMapping("/api/files")
public ResponseEntity<?> readFile(@RequestParam String filename) {
Path basePath = Paths.get("uploads").toAbsolutePath().normalize();
Path targetPath = basePath.resolve(filename).normalize();
// ✅ uploads 디렉토리 밖으로 나가려 하면 막기
if (!targetPath.startsWith(basePath)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("잘못된 경로");
}
// ✅ 파일 존재 여부 및 확장자 검사도 추가 가능
if (!Files.exists(targetPath)) {
return ResponseEntity.notFound().build();
}
String content = Files.readString(targetPath);
return ResponseEntity.ok(content);
}
필수적인 추가 조치
.normalize() | 경로 중복/../ 등을 정리 |
startsWith(SAFE_BASE) | 기준 경로 밖인지 확인 |
path traversal 탐지 | ../, ..\\, %2e%2e 등 필터링 (서버 단에서만 처리해야 안전) |
파일 권한 검증 | 이 사용자가 이 파일을 열 수 있는지 권한 체크 |
업로드 시에도 체크 | 사용자가 ../../../secret.txt 같은 이름으로 파일 올리지 못하게 해야 함 |
실전 방어법 체크리스트
사용자 입력 경로 사용 시 | 반드시 path.resolve + path.normalize |
기준 디렉토리 설정 | basePath로 고정하고 밖으로 못 나가게 |
경로에 ../ 있는지 검사 | 또는 정규화된 경로로 비교 |
확장자 제한 | .txt, .jpg만 허용 등 |
파일 이름만 입력 받기 | 경로는 백엔드가 조립 |
6. Broken Access Control
요약
- 권한이 없는 사용자가 관리자 기능, 다른 사용자의 데이터에 접근하는 공격
예시
GET /api/users/1 ← 일반 유저인데 관리자 정보 요청
방어
- 요청마다 권한(Role) 검증
- 리소스마다 접근 제한 (@PreAuthorize, @Secured 등)
7. Social Engineering (사회공학적 공격)
요약
- 기술적 공격이 아닌 사람을 속여 정보를 빼내는 방식 (시스템보다 사용자(사람)이 주요 타겟이 된다.)
- 피싱 메일, 가짜 로그인 페이지
방어
- 사용자 교육
- 2차 인증 (MFA)
- 출처 모를 링크 클릭 방지
대표적인 Social Engineering 공격 유형
🎣 피싱(Phishing) | 가짜 이메일, 문자, 로그인 페이지로 유도해 정보 탈취 |
📞 스피어 피싱(Spear Phishing) | 특정 타겟(직원, 관리자)을 노린 정교한 피싱 |
🗣️ 전화 사기 | "IT팀입니다. 비밀번호 알려주세요" 등 |
👀 숄더 서핑 | 옆자리에서 비밀번호를 엿보기 |
💾 USB 공격 | 악성 USB로 컴퓨터 감염 유도 |
방어 전략
1. 사용자 교육 (가장 중요!)
"가장 취약한 건 사람이다" → 보안은 기술보다 습관입니다.
교육 내용 예시:
- 이메일 링크 클릭 전에 출처 확인 (hover로 링크 확인)
- 출처 불명의 파일 다운로드 금지
- 가짜 로그인 페이지 구분법
- 비밀번호, OTP는 누구에게도 말하지 말기
- 의심되면 IT 보안팀에 먼저 문의
정기적인 보안 교육 + 피싱 시뮬레이션 훈련이 효과적입니다.
2. 2차 인증 (MFA, Multi-Factor Authentication)
설령 비밀번호가 유출돼도, 휴대폰 OTP, 생체 인식 등 2차 인증이 있으면 피해를 막을 수 있어요.
MFA 예시:
- Google Authenticator, Authy
- Email/문자 인증코드
- FIDO(지문/얼굴 인식 등)
관리자, 내부 시스템 사용자는 반드시 MFA 적용!
3. 출처 모를 링크 클릭 방지
- 이메일/문자에 있는 링크가 실제 사이트와 동일해 보여도 절대 클릭 금지
- 도메인 속임수 예:
- google.com.hacker.site → ❌ 위험 gooqlе.com (l 대신 소문자 L) → ❌ 위험
대응 방법:
- 직접 주소창에 도메인 입력
- 링크 위에 마우스 올려서 진짜 주소 확인
- "이메일 알림 왔어요" → 앱이나 웹사이트 직접 접속해서 확인
4. 역할/권한 최소화
내부직원이 해킹당해도 피해를 최소화하려면, 필요한 기능만 쓸 수 있도록 Role을 나눠야 해요.
- 일반 유저는 관리자 API 접근 금지
- 파일 다운로드, 삭제, 설정 변경은 Role 체크 필수
5. 의심행위 모니터링 + 알림 시스템
- 관리자 계정 로그인 시 이메일 알림
- 다중 로그인 감지 → 자동 로그아웃
- 비정상적인 IP 로그인 차단 (예: 한국 → 러시아 로그인 시)
알림 → 차단 → 로그 확인 → 관리자 대응
6. 비밀번호 정책 강화
- 최소 8~12자, 대소문자+숫자+특수문자 포함
- 일정 주기 변경 (선택적)
- 비밀번호 재사용 금지 (이메일 = GitHub = 은행 → 위험!)
7. 시스템적인 방어도 병행
로그인 시 IP/기기 정보 저장 | 새로운 기기 로그인 시 알림 |
로그인 시 지연 주기 (rate limit) | 무차별 시도 방지 |
로그인 실패 횟수 제한 | 일정 횟수 초과 시 계정 잠금 또는 MFA 요구 |
종합 방어 체크리스트
✅ 사용자 교육 | 실수 예방의 핵심 |
✅ 2차 인증 (MFA) | 비밀번호 유출 시에도 계정 보호 |
✅ 링크 클릭 주의 | 도메인 위조 막기 |
✅ 권한 최소화 | 계정 탈취 시 피해 최소화 |
✅ 로그인 이상 감지 | 보안팀 알림 or 자동 차단 |
✅ 강력한 비밀번호 정책 | 계정 자체를 튼튼하게 |
구현 사항
- React + Spring Boot에서 MFA(OTP) 적용
- 관리자 페이지에 Social Engineering 방지 팁 삽입하는 UX
- 보안 알림 로직 설계
8. Zero-Day Attack
요약
- "0-day"는 "패치까지 0일 남았다"는 뜻으로 소프트웨어의 알려지지 않은 보안 취약점을 해커가 먼저 발견하고, 개발자나 보안 커뮤니티가 패치하기 전에 공격에 사용하는 것
- 공식적인 패치가 아직 존재하지 않는 보안 취약점을 노리는 공격 (공식 패치가 나오기 전까지 대응 어려움)
- 보안 패치가 없는 상태라서 사실상 무방비 상태
방어
- 의심스러운 라이브러리 사용 지양
- 주기적인 의존성 업데이트
- Snyk, Dependabot 같은 취약점 감지 도구 활용
실전 방어 전략 (직접 막을 수는 없지만 피해를 최소화하는 전략)
1. 자동 보안 업데이트 활성화
- 의존성/라이브러리의 최신 보안 패치를 빠르게 적용
- 취약점이 공개되는 즉시 패치가 따라와야 함
도구
GitHub Dependabot | yarn.lock, package.json 감시 + PR 자동 생성 |
npm audit / yarn audit | npm 의존성 취약점 검사 |
Snyk / Sonatype / OWASP Dependency Check | 빌드 시 취약한 버전 탐지 |
2. 불필요한 서비스, 포트, 라이브러리 제거
코드가 없으면 공격도 불가능
- 사용하지 않는 패키지, API, 관리자 기능 제거
- node_modules, /actuator, /h2-console, /admin 같은 경로 비공개 처리
3. 네트워크 레벨에서 방어 (WAF, IDS, IPS)
WAF (Web Application Firewall) | SQLi, XSS, RCE 등의 이상 요청 차단 |
IDS/IPS | 침입 탐지/차단 시스템 (예: Snort, Suricata) |
Cloudflare, AWS WAF | 클라우드 환경에서 필수 설정 가능 |
제로데이 취약점이라도 비정상적인 요청을 차단해 피해를 줄일 수 있어요.
4. 원칙적인 보안 코딩 습관
“취약점이 있더라도 뚫기 어렵게 만든다”는 개념입니다.
보안 습관 체크리스트
입력값 무조건 검증 | req.body, req.query, req.params, headers 전부 |
PreparedStatement 사용 | SQL Injection 대비 |
eval(), Function() 지양 | RCE 방지 |
파일 업로드 → 확장자, 크기, 경로 체크 | Path Traversal 대비 |
환경변수 보호 | 비밀키 노출 방지 |
5. 서비스 구역화 (Zero Trust Architecture)
공격자가 들어오더라도 전체 시스템에 접근하지 못하게 분리합니다.
- DB, API, 관리자, 일반 유저 시스템을 물리적으로 분리
- 내부 API에도 토큰 기반 인증, IP 제한
6. 로깅 + 이상 탐지
- 갑자기 너무 많은 요청이 들어오거나, 알 수 없는 endpoint 요청이 많아지면
→ 의심하고 대응할 수 있게 로그/알림 설정
예시
/whoami
/nmap
/phpmyadmin
/.env
이런 요청이 들어오면 거의 100% 해킹 스캔이에요
7. 정기적인 취약점 점검 + 보안 훈련
취약점 점검 | OWASP ZAP, Burp Suite, Nessus |
팀 훈련 | 해킹 시나리오 대응 실습 (Red Team vs Blue Team) |
보안 가이드라인 준수 | OWASP Top 10 학습 + 대응 가이드 적용 |
종합 체크리스트
✅ 의존성 자동 업데이트 | dependabot, npm audit fix 등 |
✅ 사용하지 않는 기능 제거 | 공격면 최소화 |
✅ 웹 방화벽 설정 (WAF) | 비정상 요청 차단 |
✅ 네트워크 분리, API 인증 | 침투해도 더 못 가게 |
✅ 정적 코드 분석 도구 사용 | 린트 수준에서 취약점 예방 |
✅ 로그 + 이상 알림 시스템 | 공격 징후를 빠르게 탐지 |
✅ 보안 교육 & 시뮬레이션 | 대응 훈련 필수 |
기타 공격들
MITM (Man-in-the-Middle) | 중간에서 통신 탈취 → HTTPS로 방지 |
Brute Force | 비밀번호 무차별 대입 시도 |
RCE (원격 코드 실행) | 서버에서 악성 코드가 실행됨 |
DoS/DDoS | 서버를 트래픽으로 마비시킴 |
Clickjacking | iframe에 페이지를 숨겨 클릭을 유도함 |
앞으로 공부해야 할 보안 공부 키워드 요약
- OWASP Top 10 → 웹 보안 이슈 모음
- CSP / CORS / XSS / CSRF / JWT 보안
- Spring Security / Helmet.js / DOMPurify
- Axios 보안 설정 (withCredentials, timeout 등)
- ZAP, Burp Suite, Snyk → 보안 테스트 도구
'Computer > Computer Security' 카테고리의 다른 글
Spring Boot 보안 체크리스트 (0) | 2025.04.01 |
---|---|
React 보안 체크리스트 (0) | 2025.04.01 |
네트워크 보안 (0) | 2025.03.28 |
서버 보안 (1) | 2025.03.26 |
사이버 공격 (1) | 2025.03.25 |