commit bc3e31a173fd251b3348b99951afc3e91cc967ce
parent f81de57d9b83cf5705672b4dae247ce3eb44d183
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 6 Aug 2026 18:00:42 +0200
make BASE_URL mandatory if '-f' is not given
Diffstat:
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/README b/README
@@ -78,6 +78,7 @@ Paivana reads an INI-style `.conf` file. The only section used is
DESTINATION_BASE_URL = https://example.com/
MERCHANT_BACKEND_URL = https://backend.demo.taler.net/instances/sandbox/
MERCHANT_ACCESS_TOKEN = secret-token:sandbox
+ BASE_URL = http://localhost:9967/
SERVE = tcp
PORT = 9967
@@ -88,13 +89,14 @@ Paivana reads an INI-style `.conf` file. The only section used is
DESTINATION_BASE_URL Upstream server to proxy to once payment is confirmed.
MERCHANT_BACKEND_URL Base URL of the Taler merchant backend.
MERCHANT_ACCESS_TOKEN Bearer token for all calls to the merchant backend.
+ BASE_URL Public base URL of Paivana. Required unless `-f`
+ is given, in which case it is derived from the
+ forwarding headers (see below).
### Optional keys
Key Description
-------- ---------------------------------------------------------------
- BASE_URL Public base URL of Paivana. Derived from request headers
- (X-Forwarded-Host / Host / X-Forwarded-Port) if absent.
SECRET Stable secret for cookie MAC and Paivana ID derivation.
A random nonce is generated on every startup if absent.
WHITELIST POSIX extended regular expression; matching request paths
@@ -242,7 +244,12 @@ Put IPv4 proxies in `TRUSTED_PROXIES`, not in `TRUSTED_PROXIES6` as
matching, so a mapped entry would never be hit.
Set `BASE_URL` in the configuration file to the public HTTPS URL so
-that redirects and cookie domains are correct.
+that redirects and cookie domains are correct. It may be omitted only
+when `-f` is given: the flag asserts that a reverse proxy in front of
+Paivana has already enforced a correct `Host`, which is what makes it
+safe to reconstruct our own URL from the request. Without `-f` the
+client is assumed to have connected directly, `Host` is whatever it
+chose to send, and `BASE_URL` is therefore mandatory.
Source layout
diff --git a/src/backend/paivana-httpd.c b/src/backend/paivana-httpd.c
@@ -474,6 +474,35 @@ run (void *cls,
"BASE_URL",
&PH_base_url))
{
+ /* Without BASE_URL we reconstruct our own URL from the request, and
+ the only thing that makes that safe is a reverse proxy in front
+ of us that enforced a correct Host: -- which is exactly what -f
+ asserts. Talking to clients directly, Host: is whatever the
+ client typed, and it decides both the string the access cookie is
+ keyed on and the string the templates' website_regex is matched
+ against: a client sending "Host: anything.invalid" would match no
+ template and be served for free. The scheme has the same
+ problem in reverse: direct connections have no X-Forwarded-Proto
+ to consult, so a site reached over https would generate http://
+ URLs and again match no template. */
+ if ( (! PH_respect_forwarded_headers) &&
+ (! PH_no_check) )
+ {
+ /* -n has no paywall, hence no access decision that the site's
+ own identity could be got wrong for; the base URL is then only
+ cosmetic and the "pure reverse proxy" mode stays configurable
+ with nothing but DESTINATION_BASE_URL. */
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "paivana",
+ "BASE_URL");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "BASE_URL is required unless -f is given: without a"
+ " reverse proxy vouching for it, the client's Host"
+ " header cannot be used to identify this site\n");
+ PH_global_ret = EXIT_NOTCONFIGURED;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO,
"paivana",
"BASE_URL");