Post

Java XPath 삽입 코딩 기법

1. 정의

외부 입력값을 적절한 검사과정 없이 XPath 쿼리문 생성을 위한 문자열로 사용하면, 공격자는 프로그래머가 의도하지 않았던 문자열을 전달하여 쿼리문의 의미를 왜곡시키거나 그 구조를 변경하고 임의의 쿼리를 샐행하여 인가되지 않은 데이터를 열람할 수 있다.

xpath-injection

2. 안전한 코딩 기법

  • XPath 쿼리에 사용되는 외부 입력 데이터에 대하여 특수문자(", [, ], /, =, @ 등 ) 및 쿼리 예약어 필터링을 수행하고 인자화된 쿼리문을 지원하는 XQuery를 사용한다.

3. 예제

다음의 예제에서 name의 값으로 user1, passwd의 값으로 'or ''='을 전달하면 다음과 같은 질의문이 생성되어 인증과정을 거치지 않고 로그인할 수 있다.

1
//users/user[login/text()=‘user1' or ''='' and password/text() = “ or ”=“]/home_dir/text()
  • 안전하지 않은 코드의 예
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 외부로 부터 입력을 받음
String name = props.getProperty("name");
String passwd = props.getProperty("password");

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

// 외부 입력이 XPath의 인자로 사용
XPathExpression expr = xpath.compile("//users/user[login/text()='" + name + "' and password/text() = '" + passwd + "']/home_dir/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
    String value = nodes.item(i).getNodeValue();
    if (value.indexOf(">") < 0) {
        System.out.println(value);
    }
}

다음의 예제와 같이 인자화된 질의문을 지원하는 XQuery를 사용하여 미리 질의 골격을 생성하고 이에 인자값을 설정함으로써 외부의 입력으로 인하여 질의 구조가 바뀌는 것을 막을 수 있다.

  • 안전한 코드의 예
1
2
3
4
// dologin.xp 파일
declare variable $loginID as xs:string external;
declare variable $password as xs:string external;
//users/user[@loginID=$loginID and @password=$password]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// XQuery를 이용한 XPath Injection 방지
// 외부로 부터 입력을 받음
String name = props.getProperty("name");
String passwd = props.getProperty("password");
Document doc = new Builder().build("users.xml");
// XQuery를 위한 정보 로딩
XQuery xquery = new XQueryFactory().createXQuery(new File("dologin.xq"));
Map vars = new HashMap();
vars.put("loginID", name);
vars.put("password", passwd);
Nodes results = xquery.execute(doc, null, vars).toNodes();
for (int i=0; i < results.size(); i++) {
 System.out.println(results.get(i).toXML());
}

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.