4a42e1
diff --git a/plugins/epan/opcua/opcua.c b/plugins/epan/opcua/opcua.c
4a42e1
index fc26d9f30d..4ca68a9e83 100644
4a42e1
--- a/plugins/epan/opcua/opcua.c
4a42e1
+++ b/plugins/epan/opcua/opcua.c
4a42e1
@@ -38,7 +38,7 @@ void proto_reg_handoff_opcua(void);
4a42e1
 /* declare parse function pointer */
4a42e1
 typedef int (*FctParse)(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOffset);
4a42e1
 
4a42e1
-static int proto_opcua = -1;
4a42e1
+int proto_opcua = -1;
4a42e1
 static dissector_handle_t opcua_handle;
4a42e1
 /** Official IANA registered port for OPC UA Binary Protocol. */
4a42e1
 #define OPCUA_PORT_RANGE "4840"
4a42e1
diff --git a/plugins/epan/opcua/opcua_simpletypes.c b/plugins/epan/opcua/opcua_simpletypes.c
4a42e1
index a787f21c35..ab006b7552 100644
4a42e1
--- a/plugins/epan/opcua/opcua_simpletypes.c
4a42e1
+++ b/plugins/epan/opcua/opcua_simpletypes.c
4a42e1
@@ -20,6 +20,7 @@
4a42e1
 #include <epan/packet.h>
4a42e1
 #include <epan/expert.h>
4a42e1
 #include <epan/dissectors/packet-windows-common.h>
4a42e1
+#include <epan/proto_data.h>
4a42e1
 #include "opcua_simpletypes.h"
4a42e1
 #include "opcua_hfindeces.h"
4a42e1
 #include "opcua_statuscode.h"
4a42e1
@@ -80,6 +81,7 @@
4a42e1
 
4a42e1
 /* Chosen arbitrarily */
4a42e1
 #define MAX_ARRAY_LEN 10000
4a42e1
+#define MAX_NESTING_DEPTH 100
4a42e1
 
4a42e1
 static int hf_opcua_diag_mask = -1;
4a42e1
 static int hf_opcua_diag_mask_symbolicflag = -1;
4a42e1
@@ -168,6 +170,9 @@ int hf_opcua_resultMask_displayname = -1;
4a42e1
 int hf_opcua_resultMask_typedefinition = -1;
4a42e1
 
4a42e1
 static expert_field ei_array_length = EI_INIT;
4a42e1
+static expert_field ei_nesting_depth = EI_INIT;
4a42e1
+
4a42e1
+extern int proto_opcua;
4a42e1
 
4a42e1
 /** NodeId encoding mask table */
4a42e1
 static const value_string g_nodeidmasks[] = {
4a42e1
@@ -526,6 +531,7 @@ void registerSimpleTypes(int proto)
4a42e1
 
4a42e1
     static ei_register_info ei[] = {
4a42e1
         { &ei_array_length, { "opcua.array.length", PI_UNDECODED, PI_ERROR, "Max array length exceeded", EXPFILL }},
4a42e1
+        { &ei_nesting_depth, { "opcua.nestingdepth", PI_UNDECODED, PI_ERROR, "Max nesting depth exceeded", EXPFILL }},
4a42e1
     };
4a42e1
 
4a42e1
     proto_register_field_array(proto, hf, array_length(hf));
4a42e1
@@ -802,9 +808,19 @@ void parseDiagnosticInfo(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gi
4a42e1
     guint8      EncodingMask;
4a42e1
     proto_tree *subtree;
4a42e1
     proto_item *ti;
4a42e1
+    guint       opcua_nested_count;
4a42e1
 
4a42e1
     subtree = proto_tree_add_subtree_format(tree, tvb, *pOffset, -1, ett_opcua_diagnosticinfo, &ti, "%s: DiagnosticInfo", szFieldName);
4a42e1
 
4a42e1
+    /* prevent a too high nesting depth */
4a42e1
+    opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
4a42e1
+    if (++opcua_nested_count > MAX_NESTING_DEPTH)
4a42e1
+    {
4a42e1
+        expert_add_info(pinfo, ti, &ei_nesting_depth);
4a42e1
+        return;
4a42e1
+    }
4a42e1
+    p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
4a42e1
+
4a42e1
     /* parse encoding mask */
4a42e1
     EncodingMask = tvb_get_guint8(tvb, iOffset);
4a42e1
     proto_tree_add_bitmask(subtree, tvb, iOffset, hf_opcua_diag_mask, ett_opcua_diagnosticinfo_encodingmask, diag_mask, ENC_LITTLE_ENDIAN);
4a42e1
@@ -912,6 +928,16 @@ void parseVariant(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOf
4a42e1
     gint    iOffset = *pOffset;
4a42e1
     guint8  EncodingMask;
4a42e1
     gint32  ArrayDimensions = 0;
4a42e1
+    guint   opcua_nested_count;
4a42e1
+
4a42e1
+    /* prevent a too high nesting depth */
4a42e1
+    opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
4a42e1
+    if (++opcua_nested_count > MAX_NESTING_DEPTH)
4a42e1
+    {
4a42e1
+        expert_add_info(pinfo, ti, &ei_nesting_depth);
4a42e1
+        return;
4a42e1
+    }
4a42e1
+    p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
4a42e1
 
4a42e1
     EncodingMask = tvb_get_guint8(tvb, iOffset);
4a42e1
     proto_tree_add_item(subtree, hf_opcua_variant_encodingmask, tvb, iOffset, 1, ENC_LITTLE_ENDIAN);
4a42e1
@@ -1167,10 +1193,20 @@ void parseExtensionObject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, g
4a42e1
     guint32 TypeId;
4a42e1
     proto_tree *extobj_tree;
4a42e1
     proto_item *ti;
4a42e1
+    guint       opcua_nested_count;
4a42e1
 
4a42e1
     /* add extension object subtree */
4a42e1
     extobj_tree = proto_tree_add_subtree_format(tree, tvb, *pOffset, -1, ett_opcua_extensionobject, &ti, "%s: ExtensionObject", szFieldName);
4a42e1
 
4a42e1
+    /* prevent a too high nesting depth */
4a42e1
+    opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
4a42e1
+    if (++opcua_nested_count > MAX_NESTING_DEPTH)
4a42e1
+    {
4a42e1
+        expert_add_info(pinfo, ti, &ei_nesting_depth);
4a42e1
+        return;
4a42e1
+    }
4a42e1
+    p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
4a42e1
+
4a42e1
     /* add nodeid subtree */
4a42e1
     TypeId = getExtensionObjectType(tvb, &iOffset);
4a42e1
     parseExpandedNodeId(extobj_tree, tvb, pinfo, &iOffset, "TypeId");