Array Assignment in Java
bindon
2020-02-26
Secure Coding
Introduction
Java에서 클래스 작성 시 생성자(Constructor) 또는 Setter를 통해 인스턴스의 값을 할당하게 되는데, 할당하려는 값이 Call by Reference로 동작하는 값(e.g. array)인 경우 assignment(“=”) 연산자를 이용하여 값을 할당하게 되면 외부에서 변조가 가능한 문제가 존재한다. 이는 클래스 작성에만 해당되는 내용은 아니며, 발생하는 메커니즘을 파악하면 어렵지 않게 대처할 수 있다.
Vulnerable Case
- main에서 String[] 배열을 정의하여 setArray를 통해 setterClass의 인스턴스에 값을 할당
- 인스턴스에서 getArray의 첫 번째 값을 읽어오면 before가 출력됨
- 다시 setArray()를 호출하는 것이 아닌, 처음 정의한 array 배열에 접근하여 문자열을 after로 수정
- 인스턴스에서 getArray의 첫 번째 값을 읽어왔을 때 before가 출력되는 것이 아닌 after가 출력됨
package io.github.bindon;
class SetterClass {
private String[] array;
public String[] getArray() {
return array;
}
// setArray(String... array)
public void setArray(String[] array) {
this.array = array;
}
}
public class SetterTest {
public static void main(String[] args) {
// Initialize
String[] array = {"before"};
SetterClass setterClass = new SetterClass();
// Set array
setterClass.setArray(array);
System.out.println(setterClass.getArray()[0]);
// Change array
array[0] = "after";
System.out.println(setterClass.getArray()[0]);
}
}
- Result
before
after
Good Practice
Vulnerable Case의 문제를 해결하기 위해서는 clone() 함수를 이용하여 내부의 데이터들을 복사하면 해당 문제가 발생하지 않는다.
package io.github.bindon;
class SetterClass {
private String[] array;
public String[] getArray() {
return array;
}
// setArray(String... array)
public void setArray(String[] array) {
this.array = array.clone();
}
}
public class SetterTest {
public static void main(String[] args) {
// Initialize
String[] array = {"before"};
SetterClass setterClass = new SetterClass();
// Set array
setterClass.setArray(array);
System.out.println(setterClass.getArray()[0]);
// Change array
array[0] = "after";
System.out.println(setterClass.getArray()[0]);
}
}
- Result
before
before
Secure Coding Post List
TITLE | DATE | StringBuilder in Java | 2020-02-26 | HTTP Response Splitting | 2020-02-26 | Array Assignment in Java | 2020-02-26 |
---|