]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json: optionally, make string checks stricter when dispatching strings
authorLennart Poettering <lennart@poettering.net>
Tue, 23 Apr 2019 13:25:42 +0000 (15:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 2 Dec 2019 08:47:00 +0000 (09:47 +0100)
src/shared/json.c
src/shared/json.h

index 98fa067ef4db5ceffb367fc9cd53f893fcadf399..b3de2ad718f9493fdd23b536c6f45b464c1e0d92 100644 (file)
@@ -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");
index d3e44d1b0436c4bd0a69c1d591b455db6d58d05d..1ce0f90c29393bdbb8fdd120fa20482e4d279826 100644 (file)
@@ -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);