Java 시스템 또는 구성 설정의 외부 제어
1. 정의
시스템 설정이나 구성요소를 외부에서 제어할 수 있으면 예상치 못한 결과(예: 서비스 중단)를 초래하거나 악용될 가능성이 있다.
2. 안전한 코딩 기법
- 외부의 입력을 Connection.setCatalog() 메소드의 인자값을 생성하는데 사용하지 않도록 한다. 불가피하게 사용해야 한다면, 외부의 입력을 화이트리스트 방식으로 검사한 후 사용한다.
3. 예제
외부의 입력(catalog)이 JDBC의 활성화된 카탈로그를 설정하는 데 사용되고 있다. 이때 존재하지 않는 카탈로그나 권한이 없는 카탈로그 이름이 전달되면 예외상황을 발생할 수 있다.
- 안전하지 않은 코드의 예
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void setCatalog() {
try {
InitialContext ctx = new InitialContext();
DataSource datasource = (DataSource) ctx.lookup("jdbc:ocl:orcl");
Connection con = datasource.getConnection();
Properties props = new Properties();
String fileName = "file.properties";
FileInputStream in = new FileInputStream(fileName);
props.load(in);
// catalog 정보는 외부로부터 유입되는 정보
String catalog = props.getProperty("catalog");
// catalog 정보를 DB Connection을 위해서 해당 값을 체크하지 않고, DB 카탈로그 정보에 지정함
con.setCatalog(catalog);
con.close();
} catch (SQLException ex) {
System.err.println("SQLException Occured");
} catch (NamingException e) {
System.err.println("NamingException Occured");
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException Occured");
} catch (IOException e) {
System.err.println("IOException Occured");
}
}
외부의 입력값에 따라 카탈로그 이름이 바뀌어야 할 경우에는 해당 문자열을 직접 사용하지 말고, 미리 정의된 적절한 카탈로그 이름 중에 선택하여 사용한다.
- 안전한 코드의 예
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public void setCatalog() {
try {
// caltalog 값으로 c1과 c2를 사용할 경우
InitialContext ctx = new InitialContext();
DataSource datasource = (DataSource) ctx.lookup("jdbc:ocl:orcl");
Connection con = datasource.getConnection();
Properties props = new Properties();
String fileName= "file.properties";
String catalog;
FileInputStream in = new FileInputStream(fileName);
if (in != null && in.available() > 0) {
props.load(in);
if (props == null || props.isEmpty()) catalog = "c1";
else
catalog = props.getProperty("catalog");
} else {
catalog = "c1";
}
// 외부 유입 변수(catalog)에 대하서 값을 반드시 체크하고 걸러야 한다.
if ("c1".equals(catalog))
con.setCatalog("c1");
else
con.setCatalog("c2");
con.close();
} catch (SQLException ex) {
System.err.println("SQLException Occured");
} catch (NamingException e) {
System.err.println("NamingException Occured");
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException Occured");
} catch (IOException e) {
System.err.println("IOException Occured");
}
}
[출처 및 참고]
This post is licensed under CC BY 4.0 by the author.