공공부하자개발 · 영어 학습 노트
자바
실무 확장Excel · 파일 업로드 · DB 연동0/22 완료
  • 01Excel(XLSX) 구조와 순수 JDK로 읽기/쓰기
  • 02Apache POI로 Excel 업로드/다운로드
  • 03파일 업로드/다운로드 서버 (HttpServer)
  • 04JDBC 기초와 트랜잭션 (H2)
  • 05MyBatis 어노테이션 매퍼로 쿼리 연동
  • 06MyBatis XML 매퍼 · Oracle 방언 · PageHelper · Spring Boot
  • 07REST API 서버와 JSON
  • 08Vue 3 SPA 와 Java 서버 연동
  • 09@Scheduled 운영
  • 10로깅 실무: 레벨·계층, MDC 추적, 예외·성능, 마스킹, 롤링, JSON 로그
  • 11외부 API 연동
  • 12테스트 실무
  • 13암호화·개인정보 보호
  • 14인코딩·한글 실무
  • 15@Transactional 심화
  • 16긴 작업 비동기 처리와 진행률
  • 17SFTP·FTP 파일 연계
  • 18로컬 캐시와 @Cacheable
  • 19메일·알림 발송
  • 20웹 보안 체크리스트
  • 21빌드 도구와 폐쇄망 의존성 반입
  • 22성능 측정: p50·p95·p99, 측정 계층, JFR, JMH 함정, 자체 부하 테스트, 병목 순위
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 실무 확장 › 20 / 22

웹 보안 체크리스트

XSS·CSRF·SQL 인젝션·경로 탐색·업로드·IDOR·보안 헤더·의존성 취약점
섹션 7진행 0 / 22
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

6. 연습 문제

문제 1. `Guard` 에 이메일 형식 화이트리스트 검증 추가

Guard 에 간단한 이메일 형식인지 확인하는 isValidEmail(String s) 를 추가하세요. @ 가 정확히 1개이고, 앞뒤에 최소 1글자씩 있어야 통과합니다.

java
public static boolean isValidEmail(String s) {
    if (s == null) return false;
    int at = s.indexOf('@');
    if (at <= 0 || at != s.lastIndexOf('@')) return false;
    return at < s.length() - 1;
}

정규식도 가능하지만, 사내 데모에서는 이 정도 단순 검사로도 형식 오류 대부분을 걸러냅니다.

문제 2. `/download` 에 확장자 화이트리스트 추가

handleDownload 가 .txt, .pdf 이외의 확장자는 403 으로 막도록 바꿔 보세요. Guard 에 isAllowedDownloadExt(String name) 을 추가해 재사용합니다.

java
private static final Set<String> DOWNLOAD_EXT = Set.of("txt", "pdf");

public static boolean isAllowedDownloadExt(String name) {
    int dot = name.lastIndexOf('.');
    if (dot < 0) return false;
    return DOWNLOAD_EXT.contains(name.substring(dot + 1).toLowerCase());
}

경로 탐색 검증(safePath)과 확장자 검증은 서로 다른 문제이므로 두 검사를 모두 통과해야 합니다.

문제 3. 로그인 실패 카운트에 계정 잠금 해제 시간 표시 추가

4.3 의 failCount 예제에 잠금 상태일 때 남은 시간(초)을 함께 안내하도록 바꿔 보세요. 힌트: Cache 에 expireAt(key) 를 추가한 18 레슨 문제 1 을 재사용합니다.

java
long expireAt = failCount.expireAt(loginId);
long remainSec = Math.max(0, (expireAt - System.currentTimeMillis()) / 1000);
throw new LockedException(remainSec + "초 후 다시 시도하세요");

캐시 만료 시각을 그대로 안내에 쓰면 별도 타이머 없이도 잠금 해제 시간을 알려줄 수 있습니다.

연습 문제
    이전 섹션5 자주 하는 실수 (Tip)6 / 7다음 섹션7 정리