![](/media/secure-coding/images/2024/04/16/%EC%8B%9C%ED%81%90%EC%96%B4%EC%BD%94%EB%94%A92_3CHFgBI.jpg)
소프트웨어 개발보안 가이드 분석(2021) : Private 배열에 Public 데이터 할당
Private 배열에 Public 데이터 할당이란?
Private 배열에 Public 데이터를 할당하는 행위는 객체의 캡슐화 원칙을 위배하며, 데이터의 무결성과 보안성을 해칠 수 있습니다. 이 취약점은 객체의 Private 데이터가 외부에서 전달된 데이터의 참조가 되어버리는 상황을 말하며, 데이터가 예상치 못한 방식으로 변경될 수 있음을 의미합니다. 또한, Private 배열에 민감한 정보가 저장되어 있을 때 해당 배열을 Public 메소드를 통해 외부로 노출시킬 경우, 중요한 데이터가 유출되거나 조작될 수 있으며, 애플리케이션의 보안성이 크게 약화될 수 있습니다.
공격 메커니즘
Private 배열에 Public 데이터 할당 취약점의 공격 메커니즘은 주로 다음과 같습니다.
- 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 데이터 할당으로 발생할 수 있는 취약점을 보안하기 위해 다음과 같은 방법을 사용할 수 있습니다.
- 데이터 복사: 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 배열을 반환할 때도 깊은 복사를 사용함으로써 캡슐화를 유지하고 외부에서 객체의 내부 상태를 변경할 수 없도록 합니다.