보안 공부/소스코드 보안약점 진단

소스코드 보안약점 진단 - Private 배열에 Public 데이터 할당

H.J.World 2022. 2. 14. 10:10
728x90
반응형

소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.

SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.

해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.

 

제 6절 캡슐화

중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안약점으로 정보노출, 권한문제 등이 발생할 수 있다.


5. Private 배열에 Public 데이터 할당

가. 개요

public으로 선언된 메소드의 인자가 private선언된 배열에 저장되면, private배열을 외부에서 접근 하여 배열수정과 객체 속성변경이 가능해진다.

나. 보안대책

public으로 선언된 메서드의 인자를 private선언된 배열로 저장되지 않도록 한다. 인자로 들어온 배열의 복사본을 생성하고 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private변수에 할당하여 private선언된 배열과 객체속성에 대한 의도하지 않게 수정되는 것을 방지한다. 만약 배열 객체의 원소 가 String 타입 등과 같이 변경이 되지 않는 경우에는 인자로 들어온 배열의 복사본을 생성하여 할당 한다.

다. 코드예제

public으로 선언된 메서드의 인자를 private선언된 배열로 저장되지 않도록 한다. 인자로 들어온 배열의 복사본을 생성하고 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private변수에 할당하여 private선언된 배열과 객체속성에 대한 의도하지 않게 수정되는 것을 방지한다. 만약 배열 객체의 원소 가 String 타입 등과 같이 변경이 되지 않는 경우에는 인자로 들어온 배열의 복사본을 생성하여 할당 한다.

- 안전하지 않은 코드의 예 JAVA -

1: //userRoles 필드는 private이지만, public인 setUserRoles()를 통해 외부의 배열이 할당되면,
사실상 public 필드가 된다.
2: private UserRole[] userRoles;
3: public void setUserRoles(UserRole[] userRoles) {
4: this.userRoles = userRoles;
5: }

 

- 안전한 코드의 예 JAVA -

인자로 들어온 배열의 복사본을 생성하고 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private변수에 할당하면 private으로 할당된 배열과 원소에 대한 의도하지 않은 수정을 방지 할 수 있다.

1: //객체가 클래스의 private member를 수정하지 않도록 한다.
2: private UserRole[] userRoles;
3: public void setUserRoles(UserRole[] userRoles) {
4: this.userRoles = new UserRole[userRoles.length];
5: for (int i = 0; i < userRoles.length; ++i)
6: this.userRoles[i] = userRoles[i].clone();
7: }

 

라. 진단방법

private 배열이 선언되어 있는지 확인하고(①), public 메소드의 인자로 받은 배열을 private 배열 필드에 직접 할당할 경우 취약하다고 판단한다(②). 이때 선언된 private 배열의 원소가 일반 객체일 경우 각 원소별로 객체를 생성하고 객체 내부의 값을 복사하는지 확인한다. userRoles 필드는 private이지만, public인 setUserRoles()를 통해 외부의 배열이 할당되면, 사실상 public 필드가 된다.

1: public class U496 {
2: private String[] userRoles;--------------------------------①
3: public void setUserRoles(String[] userRoles) {
4: this.userRoles = userRoles;------------------------------②
5: }
6:
7: public void print() {
8: for (int i = 0; i < userRoles.length; i++)
9: System.out.println(userRoles[i]);
10: }
11: }

 

- 정탐코드의 예 -

아래 코드는 새로운 배열을 새로 생성하고 for문을 이용하여 복사하였으나, 배열의 원소가 일반객체 이기 때문에 원본(userRoles)의 주소값만 복사되어 취약하다.

1: private UserRole[] userRoles;
2: …
3: public void setUserRoles(UserRole[] userRoles) {
4: this.userRoles = new UserRole[userRoles.length];
5: for(int i =0; i < userRoles.length; i++) {
6: this.userRoles[i] = userRoles[i]; // 일반 객체일 경우 주소값만 복사된다.
7: }
8: }
728x90
반응형