From c382cb6b723a886da7b37a7e2be058653586f924 Mon Sep 17 00:00:00 2001 From: byrsapty Date: Fri, 28 Aug 2026 13:29:20 +0300 Subject: [PATCH] Fix DSL string-escaping bug breaking compilation of 2 A10 rules Both rule89 (a10_session_opened) and rule91 (a10_session_timeout) failed to compile live: \\" (two backslashes before a quote) is read by Graylog's rule DSL as an escaped backslash followed by an unescaped string terminator, not an escaped quote - so the regex() string literal ended early and everything after it parsed as garbage ("Unknown function S", "mismatched input '('", etc). Fix: exactly one backslash before each quote (\") so the DSL treats it as an escaped quote character, matching the \S/\d/\. occurrences elsewhere in the same pattern which correctly use two backslashes (DSL-decodes to one, which is what the regex engine needs). The other 4 new A10 rules didn't have this issue and already compiled successfully on the user's first live run. --- rules/rule89_a10_session_opened.json | 2 +- rules/rule91_a10_session_timeout.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/rule89_a10_session_opened.json b/rules/rule89_a10_session_opened.json index 2ade244..2aef177 100644 --- a/rules/rule89_a10_session_opened.json +++ b/rules/rule89_a10_session_opened.json @@ -1,5 +1,5 @@ { "title": "a10_session_opened", "description": "A10: admin session opened (covers both 'aXAPI session' and 'cli session' wording - same event, different access method). Built from real captured A10 syslog output.", - "source": "rule \"a10_session_opened\"\nwhen\n contains(to_string($message.message), \"session for user\") && contains(to_string($message.message), \"has been opened\")\nthen\n set_field(\"vendor\", \"a10\");\n set_field(\"event_type\", \"session_opened\");\n let m = regex(\"session for user \\\\\"(\\\\S+)\\\\\" from (\\\\S+) has been opened\\\\. Session ID assigned is (\\\\d+)\", to_string($message.message), [\"user\",\"src_ip\",\"session_id\"]);\n set_field(\"a10_user\", m[\"user\"]);\n set_field(\"src_ip\", m[\"src_ip\"]);\n set_field(\"a10_session_id\", m[\"session_id\"]);\nend" + "source": "rule \"a10_session_opened\"\nwhen\n contains(to_string($message.message), \"session for user\") && contains(to_string($message.message), \"has been opened\")\nthen\n set_field(\"vendor\", \"a10\");\n set_field(\"event_type\", \"session_opened\");\n let m = regex(\"session for user \\\"(\\\\S+)\\\" from (\\\\S+) has been opened\\\\. Session ID assigned is (\\\\d+)\", to_string($message.message), [\"user\",\"src_ip\",\"session_id\"]);\n set_field(\"a10_user\", m[\"user\"]);\n set_field(\"src_ip\", m[\"src_ip\"]);\n set_field(\"a10_session_id\", m[\"session_id\"]);\nend" } diff --git a/rules/rule91_a10_session_timeout.json b/rules/rule91_a10_session_timeout.json index 49a5295..106e1fc 100644 --- a/rules/rule91_a10_session_timeout.json +++ b/rules/rule91_a10_session_timeout.json @@ -1,5 +1,5 @@ { "title": "a10_session_timeout", "description": "A10: admin session timed out from inactivity (the detailed line naming session id/user/src_ip - the generic preceding 'Session timed out' line is a duplicate summary of the same event and is deliberately left unclassified). Built from real captured A10 syslog output.", - "source": "rule \"a10_session_timeout\"\nwhen\n contains(to_string($message.message), \"has timed out\")\nthen\n set_field(\"vendor\", \"a10\");\n set_field(\"event_type\", \"session_timeout\");\n let m = regex(\"Session ID (\\\\d+) for user \\\\\"(\\\\S+)\\\\\" from (\\\\S+) has timed out\", to_string($message.message), [\"session_id\",\"user\",\"src_ip\"]);\n set_field(\"a10_session_id\", m[\"session_id\"]);\n set_field(\"a10_user\", m[\"user\"]);\n set_field(\"src_ip\", m[\"src_ip\"]);\nend" + "source": "rule \"a10_session_timeout\"\nwhen\n contains(to_string($message.message), \"has timed out\")\nthen\n set_field(\"vendor\", \"a10\");\n set_field(\"event_type\", \"session_timeout\");\n let m = regex(\"Session ID (\\\\d+) for user \\\"(\\\\S+)\\\" from (\\\\S+) has timed out\", to_string($message.message), [\"session_id\",\"user\",\"src_ip\"]);\n set_field(\"a10_session_id\", m[\"session_id\"]);\n set_field(\"a10_user\", m[\"user\"]);\n set_field(\"src_ip\", m[\"src_ip\"]);\nend" }