[시큐어코딩 가이드] Public 메소드로부터 반환된 Private 배열

 

 

 

■ 캡슐화

 

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

 

 

Public 메소드로부터 반환된 Private 배열

 

■ 개요

 

Python은 명시적인 private 선언이 없다. 하지만 대부분의 Python 코드가 따르는 규칙으로 이름 앞에 밑줄(예:__spam)로 시작하면 Private으로 처리된다. 배열을 public으로 선언된 메소드를 통해 반환(return)하면, 그 배열의 레퍼런스가 외부에 공개되어 외부에서 배열 수정과 객체 속성변경이 가능해진다. 

 

배열 뿐 아니라 변경 가능한(mutable) 객체에 대해 모두 발생한다.

 

public - attribute, method는 기본적으로 public

 

protect - attribute, method 앞에 _(single underscore)를 붙여서 표시 함. 실제 제약 보다는 관례적임.

 

private - attribute, method 앞에 __(double underscore)를 붙여서 표시 함. 파이썬은 네임 맹글링(name mangling)으로 private 멤버에 _class__member로 접근은 가능하지만 바람직하지 않음.

 

 

■ 안전한 코딩 기법

 

private로 선언된 배열을 public으로 선언된 메소드를 통해 반환하지 않도록 해야 한다. private 배열에 대한 복사본을 반환하도록 하고 배열의 원소에 대해서는 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private 선언된 배열과 객체 속성에 대한 의도하지 않게 수정되는 것을 방지한다. 

 

만약 배열의 원소가 String 타입 등과 같이 변경이 되지 않는 경우에는 Private 배열의 복사본을 만들고 이를 반환하도록 작성한다.

 

 

코드예제

 

다음 예제는 __를 이용해서 Python의 private 배열을 생성하고 그것을 반환하는 public 메소드를 사용하고 있다. 이 경우 특정 배열 타입에 따라 외부에서 private 배열을 변조할 수 있는 문제를 내포하고 있다.

 

안전하지 않은 코드의 예
import copy
class UserObj():
__private_variable = []
def __init__(self):
pass

# private 배열을 리턴하는 public 메소드를 사용하는 경우 취약함
def get_private_member(self):
return self.__private_variable

 

아래 예제는 내부와 외부의 배열이 서로 참조되는 것을 예방하기 위해 [:]로 새로운 객체를 생성하여 값을 반환하고 있다.

 

안전한 코드의 예
class UserObj():
__private_variable = []
def __init__(self):
pass

# private 배열을 반환하는 경우 [:]를 사용하여 외부와 내부의
# 배열이 서로 참조되지 않도록 해야 한다
def get_private_member(self):
return self.__private_variable[:]

 

 

댓글

Designed by JB FACTORY