외부 입력을 통한 시스템 설정 조작 (External Configuration Control)

External Control of System or Configuration Setting

설명

검증되지 않은 사용자 입력으로 데이터베이스 연결의 카탈로그를 선택하면, 애플리케이션이 의도하지 않은 데이터 영역에서 작업할 수 있습니다. java.sql.Connection.setCatalog()의 지원과 동작은 드라이버에 따라 달라집니다. 카탈로그 변경 자체가 데이터베이스 계정의 권한을 높이지는 않지만, 그 계정이 접근할 수 있는 다른 데이터가 잘못 조회·변경될 수 있습니다.

잠재적 영향

  • 데이터베이스 조작: 공격자가 다른 데이터베이스로 연결을 변경하여 원하지 않는 데이터에 접근하거나 수정할 수 있습니다.
  • 서비스 중단: 존재하지 않는 데이터베이스로 설정하면 애플리케이션이 정상적으로 작동하지 않을 수 있습니다.
  • 접근 경계 위반: 애플리케이션 계정이 여러 카탈로그에 접근할 수 있으면 사용자나 테넌트 간 데이터 구분이 깨질 수 있습니다.

해결 방법

  1. 사용자 입력을 기반으로 데이터베이스 설정을 변경하지 않기

    • 데이터베이스 설정은 애플리케이션 내부에서 정의된 값만 사용해야 합니다.
  2. 허용된 값만 선택 가능하도록 제한하기

    • 서버가 관리하는 목록에서만 선택하게 하고, 현재 사용자가 그 카탈로그에 접근할 권한도 확인하세요.
  3. 보안 정책 적용

    • 동적 선택이 필요하지 않으면 연결 구성을 고정하세요. 필요한 경우 요청별 권한과 연결 풀의 상태 초기화를 확인해 다음 요청에 설정이 남지 않게 하세요.

예시

Java 9 이상과 javax.servlet API를 사용하는 발췌입니다. 변경 후 목록은 예시이며 모든 호출자에게 허용된 카탈로그라고 가정합니다. 사용자별 권한이 다르면 별도 인가 검사가 필요합니다.

변경 전

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;

public class UnsafeDatabaseConfig {
    public void setDatabase(HttpServletRequest request, Connection connection) throws SQLException {
        String catalog = request.getParameter("db"); // 사용자 입력값을 직접 사용
        connection.setCatalog(catalog);
    }
}

변경 후

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;

public class SafeDatabaseConfig {
    private static final Set<String> ALLOWED_CATALOGS = Set.of("main_db", "backup_db");

    public void setDatabase(HttpServletRequest request, Connection connection) throws SQLException {
        String catalog = request.getParameter("db");

        if (catalog == null || !ALLOWED_CATALOGS.contains(catalog)) {
            throw new SecurityException("Invalid database selection");
        }

        connection.setCatalog(catalog);
    }
}

설명:

  • 변경 전:
    • 입력을 검증 없이 setCatalog()에 전달하여, 드라이버와 계정이 허용하는 범위에서 의도하지 않은 카탈로그를 선택할 수 있습니다.
  • 변경 후:
    • 허용된 데이터베이스 목록을 정의하고(ALLOWED_CATALOGS), 사용자 입력이 이 목록에 포함된 경우에만 setCatalog()를 실행하도록 제한합니다.

참조