diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c
index 7a75923d4626b1a2c18e01500c0be9f979f1fe1b..21ba6f27d50353c44b62a7c2d87fedcc6967628f 100644
--- a/server/gstreamer-encoder.c
+++ b/server/gstreamer-encoder.c
@@ -20,6 +20,7 @@
 
 #include <inttypes.h>
 #include <pthread.h>
+#include <ctype.h>
 
 // ignore static constants variable not used
 #if defined(__GNUC__) && (__GNUC__ >= 6)
@@ -861,16 +862,29 @@ static const gchar* get_gst_codec_name(const SpiceGstEncoder *encoder)
     }
 }
 
-static gchar *get_gst_converter(void)
+static gpointer gst_pref_format_once(gpointer arg)
 {
-    gchar *converter, *pref_format;
+    const gchar *pref_format;
     pref_format = getenv("SPICE_CONVERTER_PREFERRED_FORMAT");
-    if (pref_format) {
-        converter = g_strconcat("videoconvert ! video/x-raw,format=", pref_format, NULL);
-    } else {
-        converter = g_strdup("videoconvert");
+    // for security limit the format to 64 characters and only alphanumeric or underscores
+    if (pref_format && pref_format[0] && strlen(pref_format) <= 64) {
+        const gchar *p;
+        for (p = pref_format; *p; ++p) {
+            if (!isalnum(*p) && *p != '_') {
+                goto wrong_format;
+            }
+        }
+        return g_strconcat("videoconvert ! video/x-raw,format=", pref_format, NULL);
     }
-    return converter;
+
+wrong_format:
+    return (gpointer) "videoconvert";
+}
+
+static gchar *get_gst_converter(void)
+{
+    static GOnce gst_once = G_ONCE_INIT;
+    return g_strdup((const gchar*) g_once(&gst_once, gst_pref_format_once, NULL));
 }
 
 static gboolean create_pipeline(SpiceGstEncoder *encoder)