내일배움캠프

[내일배움캠프] 시큐어 코딩

munsik22 2026. 6. 4. 10:44

목차

    🧩 CORS

    CORS(Cross-Origin Resource Sharing)는 한 출처(도메인, 프로토콜, 포트)에서 실행 중인 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 브라우저에서 제공하는 보안 기능이다.

    • 웹 애플리케이션은 기본적으로 동일 출처 정책(Same-Origin Policy)에 따라 동작하며, 이는 보안상의 이유로 다른 출처의 리소스 접근을 제한한다.
    • CORS는 이러한 제한을 완화하여 특정 조건 하에 다른 출처의 리소스 접근을 허용한다.
    • Preflight: 브라우저가 실제 요청을 보내기 전에 서버에 요청할 권한이 있는지 확인하는 과정

    CORS 설정 시 주의사항

    • 보안 고려사항
      • 신뢰할 수 없는 출처를 허용하지 않도록 주의
      • allowedOrigins에 와일드카드(*)를 사용하면 모든 출처에서의 요청을 허용하므로 주의가 필요
      • 민감한 정보를 보호하기 위해 Access-Control-Allow-Credentials를 신중하게 설정
    • 성능 고려사항
      • Preflight 요청이 빈번하면 성능 저하가 발생할 수 있으므로, Access-Control-Max-Age를 설정하여 Preflight 요청을 캐싱
      • 불필요한 Preflight 요청을 최소화하기 위해 단순 요청 조건을 충족하도록 API 설계를 검토

    백엔드 단에서 CORS 설정

    • 전역설정
    @Configuration
    public class WebConfig {
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")
                            .allowedOrigins("http://localhost:3000")  // 허용할 출처
                            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                            .allowedHeaders("*")
                            .allowCredentials(true)
                            .maxAge(3600);  // Preflight 요청 캐시 시간
                }
            };
        }
    }
    • 컨트롤러 레벨 설정
    @RestController
    public class MyController {
    
        @CrossOrigin(origins = "http://localhost:3000")
        @GetMapping("/api/data")
        public String getData() {
            return "Data from server";
        }
    }

    🧩 CSRF

    CSRF(Cross-Site Request Forgery)는 웹 애플리케이션의 취약점을 이용해 사용자가 의도하지 않은 요청을 보내도록 하는 공격 기법이다.

    • 공격자는 사용자가 인증된 상태를 악용하여 사용자가 원하지 않는 행동을 수행하게 만든다.
    • 사용자가 로그인된 상태에서 악의적인 웹사이트를 방문하면, 그 웹사이트가 사용자의 권한을 이용해 은행 계좌에서 돈을 송금하도록 할 수 있다.

    공격 예시

    <!DOCTYPE html>
    <html>
    <body>
      <h1>Free Gift</h1>
      <img src="http://bank.com/transfer?amount=1000&to=attacker" style="display:none;" />
    </body>
    </html>
    • 사용자가 이 페이지를 방문하면 이미지 태그를 통해 attacker에게 1000원을 송금하는 요청이 자동으로 실행된다.
    • 사용자가 이미 bank.com에 로그인 된 상태라면, 이 요청은 인증된 상태로 처리된다.

    방지 방법

    • Referer 헤더 검증: 서버는 요청의 Referer 헤더를 확인하여 요청이 신뢰할 수 있는 출처에서 온 것인지 확인할 수 있다.
    • CSRF 토큰 사용: 서버는 각 요청에 대해 고유한 토큰을 생성하고, 이를 폼에 포함시킨다. 서버는 요청이 들어올 때 이 토큰을 검증한다.
    • form 대신 API사용: API를 통해 JSON 데이터로 통신한다면 해당 이슈를 피할 수 있다.

    CSRF 토큰 예시

    • SampleController
    @Controller
    public class SampleContorller {
    
        @GetMapping("/")
        public String showForm() {
            return "form";
        }
    
        @PostMapping("/submit")
        public String  handleFormSubmit(@RequestParam("name") String name, @RequestParam("_csrf") String csrfToken) {
            System.out.println("Received CSRF token: " + csrfToken);
            System.out.println("Received name: " + name);
            return "result";
        }
    }
    • SecurityConfig
    @Configuration
    public class SecurityConfig {
    
        @Bean
        public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                    .authorizeHttpRequests(authorize -> authorize
                            .anyRequest().permitAll()
                    )
                    .csrf(csrf -> csrf
                            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    );
    
            return http.build();
        }
    }

    🧩 XSS

    XSS(Cross-Site Scripting)는 웹 애플리케이션의 취약점을 이용해 악성 스크립트를 다른 사용자의 브라우저에서 실행시키는 공격이다.

    공격 유형

    • 반사형 XSS: 사용자가 입력한 데이터가 즉시 웹 페이지에 반영되어 발생하는 공격
      • 예: 사용자가 http://example.com/search?q=<script>alert(document.cookie)</script>와 같은 URL을 입력한 경우 쿠키 탈취가 가능함
    • 저장형 XSS: 악성 스크립트가 서버에 저장되어 여러 사용자가 해당 스크립트를 실행하게 되는 경우
      • 예: 게시판에 악성 스크립트를 포함한 글을 작성하면 해당 글을 보는 모든 사용자의 브라우저에서 스크립트가 실행됨
    • DOM 기반 XSS: 클라이언트 측에서 JavaScript를 통해 DOM을 동적으로 조작할 때 발생
      • 예: 클라이언트 측 스크립트가 URL 파라미터를 읽어와 DOM에 삽입할 때, 악성 스크립트가 포함될 수 있음
      • 사용자가 http://example.com/#<script>alert('XSS');</script>라는 URL에 접근하면 'XSS'라는 alert 창이 뜸

    [반사형 XSS와 DOM 기반 XSS의 차이]
    반사형 XSS는 서버 측에서 발생하지만, DOM 기반 XSS는 서버 요청 없이 클라이언트 측에서 발생한다.

    XSS 방어 기법

    • 입력 검증 및 인코딩
    • Content Security Policy(CSP): 웹 애플리케이션이 로드할 수 있는 리소스의 출처를 정의하는 HTTP 응답 헤더
    • HTTPOnly 쿠키 사용
    • JavaScript 안전하게 사용하기: 클라이언트 측에서 사용자 입력을 직접적으로 처리하지 않도록 함

    🧩 SQL Injection

    SQL Injection은 공격자가 웹 애플리케이션의 데이터베이스 쿼리에 악의적인 SQL 코드를 삽입하여 데이터베이스를 조작하거나 민감한 정보를 탈취하는 공격 기법이다.

    예시

    1. 공격자가 username 필드에 admin'; --'를 입력함
    2. SQL 쿼리는 SELECT * FROM users WHERE username = 'admin'; --' AND password = 'password'로 변경됨
    3. -- 이후 코드는 주석 처리되어 무시되고, 결과적으로 쿼리는 SELECT * FROM users WHERE username = 'admin';가 되어 공격자가 비밀번호를 입력하지 않아도 인증됨

    SQL Injection 방어 기법

    • Prepared Statements: SQL 쿼리를 미리 컴파일하여 파라미터화된 쿼리를 사용
    • Stored Procedures: DB에서 미리 정의된 저장 프로시저를 호출하여 실행
    • ORM(객체 관계 매핑): Hibernate 같은 ORM 프레임워크를 사용하여 DB 접근을 추상화
    • 입력 검증 및 인코딩
    • 최소 권한 원칙

    🧩 기타 보안 문제들

    • Open Redirect: 공격자가 웹 애플리케이션의 리디렉션 기능을 악용하여 사용자를 악성 사이트로 유도하는 공격
    • Directory Traversal: 공격자가 웹 애플리케이션의 파일 시스템에서 허용되지 않은 파일이나 디렉토리에 접근할 수 있도록 하는 공격
    • Clickjacking: 공격자가 웹 페이지의 투명한 프레임을 사용하여 사용자가 클릭하도록 유도하는 공격
    • Sensitive Data Exposure: 애플리케이션이 민감한 데이터를 충분히 보호하지 않아 공격자가 이를 탈취하는 공격
    • Insecure Deserialization: 공격자가 악의적으로 조작된 객체를 애플리케이션에 전달하여 실행시키는 공격