
GeoServer & GeoTools SQL 인젝션 (CVE-2023-25157 & CVE-2023-25158)
이 저장소는 GeoServer 플랫폼 및 GeoTools 라이브러리에서 발견된 SQL 삽입 취약점에 대한 상세한 설명과 재현 단계를 포함하고 있습니다. 이 취약점에는 GeoServer의 경우 CVE-2023-25157, GeoTools의 경우 CVE-2023-25158 식별자가 할당되었습니다.
GeoServer는 Java로 작성된 오픈소스 소프트웨어 서버로, 지리공간 데이터를 보고, 편집하고, 공유할 수 있는 기능을 제공합니다. 이는 GIS(지리정보시스템) 데이터베이스, 웹 기반 데이터, 개인 데이터셋 등 다양한 출처의 지리공간 데이터를 배포하기 위한 유연하고 효율적인 솔루션으로 설계되었습니다.
GeoServer는 데이터 공유를 위해 Web Feature Service(WFS), Web Map Service(WMS), Web Coverage Service(WCS)를 포함한 OGC(Open Geospatial Consortium) 표준을 준수합니다. 이러한 표준 준수는 GeoServer의 데이터가 맞춤형 GIS 소프트웨어부터 기성 솔루션에 이르기까지 다양한 애플리케이션에서 사용될 수 있음을 의미합니다.
GeoServer는 주로 Spring Framework를 기반으로 구축되었지만, 다음과 같은 여러 다른 라이브러리 및 프레임워크도 사용합니다:
GeoTools: 지리공간 데이터를 위한 도구를 제공하는 오픈소스 Java 라이브러리입니다. GeoServer는 데이터 읽기, 쓰기, 변환과 같은 많은 핵심 기능에 GeoTools를 사용합니다.해당 취약점은 OGC(Open Geospatial Consortium) 표준에 의해 정의된 필터 및 함수 표현식에 깊이 내재되어 있습니다. 이러한 표현식은 지리공간 데이터 쿼리 및 조작의 중추를 형성하며, GeoServer 및 GeoTools와 같은 시스템의 기능에 중추적인 역할을 합니다.
이러한 취약점이 악용되면 심각한 보안 위반으로 이어질 수 있습니다. 정보의 무단 공개가 주요 관심사이며, 공격자는 데이터베이스에 저장된 민감한 데이터에 접근할 수 있습니다. 무단 수정도 또 다른 잠재적 결과로, 공격자가 데이터를 자신에게 유리하게 조작할 수 있습니다. 또한 이러한 취약점은 서비스 중단을 용이하게 하여 성공적인 악용 시 서비스를 사용할 수 없게 만들 수 있습니다.
다음은 식별된 각 취약점에 대한 심층 분석을 제공합니다. 각 취약점은 구체적인 특성, 발현 조건 및 악용 시 잠재적 영향에 대해 자세히 설명합니다. 다음은 GeoServer에서 발견된 취약점에 대한 상세 분석입니다:
PropertyIsLike 필터: 이 취약점은 PropertyIsLike 필터가 문자열 필드와 함께 관계형 데이터베이스 기반 저장소, 인코딩 함수가 활성화된 PostGIS DataStore, 또는 인덱스가 관계형 데이터베이스에 저장된 이미지 모자이크와 함께 사용될 때 존재합니다.strEndsWith 함수: 이 취약점은 인코딩 함수가 활성화된 PostGIS DataStore와 함께 strEndsWith 함수가 사용될 때 발생합니다.strStartsWith 함수: 이 취약점은 인코딩 함수가 활성화된 PostGIS DataStore와 함께 strStartsWith 함수가 사용될 때 발견됩니다.FeatureId 필터: 이 취약점은 FeatureId 필터가 문자열 기본 키 열이 있는 모든 데이터베이스 테이블과 함께 사용되고 준비된 문(Prepared Statement)이 비활성화된 경우에 존재합니다.jsonArrayContains 함수: 이 취약점은 jsonArrayContains 함수가 문자열 또는 JSON 필드와 함께 PostGIS 또는 Oracle DataStore에서 사용될 때 발견됩니다(GeoServer 2.22.0 이상 버전에서만 해당).DWithin 필터: 이 취약점은 DWithin 필터가 Oracle DataStore와 함께 사용될 때 발견됩니다.그리고 GeoTools에서 발견된 취약점에 대한 상세 분석은 다음과 같습니다:
PropertyIsLike 필터:
strEndsWith 함수:
strStartsWith 함수:
FeatureId 필터:
jsonArrayContains 함수:
DWithin 필터:
CVE-2023-25157 GeoServer SQL Injection 취약점의 영향을 받습니다.CVE-2023-25158 GeoTools SQL Injection 취약점의 영향을 받습니다.GeoServer SQL Injection(CVE-2023-25157) 및 GeoTools SQL Injection(CVE-2023-25158) 취약점 모두에 대해 권장되는 조치는 명시된 버전 이상으로 업그레이드하는 것입니다. 이 업그레이드가 완료되면 추가 조치가 필요하지 않습니다. 그러나 신속하게 업그레이드하기 어려운 사용자를 위해 Geo 팀은 아래에 몇 가지 대체 솔루션을 제공했습니다.
strEndsWith, strStartsWith 취약점을 완화하기 위해 PostGIS Datastore 인코딩 함수 설정 비활성화(게시된 피처 유형에 문자열 필드가 있는 경우 Like 필터에는 완화책이 없음).
FeatureId 취약점을 완화하기 위해 PostGIS DataStore preparedStatements 설정 활성화.```java
Map<String, Object> params = new HashMap < >();
params.put("dbtype", "postgis");
params.put("host", "localhost");
params.put("port", 5432);
params.put("schema", "public");
params.put("database", "database");
params.put("user", "postgres");
params.put("passwd", "postgres");
params.put("preparedStatements", true); // mitigation
params.put("encode functions", false); // mitigation
DataStore dataStore = DataStoreFinder.getDataStore(params);
- 공격 표면을 제한하는 좋은 방법으로, 연결 풀에서 사용되는 데이터베이스 계정에 최소한의 필요한 권한만 부여하는 것이 중요합니다(예: WFS-T/임포터/REST 과립 수집을 사용하지 않는 경우 읽기 전용, 프로덕션 사용에 필요한 스키마와 테이블로만 접근 제한).
- `PropertyIsLike` 필터에 대한 완화 방법은 없으며, 업그레이드할 수 있을 때까지 데이터베이스 DataStore를 비활성화하는 것을 선택할 수 있습니다.
- Oracle DataStore의 `DWithin`에 대한 완화 방법은 없으며, 업그레이드할 수 있을 때까지 Oracle DataStore를 비활성화하는 것을 선택할 수 있습니다.
### <b>패치 분석: GitHub 이슈 및 관련 커밋</b>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
아래에는 GeoServer 및 GeoTools에서 발견된 SQL 삽입 취약점과 관련된 몇 가지 관련 JIRA 이슈에 대한 링크가 제공됩니다. 이 링크는 이러한 특정 취약점과 관련된 중요한 데이터, 논의 및 제안된 해결책에 접근할 수 있게 해줍니다.
- [GEOS-10842: JDBCConfig: SQL 쿼리에서 사용자 입력 이스케이프](https://osgeo-org.atlassian.net/browse/GEOS-10842)
- [GEOS-10839: JDBCConfig: SQL 주석 및 예쁘게 출력을 비활성화하는 JDBC 구성 매개변수 추가](https://osgeo-org.atlassian.net/browse/GEOS-10839)
- [GEOT-7302: SQL 쿼리에서 사용자 입력 이스케이프](https://osgeo-org.atlassian.net/browse/GEOT-7302)
[`geoserver/geoserver@145a8af`](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b) 커밋을 살펴보면 각각 다음과 같은 변경 사항을 명확히 볼 수 있습니다:
- [`ConfigDatabase.java`](https://github.com/geoserver/geoserver/blob/b05287608048d0f6e36c264f43fe15aa5dfb5130/src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/ConfigDatabase.java)에서 속성 필드 추가와 이 속성 필드를 포함하도록 생성자 변경이 이루어졌습니다. 이는 데이터베이스 구성을 더 많이 사용자 정의할 수 있게 하여 잠재적으로 향상된 보안 조치를 가능하게 합니다. [`NamedParameterJdbcTemplate`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.html)은 Spring Framework에서 제공하는 클래스로, 기존의 자리 표시자('?') 인수를 사용하여 JDBC 문을 프로그래밍하는 대신 명명된 매개변수를 사용하여 JDBC 문을 프로그래밍하는 지원을 추가합니다. 이 커밋에서 `ConfigDatabase` 생성자는 `DataSource`를 받아 `NamedParameterJdbcTemplate`을 생성하도록 업데이트됩니다. 명명된 매개변수는 가독성을 향상시키고 인수가 매개변수화되어 SQL 명령의 일부가 아니라는 점을 명확히 하여 SQL 삽입 공격을 방지할 수도 있습니다.
> [src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/ConfigDatabase.java](https://github.com/geoserver/geoserver/commit/145a8af798590288d270b240235e89c8f0b62e?diff=split#diff-1b49bc6af3f36da2ebf7a0d8d3af3fa3697ccee91bf67a690f99837ee2730bed)```java
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.jdbcconfig.internal;
// import some packages...
import org.geoserver.jdbcloader.JDBCLoaderProperties;
public class ConfigDatabase implements ApplicationContextAware {
public static final Logger LOGGER = Logging.getLogger(ConfigDatabase.class);
private static final int LOCK_TIMEOUT_SECONDS = 60;
private Dialect dialect;
private JDBCLoaderProperties properties;
// rest of the codebase
protected ConfigDatabase() {
//
}