소프트웨어 개발보안 가이드 분석(2021) : Private 배열에 Public 데이터 할당

Private 배열에 Public 데이터 할당이란?

Private 배열에 Public 데이터를 할당하는 행위는 객체의 캡슐화 원칙을 위배하며, 데이터의 무결성과 보안성을 해칠 수 있습니다. 이 취약점은 객체의 Private 데이터가 외부에서 전달된 데이터의 참조가 되어버리는 상황을 말하며, 데이터가 예상치 못한 방식으로 변경될 수 있음을 의미합니다. 또한, Private 배열에 민감한 정보가 저장되어 있을 때 해당 배열을 Public 메소드를 통해 외부로 노출시킬 경우, 중요한 데이터가 유출되거나 조작될 수 있으며, 애플리케이션의 보안성이 크게 약화될 수 있습니다.

 

공격 메커니즘

Private 배열에 Public 데이터 할당 취약점의 공격 메커니즘은 주로 다음과 같습니다.

  1. Public 메소드의 인자를 Private 배열에 저장: Public으로 선언된 메소드의 인자가 Private으로 선언된 배열에 저장될 때, 외부에서 Private 배열에 접근하고 수정하여 객체 속성을 변경할 수 있습니다.

Private 배열에 Public 데이터 할당 취약점은 객체의 캡슐화를 해치고, 객체의 안전성을 위협할 수 있습니다.

 

취약한 웹 애플리케이션의 예

다음 코드는 Private 배열에 Public 데이터를 할당하고, 이 Private 배열을 반환하는 메소드를 포함하는 예제 코드입니다. 이 코드는 객체의 캡슐화 원칙을 위반하며, 외부에서 객체의 내부 상태를 변경할 수 있는 취약점이 존재합니다.

// Private 배열에 Public 데이터 할당
public void setPrivateData(String[] data) {
    this.privateData = data;
}

// Private 배열 반환
public String[] getPrivateData() {
    return privateData;
}

public static void main(String[] args) {
    VulnerableExample example = new VulnerableExample();

    // Public 데이터
    String[] publicData = {"public1", "public2", "public3"};

    // Private 배열에 Public 데이터 할당
    example.setPrivateData(publicData);

    // Private 배열 반환
    String[] retrievedData = example.getPrivateData();

    // Private 배열에 할당된 데이터 출력
    for (String data : retrievedData) {
        System.out.println(data);
    }
}

위의 코드에서는 setPrivateData 메소드를 통해 Private 배열에 Public 데이터를 할당하고, getPrivateData 메소드를 통해 Private 배열을 반환합니다. 이렇게 되면 외부에서 Public 데이터에 접근하여 Private 배열의 데이터를 읽거나 수정할 수 있습니다.

 

시큐어코딩 적용 방법

Private 배열에 Public 데이터 할당으로 발생할 수 있는 취약점을 보안하기 위해 다음과 같은 방법을 사용할 수 있습니다.

  1. 데이터 복사: clone() 메소드, Arrays.copyOf 메소드 등을 사용하여 원본 배열과는 독립적인 배열을 생성함으로써 Private 변수와 객체 속성에 대한 의도치 않은 수정을 방지합니다.

​

이러한 방어 방법은 객체의 캡슐화를 유지하고, 외부로부터의 무단 접근이나 수정을 방지하여 객체의 안전성을 보호하는 데 중요한 역할을 합니다.

​

다음 코드는 Arrays.copyOf 메소드를 사용하여 데이터를 Private 배열에 할당하거나 반환할 때 깊은 복사(Deep copy)를 수행하는 코드입니다.

import java.util.Arrays;

public class SecureExample {
    private String[] privateData;

    // Private 배열에 복사된 데이터 할당
    public void setPrivateData(String[] data) {
        if (data != null) {
            this.privateData = Arrays.copyOf(data, data.length);
        } else {
            this.privateData = null;
        }
    }

    // Private 배열의 복사본 반환
    public String[] getPrivateData() {
        if (privateData != null) {
            return Arrays.copyOf(privateData, privateData.length);
        } else {
            return null;
        }
    }

    public static void main(String[] args) {
        SecureExample example = new SecureExample();

        // Public 데이터
        String[] publicData = {"public1", "public2", "public3"};

        // Private 배열에 복사된 Public 데이터 할당
        example.setPrivateData(publicData);

        // Private 배열의 복사본 반환
        String[] retrievedData = example.getPrivateData();

        // Private 배열에 할당된 데이터 출력
        for (String data : retrievedData) {
            System.out.println(data);
        }
    }
}

Arrays.copyOf 메소드를 사용하여 배열의 참조가 아닌 실제 값을 복사함으로써, 원본 배열과 독립적인 새 배열을 만듭니다. 이 과정을 깊은 복사라고 하며, 이를 통해 private 배열에 public 데이터를 할당하고, private 배열을 반환할 때도 깊은 복사를 사용함으로써 캡슐화를 유지하고 외부에서 객체의 내부 상태를 변경할 수 없도록 합니다.

  • 이전 소프트웨어 개발보안 가이드 분석(2021) : Public 메소드 부터 반환된 Private 배열
  • 다음 소프트웨어 개발보안 가이드 분석(2021) : DNS lookup에 의존한 보안결정