GeoTools: a second XML parser lost the access limits
GeoTools is a Java library for map data, and GeoServer and GeoNetwork are map servers built on it. GeoServer has a public web interface called WFS, which answers requests for map features. These requests can be XML documents.
An XML document can refer to other files. A schema is a file that describes which elements a document may contain, and a document can name its schema by location. For example, a document about roads might point to https://example.org/roads.xsd. An XML parser loads such references by itself, with no extra code from the application.
This is risky on a server, because a stranger may write the document, and the parser runs with the server's access. So applications set an entity resolver. This is a function that the parser calls before it loads a reference, and it can allow or refuse each one. GeoServer uses one to hold references to an allowed list.
ParserHandler.java and Schemas.java before the fix.# ParserHandler: the main parser
set_entity_resolver(resolver):
self.resolver = resolver
resolve_entity(reference):
# Allows or refuses each reference.
return self.resolver.resolve(reference)
load_schemas(attrs):
for location in schema_locations(attrs):
# self.resolver is not passed along.
schema = Schemas.parse(location)
self.schemas.add(schema)
# Schemas: uses the Eclipse XSD parser
Schemas.parse(location):
resources = ResourceSet()
# No resolver checks this fetch.
data = read_uri(location, resources)
return resources.load_schema(data)In the pseudocode, the main parser calls resolve_entity for each reference it meets, and the resolver can refuse it. load_schemas then reads the schema locations from the document, and it hands each one to Schemas.parse. That function uses a second parser, from the Eclipse XSD library. The advisory says that the Schemas class never received the resolver. So read_uri could load a reference that the main parser would refuse.
The failed assumption is that a rule set on one parser applies to all of them. Setting a resolver changes one object. It does nothing for another object, unless the code passes the resolver along. Both parsers read input from the same request, so the weaker one sets the real limit.
The result has two parts. A reference could name a file, so the server could disclose files that its process can read. A reference could also name a network address, so the server would send a request there. This second part is server-side request forgery, where an outsider makes a server send requests from inside its own network.
The CVE record rates the library at 9.9, and GeoServer rates its own product at 8.2.
GeoServer credits XBOW, an autonomous security tool whose report a researcher reviewed before submission. An independent report also arrived. GeoTools released fixes in versions 33.1, 32.3, 31.7 and 28.6.1.