시큐어 코딩이 중요한 이유
•
국내 보안 관련 법령 (정보통신망법, 개인정보보호법 등)
•
보안 취약점 하나가 기업 신뢰도와 금전 피해로 직결
자바에서 자주 발생하는 보안 취약점과 예방 방법
1. SQL Injection
•
취약 예시: Statement에 문자열 덧붙이기
•
방어 코드: PreparedStatement 사용
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
Java
복사
2. XSS (Cross Site Scripting)
•
취약 예시: 입력값 그대로 HTML에 출력
•
방어 코드: StringEscapeUtils.escapeHtml4(userInput)
3. CSRF (Cross Site Request Forgery)
•
방어 기법: Spring Security CSRF 토큰 적용
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
Java
복사
4. 파일 업로드 취약점
•
방어 코드: 확장자 검증 + 파일명 UUID 처리 + 업로드 경로 외부 노출 방지
String safeFilename = UUID.randomUUID().toString() + ".jpg";
Java
복사
5. 암호화/복호화 취약점
•
잘못된 예: MD5, SHA1 사용
•
안전한 방식: PBKDF2, bcrypt, Argon2
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashed = encoder.encode(rawPassword);
Java
복사
6. 보안 관련 자바 라이브러리 추천
•
Spring Security: 인증·인가 프레임워크
•
OWASP ESAPI: 보안 유틸리티 제공
•
Apache Shiro: 경량 보안 프레임워크
실전 시큐어 코딩
1. 입력값 검증 (Input Validation)
•
잘못된 예 (취약 코드)
String email = request.getParameter("email");
// 바로 DB 쿼리에 사용 → 위험
Java
복사
•
안전한 예 (화이트리스트 검증)
if (!email.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
throw new IllegalArgumentException("Invalid email format");
}
Java
복사
Tip: 입력 검증은 화이트리스트 방식으로 허용할 값만 명시하는 것이 기본 원칙이다.
2. 인증과 세션 관리 (Authentication & Session)
•
비밀번호 저장 시 보안 처리
◦
절대 평문 저장 금지
◦
안전한 해시 알고리즘 사용
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(plainPassword);
Java
복사
추천 알고리즘: bcrypt, Argon2, PBKDF2
•
세션 고정 공격 방지
request.getSession().invalidate();
request.getSession(true); // 새로운 세션 발급
Java
복사
3. SQL 인젝션 방지
•
잘못된 예
String query = "SELECT * FROM users WHERE id = " + userId;
Java
복사
•
안전한 예 (PreparedStatement)
String query = "SELECT * FROM users WHERE id = ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setInt(1, userId);
Java
복사
ORM 사용 시에도 @Param이나 바인딩 방식을 통해 방어한다.
4. XSS 방어
•
취약 코드
out.println("<p>" + userInput + "</p>");
Java
복사
•
방어 코드
out.println("<p>" + StringEscapeUtils.escapeHtml4(userInput) + "</p>");
Java
복사
Spring MVC에서는 @ResponseBody와 th:text로 자동 XSS 방어 처리가 됩니다.
5. CSRF 방지 (Spring Security)
•
기본 설정 (Spring Security)
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
Java
복사
폼 전송 시 CSRF 토큰을 반드시 포함해야 요청이 정상 처리됩니다.
6. 파일 업로드 보안
•
안전한 파일명 처리
String safeFilename = UUID.randomUUID().toString() + ".jpg";
Java
복사
•
업로드 경로 분리
◦
/upload 폴더를 웹 루트 외부에 두고 다운로드 시 별도의 컨트롤러로 파일을 제공하도록 설계한다.
7. 민감 정보 로그 출력 금지
•
잘못된 로그 예시
log.info("로그인 시도: username={}, password={}", username, password);
Java
복사
•
올바른 로그 예시
log.info("로그인 시도: username={}", username);
Java
복사
8. 보안 HTTP 헤더 설정 (Spring Security)
•
이 설정은 XSS, Clickjacking 공격 방어에 효과적이다.
http.headers()
.xssProtection()
.and()
.contentSecurityPolicy("script-src 'self'")
.and()
.frameOptions().deny();
Java
복사
9. 포인트
•
SQL Injection은 PreparedStatement로 방어한다.
•
비밀번호는 bcrypt로 해싱하여 저장한다.
•
CSRF 방어를 위해 Spring Security의 기본 정책을 따른다.
•
XSS 방어는 출력 시 HTML 이스케이프 처리한다.