메뉴 건너뛰기

app

캡슐화의 구멍을 막아라: CWE-495 Private 배열 반환

suritam92026.01.18 08:17조회 수 0댓글 0

    • 글자 크기

1. Private 배열 반환의 위험성

CWE-495는 클래스 내부의 private으로 선언된 배열이나 가변 객체(Mutable Object)를 public 메서드를 통해 직접 반환할 때 발생합니다. 자바에서 배열은 참조 타입이므로, 메서드가 원본 배열의 참조 주소를 반환하면 외부 호출자는 이 주소를 통해 클래스 내부의 데이터를 직접 수정할 수 있게 됩니다. 이는 객체의 상태를 외부에서 변경할 수 없도록 설계한 캡슐화(Encapsulation) 원칙을 완전히 무너뜨리며, 시스템의 무결성을 해치는 결과를 초래합니다.

2. 흔히 발생하는 취약한 패턴

주로 클래스 내부의 설정 값이나 권한 목록을 제공할 때 실수하기 쉽습니다.

  • 배열 직접 반환: private String[] roles;를 정의하고 public String[] getRoles() { return roles; }와 같이 그대로 내보내는 경우.

  • 가변 컬렉션 노출: List, Map 등 외부에서 수정 가능한 객체를 get 메서드로 직접 반환하는 경우.

  • 얕은 복사(Shallow Copy): 배열의 주소값만 복사하여 전달함으로써 결과적으로 원본 데이터에 접근 가능하게 만드는 경우.

3. 실무적 대응: 방어적 복사(Defensive Copy)

데이터를 외부로 전달할 때는 반드시 원본과의 연결 고리를 끊어야 합니다.

  • 방어적 복사 수행: 배열을 반환할 때 clone() 메서드나 System.arraycopy()를 사용하여 데이터만 복사된 새로운 배열을 생성해 반환합니다.

  • 불변 객체로 변환: 컬렉션의 경우 Collections.unmodifiableList() 등을 사용하여 수정이 불가능한 뷰(View)를 제공합니다.

  • 필요한 값만 전달: 배열 전체를 넘기기보다 특정 인덱스의 값만 제공하거나, 복사된 리스트를 반환하는 방식을 고려합니다.

4. CWE-495 대응 및 안전한 데이터 반환 자바 코드 예시

Java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;

public class UserSecurityConfig {
    private static final Logger logger = LoggerFactory.getLogger(UserSecurityConfig.class);

    // [보안 위험] private 배열이지만 직접 반환 시 외부에서 수정 가능
    private String[] userRoles = {"USER", "GUEST"};

    /* [위험한 코드] 
    public String[] getUserRoles() {
        return userRoles; // 참조 주소가 노출됨 (CWE-495)
    }
    */

    // [CWE-495 조치] 방어적 복사를 통해 새로운 배열을 반환
    public String[] getUserRoles() {
        if (this.userRoles == null) {
            return new String[0];
        }
        // 원본 배열을 복제하여 반환함으로써 내부 데이터를 보호함
        return this.userRoles.clone(); 
    }

    public void printRoles() {
        logger.debug("Current Internal Roles: {}", Arrays.toString(userRoles));
    }
}

코멘트: "Private이니까 안전하겠지"라는 생각은 자바의 참조 매커니즘 앞에서 무용지물입니다. 외부에서 내가 관리하는 배열의 값을 임의로 바꾼다면, 권한 체크 로직이나 시스템 설정이 순식간에 우회될 수 있습니다. logger.debug()를 통해 내부 상태를 모니터링하되, 데이터를 내보낼 때는 항상 "복사본을 준다"는 원칙을 지키십시오. 이것이 캡슐화를 완성하는 시큐어 코딩의 핵심입니다.

    • 글자 크기
외부의 손길로부터 내부를 격리하라: CWE-496 (by suritam9) 섞여버린 데이터의 비극: CWE-488 & CWE-543 잘못된 세션 정보 노출 (by suritam9)

댓글 달기

첨부 (0)
위로