commit 55824365b87f548765e3ef2bacddaf33995a5d2a
parent e550e7e1fb17d3a140ccd156ebcaeae563751e90
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 22 Jun 2025 13:48:38 +0200
add 'Cache-control: no-store' by default (fixes #9723)
Diffstat:
14 files changed, 71 insertions(+), 31 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
@@ -1225,7 +1225,8 @@ handler_seed (struct TEH_RequestContext *rc,
resp = MHD_create_response_from_buffer (SEED_SIZE,
body,
MHD_RESPMEM_MUST_FREE);
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ false);
ret = MHD_queue_response (rc->connection,
MHD_HTTP_OK,
resp);
@@ -1534,7 +1535,8 @@ toplevel_redirect (struct TEH_RequestContext *rc,
GNUNET_break (0);
return MHD_NO;
}
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -153,7 +153,8 @@ aml_trigger_callback (
adc->response = MHD_create_response_from_buffer_static (
0,
"");
- TALER_MHD_add_global_headers (adc->response);
+ TALER_MHD_add_global_headers (adc->response,
+ true);
}
GNUNET_assert (NULL != adc->response);
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
@@ -2290,7 +2290,8 @@ setup_general_response_headers (void *cls,
struct TEH_KeyStateHandle *ksh = cls;
char dat[128];
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c
@@ -656,7 +656,8 @@ current_rules_cb (
NULL,
MHD_RESPMEM_PERSISTENT);
add_nocache_header (resp);
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ false);
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
MHD_HTTP_HEADER_ETAG,
diff --git a/src/exchange/taler-exchange-httpd_kyc-upload.c b/src/exchange/taler-exchange-httpd_kyc-upload.c
@@ -170,7 +170,8 @@ aml_trigger_callback (
0,
""
);
- TALER_MHD_add_global_headers (uc->response);
+ TALER_MHD_add_global_headers (uc->response,
+ true);
}
MHD_resume_connection (uc->rc->connection);
diff --git a/src/include/taler/taler_mhd2_lib.h b/src/include/taler/taler_mhd2_lib.h
@@ -104,9 +104,14 @@ TALER_MHD2_setup (enum TALER_MHD2_GlobalOptions go);
* if we want to always close connections.
*
* @param response response to modify
+ * @param allow_store set to true to NOT add a "Cache-Control"
+ * directive that prevents caches and browsers from storing the data;
+ * if false, we set "Cache-Control: no-store" (privacy by default);
+ * set to true if the response contains no personal data
*/
void
-TALER_MHD2_add_global_headers (struct MHD_Response *response);
+TALER_MHD2_add_global_headers (struct MHD_Response *response,
+ bool allow_store);
/**
diff --git a/src/include/taler/taler_mhd_lib.h b/src/include/taler/taler_mhd_lib.h
@@ -113,9 +113,14 @@ TALER_MHD_setup (enum TALER_MHD_GlobalOptions go);
* if we want to always close connections.
*
* @param response response to modify
+ * @param allow_store set to true to NOT add a "Cache-Control"
+ * directive that prevents caches and browsers from storing the data;
+ * if false, we set "Cache-Control: no-store" (privacy by default);
+ * set to true if the response contains no personal data
*/
void
-TALER_MHD_add_global_headers (struct MHD_Response *response);
+TALER_MHD_add_global_headers (struct MHD_Response *response,
+ bool allow_store);
/**
diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c
@@ -1091,7 +1091,8 @@ proof_post_conversion_cb (void *cls,
MHD_add_response_header (resp,
MHD_HTTP_HEADER_LOCATION,
ph->pd->post_kyc_redirect_url));
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ false);
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_SUCCESS,
ph->pd->section,
@@ -1579,7 +1580,8 @@ webhook_generic_reply (struct TALER_KYCLOGIC_WebhookHandle *wh,
expiration = GNUNET_TIME_UNIT_ZERO_ABS;
resp = MHD_create_response_from_buffer_static (0,
"");
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ true);
wh->cb (wh->cb_cls,
wh->process_row,
&wh->h_payto,
diff --git a/src/kyclogic/taler-exchange-helper-sanctions-dummy.c b/src/kyclogic/taler-exchange-helper-sanctions-dummy.c
@@ -47,10 +47,6 @@ main (int argc,
JSON_DISABLE_EOF_CHECK,
&err)))
{
- struct GNUNET_TIME_Timestamp expiration
- = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS));
-
if (! json_is_object (input))
{
json_decref (input);
diff --git a/src/mhd/Makefile.am b/src/mhd/Makefile.am
@@ -18,7 +18,7 @@ libtalermhd_la_SOURCES = \
mhd_run.c \
mhd_spa.c
libtalermhd_la_LDFLAGS = \
- -version-info 6:0:0 \
+ -version-info 7:0:0 \
-no-undefined
libtalermhd_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \
diff --git a/src/mhd/mhd2_legal.c b/src/mhd/mhd2_legal.c
@@ -257,7 +257,8 @@ TALER_MHD2_reply_legal (struct MHD_Request *request,
MHD_RESPONSE_SET_OPTIONS (
resp,
MHD_R_OPTION_HEAD_ONLY_RESPONSE (true)));
- TALER_MHD2_add_global_headers (resp);
+ TALER_MHD2_add_global_headers (resp,
+ true);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (resp,
MHD_HTTP_HEADER_EXPIRES,
@@ -310,7 +311,8 @@ return_t:
t->terms_size,
(void *) t->terms);
}
- TALER_MHD2_add_global_headers (resp);
+ TALER_MHD2_add_global_headers (resp,
+ true);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (resp,
MHD_HTTP_HEADER_EXPIRES,
diff --git a/src/mhd/mhd2_responses.c b/src/mhd/mhd2_responses.c
@@ -40,7 +40,8 @@ TALER_MHD2_setup (enum TALER_MHD2_GlobalOptions go)
void
-TALER_MHD2_add_global_headers (struct MHD_Response *response)
+TALER_MHD2_add_global_headers (struct MHD_Response *response,
+ bool allow_store)
{
if (0 != (TM_go & TALER_MHD2_GO_FORCE_CONNECTION_CLOSE))
GNUNET_break (MHD_SC_OK ==
@@ -58,6 +59,11 @@ TALER_MHD2_add_global_headers (struct MHD_Response *response)
/* Not available as MHD constant yet */
"Access-Control-Expose-Headers",
"*"));
+ if (! allow_store)
+ GNUNET_break (MHD_SC_OK ==
+ MHD_response_add_header (response,
+ MHD_HTTP_HEADER_CACHE_CONTROL,
+ "no-store"));
}
@@ -151,7 +157,8 @@ TALER_MHD2_make_json (enum MHD_HTTP_StatusCode sc,
GNUNET_break (0);
return NULL;
}
- TALER_MHD2_add_global_headers (response);
+ TALER_MHD2_add_global_headers (response,
+ false);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -214,7 +221,8 @@ TALER_MHD2_reply_json (struct MHD_Request *request,
GNUNET_break (0);
return NULL;
}
- TALER_MHD2_add_global_headers (response);
+ TALER_MHD2_add_global_headers (response,
+ false);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -263,7 +271,8 @@ TALER_MHD2_reply_cors_preflight (struct MHD_Request *request)
return NULL;
/* This adds the Access-Control-Allow-Origin header.
* All endpoints of the exchange allow CORS. */
- TALER_MHD2_add_global_headers (response);
+ TALER_MHD2_add_global_headers (response,
+ true);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (response,
/* Not available as MHD constant yet */
@@ -356,7 +365,8 @@ TALER_MHD2_reply_agpl (struct MHD_Request *request,
GNUNET_break (0);
return MHD_NO;
}
- TALER_MHD2_add_global_headers (response);
+ TALER_MHD2_add_global_headers (response,
+ true);
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -392,7 +402,8 @@ TALER_MHD2_reply_static (struct MHD_Request *request,
GNUNET_break (0);
return NULL;
}
- TALER_MHD2_add_global_headers (response);
+ TALER_MHD2_add_global_headers (response,
+ true);
if (NULL != mime_type)
GNUNET_break (MHD_SC_OK ==
MHD_response_add_header (response,
diff --git a/src/mhd/mhd_legal.c b/src/mhd/mhd_legal.c
@@ -250,7 +250,8 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn,
resp = MHD_create_response_from_buffer (0,
NULL,
MHD_RESPMEM_PERSISTENT);
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
MHD_HTTP_HEADER_EXPIRES,
@@ -303,7 +304,8 @@ return_t:
(void *) t->terms,
MHD_RESPMEM_PERSISTENT);
}
- TALER_MHD_add_global_headers (resp);
+ TALER_MHD_add_global_headers (resp,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
MHD_HTTP_HEADER_EXPIRES,
diff --git a/src/mhd/mhd_responses.c b/src/mhd/mhd_responses.c
@@ -40,7 +40,8 @@ TALER_MHD_setup (enum TALER_MHD_GlobalOptions go)
void
-TALER_MHD_add_global_headers (struct MHD_Response *response)
+TALER_MHD_add_global_headers (struct MHD_Response *response,
+ bool allow_store)
{
if (0 != (TM_go & TALER_MHD_GO_FORCE_CONNECTION_CLOSE))
GNUNET_break (MHD_YES ==
@@ -58,6 +59,11 @@ TALER_MHD_add_global_headers (struct MHD_Response *response)
/* Not available as MHD constant yet */
"Access-Control-Expose-Headers",
"*"));
+ if (! allow_store)
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CACHE_CONTROL,
+ "no-store"));
}
@@ -144,7 +150,8 @@ TALER_MHD_make_json (const json_t *json)
GNUNET_break (0);
return NULL;
}
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ false);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -204,7 +211,8 @@ TALER_MHD_reply_json (struct MHD_Connection *connection,
GNUNET_break (0);
return MHD_NO;
}
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ false);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -262,7 +270,8 @@ TALER_MHD_reply_cors_preflight (struct MHD_Connection *connection)
return MHD_NO;
/* This adds the Access-Control-Allow-Origin header.
* All endpoints of the exchange allow CORS. */
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
/* Not available as MHD constant yet */
@@ -359,7 +368,8 @@ TALER_MHD_reply_agpl (struct MHD_Connection *connection,
GNUNET_break (0);
return MHD_NO;
}
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ true);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -403,7 +413,8 @@ TALER_MHD_reply_static (struct MHD_Connection *connection,
GNUNET_break (0);
return MHD_NO;
}
- TALER_MHD_add_global_headers (response);
+ TALER_MHD_add_global_headers (response,
+ true);
if (NULL != mime_type)
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,