본문 바로가기
04. 시큐어코딩

시큐어코딩(24) - Unsafe Reflection

by 김덕환 2017. 11. 23.
반응형

1. 정의


안전하지 않은 리플렉션 (Use of Externally-Controlled Input to Select Classes or Code, Unsafe Reflection)


동적 클래스 적재(loading)에 외부의 검증되지 않은 입력을 사용할 경우, 공격자가 외부 입력을 변조하여 의도하지 않은 클래스가 적대되도록 할 수 있다. 



2. 해결방법


- 외부의 입력을 직접 클래스 이름으로 사용하지 말고, 외부의 입력에 따리 미리 정한 후보(white list) 중에서 적절한 클래스 이름을 선택하도록 한다. 



3. 예제


========================== 안전하지 않은 코드의 예 ==========================


public void workType()

{

Properties props = new Properties();


if ( in !=null && in.available() > 0 )

{

props.load(in);

if ( props == null || props.isEmpty() )

return ;

}

String type = props.getProperty("type");

Worker w;


// 외부에서 입력된 type값의 유효성을 검증하지 않고 있다. 

try

{

Class workClass = Class.forName(type + "Worker");

w = (Worker) workClass.newInstance();

w.doAction();

}

catch (ClassNotFoundException e) { ... }


}


abstract class Worker

{

String work = "";

public abstract void doAction();

}


============================================================================


위의 예제는 외부 입력(type)을 클래스 이름의 일부로 사용하여 객체를 생성하고 있다. 이 경우 공격자가 외부 입력을 변조하여 부적절한 다른 클래스가 적재되도록 할 수 있다. 



============================== 안전한 코드의 예 =============================


public void workType()

{

Properties props = new Properties();


if ( in !=null && in.available() > 0 )

{

props.load(in);

if ( props == null || props.isEmpty() )

return ;

}

String type = props.getProperty("type");

Worker w;


// 외부 입력되는 값에 대해 유효성을 검증하여야 한다. 

if (type == null || "".equals(type)) return;

if (type.equals("Slow"))

{

w = new SlowWorker();

w.doAction();

}

else if (type.equals("Hard"))

{

w = new HardWorker();

w.doAction();

}

else

{

System.err.printf("No propper class name!");

}


}


abstract class Worker

{

String work = "";

public abstract void doAction();

}


============================================================================


위의 코드와 같이 외부의 입력(type)에 따라, 미리 정한 후보(white list) 중에서 적절한 클래스 이름이 설정되도록 함으로써, 외부의 악의적인 입력에 의하여 부적절한 클래스가 사용되는 위험성을 제거할 수 있다. 

반응형