tilegroxy docs

Philosophy

Tilegroxy operates as a configuration driven framework for flexibly serving up data that comes from a wide variety of possible sources. The flexible configuration means that an operator can misconfigure tilegroxy in an insecure manner that opens it up to a wide variety of vulnerabilities. Tilegroxy cannot and does not attempt to prevent all possible misconfigurations. It does, however, aim to equip operators with the tools necessary to have a secure deployment when properly configured.

User Inputs

Tilegroxy draws a distinction between inputs provided by the Operator (probably you) and the User (the end user who makes tile requests). Operator input is inherently trusted and beyond preventing foot-guns, no attempt is made to prevent potentially malicious intent. User input meanwhile is treated as potentially hostile.

Layer Name Parameters

Tilegroxy supports parameterized layer names where each parameter is arbitrary user input. By default these parameters are not used for anything and merely provide flexibility in how one refers to a map layer. However, the Operator can configure these parameters to be used in a variety of ways, for instance placed inside of proxied URLs, inside of SQL as parameters in Prepared Statements, or as inputs in arbitrary code.

The possible values can be constrained in two ways: a paramValidator that applies a Regular Expression to validate the parameters specified, and a paramMap that allows restricting to a static set of possible values. It is recommended the Operator defines restrictions as tightly as possible.

The configuration for tilegroxy should be treated the same as one would treat code, it should be carefully reviewed, kept in source control, and one should never trust complex configuration from third parties without vetting it for bugs and vulnerabilities.

Headers and Query Params

By default tilegroxy ignores incoming HTTP headers and the query string. It is possible for the Operator to utilize these in many of the same situations described in Layer Name Parameters. However, there is no facility for validating these inputs.

Use extreme caution in trusting incoming headers and query parameters.

X-Forwarded

A few systems in tilegroxy identify incoming request information such as client IP or external request hostname/protocol/path. The standard mechanism for keeping these working behind proxies or WAFs is the X-Forwarded-* headers. Those headers are prone to forgery attacks so tilegroxy only trusts the headers on a limited basis and requires identifying the IP of trusted proxies via server.forwarded.trusted. Every private network address is trusted by default, so make sure to add the CIDR block for any proxies outside your network, and narrow it if clients can reach tilegroxy without going through a proxy. Set server.tilejson.baseurls if any proxy passes X-Forwarded-Host through unchanged.

Per-User Tiles

An Operator can configure a layer whose tiles depend on who requested them, by interpolating the identity into the upstream request or by cropping to an area the requester’s credentials allow. The cache key carries no identity, so such a layer leaks tiles between users unless it uses a tenant cache or skips caching. See User Dynamic Layers.

Upstream Responses

One of the primary use-cases for tilegroxy is to proxy tile requests to another HTTP(s) server. These inputs are cached and returned to the user, either as-is or with transformation. In order to prevent a third-party server returning malicious inputs a few protections are available:

Content Type validation

If the server returns an invalid content-type then the request errors. By default only PNG, JPEG, and vector tile payloads are allowed. See Content Type for the full default allowlist.

Content Type mirroring

When returning a payload retrieved from a third party HTTP service tilegroxy will return the same content-type as the server, this helps prevent using tilegroxy to deliver malicious javascript payloads disguised under a false content type

Content Size validation

If the server fails to return a content size header or if the content size is greater than a limit (by default 10 MiB) then the request errors. Tilegroxy will not allocate a buffer greater than the allowed size even if the server responds with a larger response than advertised

TLS validation

If the URL configured includes an https protocol then standard TLS certificate validation occurs. Tilegroxy uses default Go settings for validation including a minimum version of TLS 1.2 and rejection of insecure ciphers. A TLS profile can narrow which CAs are trusted for an upstream or raise the minimum version

Despite these protections it’s important that operators only utilize trusted services to originate its maps. Tilegroxy cannot protect against a third party returning a valid result containing offensive imagery.

Never allow user input to dictate the hostname used.

Authentication

Tilegroxy provides a flexible capability for auth but defaults to operating unauthenticated. The flagship mode is via JWTs provided via HTTP header, which provides a capability for both authentication and authorization by layer and geographic region.

Tilegroxy is primarily intended to be used as a microservice within a broader application ecosystem so implementing the specifics of how authentication should work end-to-end is left up to the operator in conjunction with their needs.

The server can also require client certificates. Every certificate from the configured CA is treated the same, so it controls who can connect but not what they can access.

Rate Limiting

Rate limiting can stop one user from exhausting an upstream provider or a quota shared with everyone else. It isn’t a defense against denial of service, since every rejected request is still received and checked. See Rate Limiting.

User IDs, tenant IDs, and IP addresses are hashed with SHA-256 before being used as store keys so any value is safe to store. The hash is unsalted, so anyone who can read the store can check whether a known IP or ID is being counted. Restrict access to the store accordingly.

Logging

Tilegroxy has a few separately configurable log streams available. Consider ingesting each of these into your SIEM or log aggregator if your system is security-sensitive.

Most notably from a security side, rejected requests, rate limit rejections, and configuration reloads can be recorded to a dedicated audit log.