Skip to content

Kévin Dunglas

Founder of Les-Tilleuls.coop (worker-owned cooperative). Creator of API Platform, FrankenPHP, Mercure.rocks, Vulcain.rocks and of some Symfony components.

Menu
  • Talks
  • Resume
  • Sponsor me
  • Contact
Menu

New in Caddy 2.5: Redact Sensitive Data from Your Logs

Posted on April 29, 2022April 29, 2022 by Kévin Dunglas

Caddy is the rising star of web servers. It is fast, easy to configure, fully featured (automatic TLS certificate generation and renewal, HTTP/3, cloud-native, config hot reloading…), and secure (it is written in Go, not in C).

Thanks to its unmatched extensibility that makes it a top-notch app platform, Caddy has a thriving ecosystem!

To see how it is powerful, take a look at my Mercure (push capabilities) and Vulcain (client-driven hypermedia APIs) modules! Caddy is also the webserver powering API Platform and Symfony Docker.

4 days ago, after 1 year of work, Matt Holt released Caddy 2.5! This new version contains some new features I contributed or helped to design, improving the security of the logging system.

Redacting Sensitive HTTP Headers

Unlike most other web servers, Caddy emits verbose structured logs. While it’s convenient to be able to inspect and analyze every single detail of the HTTP messages, this can also be dangerous. Until version 2.5, all HTTP headers were logged whenever logging was enabled. Even sensitive headers.

This can lead to serious security issues if the system processing and storing logs (ELK, Datadog…) isn’t configured properly. And they aren’t by default! Even companies such as Facebook, Twitter, and GitHub stored millions of user passwords in plain text because of similar misconfigurations.

In version 2.5, standard headers that may contain credentials, as defined in the fetch() specification, are automatically redacted. These headers are Cookie, Set-Cookie, Authorization and Proxy-Authorization.

If you need to log these headers, for instance during a debugging session, Francis Lavoie added a new option to re-enable the old behavior: log_credentials.

Introducing New Log Filters

But even this change isn’t enough to cover all cases where sensitive data need to be redacted from the logs. Although it’s considered bad security practice, it’s common for query parameters to contain sensitive information. Some examples:

  • OAuth access tokens
  • “magic links” and other temporary URLs
  • PHP session IDs
  • Mercure JWTs (the reason why I started working on this topic in the first time)

In many cases, you may want to log some query parameters but remove or replace others that contain sensitive data. E.g.: the access_token query parameter defined in the OAuth 2 specifications.

Similarly, instead of deleting the Cookie header entirely, which means removing all cookies, you may want to remove some specific cookies but keep others. To cover these more advanced but fairly common use cases, I added a bunch of new filters.

The first new filter allows to delete, replace, or hash specific query parameters:

log {
	format filter {
		wrap console
		fields {
			uri query {
				replace access_token REDACTED
				delete my_sensitive_param
				hash my_parameter
			}
		}
	}
}

I also contributed a similar filter to manipulate cookies:

log {
	format filter {
		wrap console
		fields {
			request>headers>Cookie cookie {
				replace PHPSESSID REDACTED
				delete my_sensitive_cookie
				hash my_cookie
			}
		}
	}
}

Finally, I added the ability to hash or apply a regular expression to the value of any logged field:

log {
	format filter {
		wrap console
		fields {
			request>headers>MyCustomHeader regexp secret REDACTED
			request>headers>AnotherCustomHeader hash
		}
	}
}

The hash filter is especially useful to prevent different queries from looking the same in the logs, or when you want to be able to group together queries that have the same redacted values.

If you need help setting up or even patching Caddy, if you want to hire a team of experimented Go developers, or if you need experts to secure your application: contact us! Les-Tilleuls.coop can help you!

Related posts:

  1. The Mercure.rocks Hub is now based on Caddy Web Server
  2. API Platform 2.6: PHP 8 support, Next.js and Nuxt.js app generator, Caddy server, ActivityPub and much more!
  3. PHP Schema: generate a fully functional PHP / Doctrine / Symfony data model from Schema.org vocabulary in minutes
  4. Slides à propos des Linked Data et des API REST Hypermedia avec Symfony

Leave a ReplyCancel reply

Social

  • Bluesky
  • GitHub
  • LinkedIn
  • Mastodon
  • X
  • YouTube

Links

  • API Platform
  • FrankenPHP
  • Les-Tilleuls.coop
  • Mercure.rocks
  • Vulcain.rocks

Subscribe to this blog

Top Posts & Pages

  • JSON Columns and Doctrine DBAL 3 Upgrade
  • Securely Access Private Git Repositories and Composer Packages in Docker Builds
  • Preventing CORS Preflight Requests Using Content Negotiation
  • FrankenPHP: The Modern Php App Server, written in Go
  • Symfony's New Native Docker Support (Symfony World)
  • Develop Faster With FrankenPHP
  • PHP and Symfony Apps As Standalone Binaries
  • How to debug Xdebug... or any other weird bug in PHP
  • HTTP compression in PHP (new Symfony AssetMapper feature)
  • Generate a Symfony password hash from the command line

Tags

Apache API API Platform Buzz Caddy Docker Doctrine FrankenPHP Go Google GraphQL HTTP/2 Hydra hypermedia Hébergement Javascript JSON-LD Kubernetes La Coopérative des Tilleuls Les-Tilleuls.coop Lille Linux Mac Mercure Mercure.rocks Messagerie Instantanée MySQL performance PHP Punk Rock Python React REST Rock'n'Roll Schema.org Security SEO SEO Symfony Symfony Live Sécurité Ubuntu Web 2.0 webperf XML

Archives

Categories

  • DevOps (84)
    • Ubuntu (68)
  • Go (17)
  • JavaScript (46)
  • Mercure (7)
  • Opinions (91)
  • PHP (170)
    • API Platform (77)
    • FrankenPHP (9)
    • Laravel (1)
    • Symfony (97)
    • Wordpress (6)
  • Python (14)
  • Security (15)
  • SEO (25)
  • Talks (46)
© 2025 Kévin Dunglas | Powered by Minimalist Blog WordPress Theme