Aug 20, 2026·6 min read·2 visits
Multiple vulnerabilities in GeoLens allow unauthorized metadata and map tile disclosure, unauthenticated Denial of Service, and administrative takeover via weak default credentials.
GeoLens before version 1.2.4 contains multiple critical-tier security vulnerabilities including improper authorization in metadata access, tile cache scope leakage, dataset title enumeration, weak default credentials, and denial of service via STAC POST search.
GeoLens is a self-hosted geospatial data catalog. Version 1.2.4 resolves a suite of vulnerabilities designated as Tier-0 Security Hardening. These vulnerabilities compromise resource authorization, data confidentiality, and system availability.
At the core of the findings is an architectural pattern where the application authorizes access to a specific resource identifier but subsequently serves a different, un-re-authorized resource. Additionally, the software exposes private map tiles via cache-poisoning vectors and allows unauthenticated denial of service through complex spatial query payloads.
This analysis details the root causes of these vulnerabilities, walks through the patched code paths, and provides remediation guidance to secure production deployments.
The primary authorization vulnerability (SEC-001) occurs within the record sub-resource endpoints. The application gated read access to sub-resources solely by verifying if the user was authenticated. It failed to check if the caller had authorization to access the specific dataset backing the record. Consequently, any authenticated user could query contact details, keywords, and distribution URLs of private catalog records.
The tile caching vulnerability (SEC-002 and SEC-009) stems from improper cache-control headers. The raster tile proxy endpoint hardcoded the response header Cache-Control: public, max-age=3600. The reverse proxy cached these responses using a key containing only the coordinate paths. This allowed unauthenticated users to fetch cached tiles belonging to private datasets. In the vector tile router, the logic failed to specify a private cache scope after validating signature tokens, defaulting instead to a public scope.
The STAC search vulnerability (SEC-023) is caused by asymmetric validation rules between GET and POST handlers. The GET endpoint enforced a maximum length of 10,000 characters on spatial geometry parameters, whereas the POST endpoint accepted unrestricted JSON geometry payloads. The database backend exhausted its memory and CPU resources attempting to parse massive GeoJSON polygons via expensive spatial intersection operations.
The fix for SEC-001 redirects record authorization to the dataset's role-based access control handler. Below is the updated routing logic that verifies the backing dataset's visibility.
# backend/app/modules/catalog/records/router.py
async def _check_record_read_access(
record_id: uuid.UUID,
user: Identity | None,
) -> None:
record = await get_record(db, record_id)
if record is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Record not found"
)
# Delegate to the backing dataset to enforce proper RBAC
dataset = (
await db.execute(
select(Dataset)
.options(joinedload(Dataset.record))
.where(Dataset.record_id == record_id)
)
).scalars().first()
if dataset is not None:
try:
await check_dataset_access_or_anonymous(db, dataset, dataset.id, user)
except HTTPException:
# Normalize response to prevent resource enumeration
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Record not found"
)
returnFor SEC-002, the response headers are updated to check the backend authorization status. If the dataset requires authentication, the router sets Cache-Control: private, no-store to instruct Nginx and other downstream proxies not to cache the spatial data.
# backend/app/processing/tiles/router.py
cache_status = auth_resp.headers.get("X-GeoLens-Cache-Status", "private")
if cache_status == "public":
cache_control = "public, max-age=3600"
else:
cache_control = "private, no-store"
return Response(
content=resp.content,
media_type=resp.headers.get("content-type", "image/png"),
headers={"Cache-Control": cache_control},
)For SEC-023, the StacSearchBody class now includes a field validator that serializes the intersects parameter to evaluate its string length before processing. If the length exceeds 10,000 characters, the request is rejected immediately.
# backend/app/standards/stac/router.py
@field_validator("intersects")
@classmethod
def _cap_intersects_size(cls, v: dict | None) -> dict | None:
max_serialized = 10000
if v is not None and len(json.dumps(v)) > max_serialized:
raise ValueError(
f"intersects GeoJSON too large (max {max_serialized} serialized characters)"
)
return vExploitation of SEC-001 requires an authenticated session. An attacker with low-privilege access can perform sequential UUID scanning or dictionary attacks against the /records/{id}/contacts endpoint. Because the endpoint did not check dataset ownership, successful requests return the PII of dataset contacts directly.
GET /records/550e8400-e29b-41d4-a716-446655440000/contacts HTTP/1.1
Host: geolens.internal
Authorization: Bearer <low_privilege_token>
Exploitation of SEC-002 relies on cache key manipulation. An attacker first requests a private dataset tile utilizing valid credentials. The reverse proxy stores the resulting image tile under the cache key of the coordinate path. Subsequently, an unauthenticated attacker requests the same tile without credentials. The reverse proxy serves the cached tile directly from memory.
GET /raster/dataset-uuid/10/512/341 HTTP/1.1
Host: geolens.internal
# No Authorization header provided, but cached response is returned
To execute the denial of service (SEC-023), an unauthenticated attacker transmits a crafted POST request containing a deeply nested or highly complex multi-polygon. The target database attempts to resolve the spatial intersection, consuming all available worker connections.
POST /stac/search HTTP/1.1
Host: geolens.internal
Content-Type: application/json
{
"intersects": {
"type": "Polygon",
"coordinates": [[[0.0, 0.0], [0.1, 0.1], [0.2, 0.2]]]
}
}
The cumulative impact of these vulnerabilities is classified as High. SEC-001 results in the exposure of sensitive database contact information, which represents a violation of data privacy policies. SEC-002 allows unauthenticated external actors to harvest restricted geospatial image layers, compromising proprietary mapping data.
SEC-010 and SEC-011 expose the administration panel and PostgreSQL database to complete takeover. The default passwords admin and geolens are widely known, making any internet-accessible deployment susceptible to automated brute-force scripts.
Finally, SEC-023 enables attackers to disrupt service availability. Because the STAC search endpoint is unauthenticated, a single malicious client can lock database connection pools, inducing persistent downtime for all legitimate API clients.
Upgrading to GeoLens version 1.2.4 is the recommended remediation path. The updated installer script generates cryptographically secure passwords from /dev/urandom and automatically patches environment files. Existing deployments should verify that database passwords have been rotated away from the default value of geolens.
If upgrading is not immediately possible, implement the following web application firewall (WAF) rules to filter incoming traffic. Limit the payload size on /stac/search to block large GeoJSON arrays.
SecRule REQUEST_URI "@beginsWith /stac/search" \
"id:100001,phase:1,deny,status:413,t:none,chain"
SecRule REQUEST_BODY_LENGTH "@gt 51200"
Additionally, configure downstream caching layers to strip cache headers on tile queries unless the dataset is explicitly configured as public. Ensure that Nginx reverse proxies respect the no-store Cache-Control header.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Attribute | Detail |
|---|---|
| CWE ID | CWE-285 |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.8 |
| EPSS Score | 0.001 |
| Impact | Data Disclosure / System Compromise |
| Exploit Status | none |
| CISA KEV Status | Not Listed |
A security vulnerability in Copier versions 9.5.0 through 9.15.1 allows unauthenticated remote code execution via crafted HTTP requests or local paths containing traversal sequences. The trust-evaluation mechanism compares target repository paths or URLs against trusted prefixes using unnormalized string comparison, while the subsequent fetching mechanism normalizes the path before cloning. Attackers can exploit this asymmetry to bypass security warning prompts and execute arbitrary commands under the local user context.
CVE-2026-55694 is a chained Information Disclosure and Insecure Direct Object Reference (IDOR) vulnerability in Snipe-IT prior to version 8.6.3. The vulnerability allows authenticated, restricted users to completely bypass randomized file-naming security controls, leak the obfuscated filenames of signed End User License Agreements (EULAs), and subsequently download these confidential documents across tenant boundaries.
Snipe-IT is an IT asset/license management system. Prior to 8.6.3, any activated account can request /maintenances/{id} and read maintenance records for assets in the same company without asset or maintenance permission. app/Http/Controllers/MaintenancesController.php show() renders the record without authorize(), while company-scoped route-model binding only prevents access to other companies. Disclosed fields include asset tags, suppliers, purchase costs, notes, and dates. This issue is fixed in version 8.6.3.
A Stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability exists in Snipe-IT versions prior to 8.6.2. The vulnerability occurs when a stored manufacturer or supplier name is converted to CamelCase and rendered within the 'data-selected-count-id' attribute of a table. Client-side JavaScript retrieves this decoded attribute and performs unsafe string concatenation, passing it directly into jQuery's '.after()' method, enabling authenticated attackers to execute arbitrary JavaScript in the victim's session.
CVE-2026-62673 (also known as CVE-2026-62230 and GHSA-vwg3-w8w3-pc79) is a high-severity security bypass vulnerability in the Grav CMS. It permits unauthenticated remote attackers to circumvent directory and file access policies defined in Apache .htaccess. This flaw allows direct retrieval of sensitive configuration files, system-level credentials, and database equivalents from case-insensitive host filesystems.
A credential disclosure vulnerability in the mcp-searxng NPM package prior to version 1.12.0 allows attackers to recover plain-text SearXNG Basic Authentication credentials. The application exposes these credentials via console logs (stderr), MCP logging notifications, validation error messages, and JSON-RPC error responses. This occurs because the application lacks comprehensive sanitization across diagnostic boundaries when credentials are parsed from the SEARXNG_URL environment variable.