본문 바로가기
Web Security/SecureCoding

안전하지 않은 리플렉션

by KkingKkang 2023. 2. 1.

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

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

 

안전하지 않은 코드 ▼

public void workType() {
	
    Properties props = new Properties();
    // ...
    if( in != null && in.available() > 0 ) {
    	props.load(in);
        if(props == null || props.isEmpty())
        	return;
    }
    Strong type = props.getProperty("type");
    Worker w;
    
    //외부에서 입력된 type의 값의 유효성을 검증하고 있지 않다. 
    try {
    	Class workClass = Class.forName(type + "Worker");
        w = (Worker) workClass.newInstance();
        w.doActionn();
    } catch(ClassNotFoundException e) {}
    // ...
}

abstract class Worker {
	String work = "";
    public abstract void doAction();
}

 

안전한 코드 ▼

//...
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 = "";
    publicabstract void doAction();
  }

 

 

반응형

댓글