diff --git a/src/shared/json.c b/src/shared/json.c index 98fa067ef4..b3de2ad718 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -3611,6 +3611,9 @@ int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFla if (!json_variant_is_string(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name)); + if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant))) + return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name)); + r = free_and_strdup(s, json_variant_string(variant)); if (r < 0) return json_log(variant, flags, r, "Failed to allocate string: %m"); @@ -3634,6 +3637,9 @@ int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags /* Let's be flexible here: accept a single string in place of a single-item array */ if (json_variant_is_string(variant)) { + if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant))) + return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name)); + l = strv_new(json_variant_string(variant)); if (!l) return log_oom(); @@ -3649,6 +3655,9 @@ int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags if (!json_variant_is_string(e)) return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not a string."); + if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(e))) + return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name)); + r = strv_extend(&l, json_variant_string(e)); if (r < 0) return json_log(e, flags, r, "Failed to append array element: %m"); diff --git a/src/shared/json.h b/src/shared/json.h index d3e44d1b04..1ce0f90c29 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -230,10 +230,11 @@ typedef enum JsonDispatchFlags { JSON_PERMISSIVE = 1 << 0, /* Shall parsing errors be considered fatal for this property? */ JSON_MANDATORY = 1 << 1, /* Should existence of this property be mandatory? */ JSON_LOG = 1 << 2, /* Should the parser log about errors? */ + JSON_SAFE = 1 << 3, /* Don't accept "unsafe" strings in json_dispatch_string() + json_dispatch_string() */ /* The following two may be passed into log_json() in addition to the three above */ - JSON_DEBUG = 1 << 3, /* Indicates that this log message is a debug message */ - JSON_WARNING = 1 << 4, /* Indicates that this log message is a warning message */ + JSON_DEBUG = 1 << 4, /* Indicates that this log message is a debug message */ + JSON_WARNING = 1 << 5, /* Indicates that this log message is a warning message */ } JsonDispatchFlags; typedef int (*JsonDispatchCallback)(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);