aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-12-13 20:35:48 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-12-13 20:35:48 +0000
commit413ecb9bde4067f916592d69d43314bd9ad136cc (patch)
tree40b192fe182b70c17c950729a41ae2be0ce0abf3 /src/libserver
parent85c3e693bfeae78f1ffa549eab64da8ac6c05ad1 (diff)
downloadrspamd-413ecb9bde4067f916592d69d43314bd9ad136cc.tar.gz
rspamd-413ecb9bde4067f916592d69d43314bd9ad136cc.zip
[Minor] Add some tags limit to avoid HTML parser DoS
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/html.c51
-rw-r--r--src/libserver/html.h2
2 files changed, 36 insertions, 17 deletions
diff --git a/src/libserver/html.c b/src/libserver/html.c
index fc08baeb5..26318db43 100644
--- a/src/libserver/html.c
+++ b/src/libserver/html.c
@@ -28,6 +28,7 @@
static sig_atomic_t tags_sorted = 0;
static sig_atomic_t entities_sorted = 0;
+static const guint max_tags = 8192; /* Ignore tags if this maximum is reached */
struct html_tag_def {
const gchar *name;
@@ -997,8 +998,13 @@ rspamd_html_process_tag (rspamd_mempool_t *pool, struct html_content *hc,
nnode);
}
+ if (hc->total_tags > max_tags) {
+ hc->flags |= RSPAMD_HTML_FLAG_TOO_MANY_TAGS;
+ }
+
if (tag->id == -1) {
/* Ignore unknown tags */
+ hc->total_tags ++;
return FALSE;
}
@@ -1006,25 +1012,26 @@ rspamd_html_process_tag (rspamd_mempool_t *pool, struct html_content *hc,
if (!(tag->flags & CM_INLINE)) {
/* Block tag */
- nnode = g_node_new (tag);
-
if (tag->flags & (FL_CLOSING|FL_CLOSED)) {
if (!*cur_level) {
msg_debug_html ("bad parent node");
- g_node_destroy (nnode);
return FALSE;
}
- g_node_append (*cur_level, nnode);
+ if (hc->total_tags < max_tags) {
+ nnode = g_node_new (tag);
+ g_node_append (*cur_level, nnode);
- if (!rspamd_html_check_balance (nnode, cur_level)) {
- msg_debug_html (
- "mark part as unbalanced as it has not pairable closing tags");
- hc->flags |= RSPAMD_HTML_FLAG_UNBALANCED;
- *balanced = FALSE;
- }
- else {
- *balanced = TRUE;
+ if (!rspamd_html_check_balance (nnode, cur_level)) {
+ msg_debug_html (
+ "mark part as unbalanced as it has not pairable closing tags");
+ hc->flags |= RSPAMD_HTML_FLAG_UNBALANCED;
+ *balanced = FALSE;
+ } else {
+ *balanced = TRUE;
+ }
+
+ hc->total_tags ++;
}
}
else {
@@ -1043,8 +1050,13 @@ rspamd_html_process_tag (rspamd_mempool_t *pool, struct html_content *hc,
hc->flags |= RSPAMD_HTML_FLAG_UNBALANCED;
*balanced = FALSE;
tag->parent = parent->parent;
- g_node_append (parent->parent, nnode);
- *cur_level = nnode;
+
+ if (hc->total_tags < max_tags) {
+ nnode = g_node_new (tag);
+ g_node_append (parent->parent, nnode);
+ *cur_level = nnode;
+ hc->total_tags ++;
+ }
return TRUE;
}
@@ -1053,10 +1065,15 @@ rspamd_html_process_tag (rspamd_mempool_t *pool, struct html_content *hc,
parent->content_length += tag->content_length;
}
- g_node_append (*cur_level, nnode);
+ if (hc->total_tags < max_tags) {
+ nnode = g_node_new (tag);
+ g_node_append (*cur_level, nnode);
+
+ if ((tag->flags & FL_CLOSED) == 0) {
+ *cur_level = nnode;
+ }
- if ((tag->flags & FL_CLOSED) == 0) {
- *cur_level = nnode;
+ hc->total_tags ++;
}
if (tag->flags & (CM_HEAD|CM_UNKNOWN|FL_IGNORE)) {
diff --git a/src/libserver/html.h b/src/libserver/html.h
index 5216ad767..84d5e2bc2 100644
--- a/src/libserver/html.h
+++ b/src/libserver/html.h
@@ -17,6 +17,7 @@
#define RSPAMD_HTML_FLAG_UNBALANCED (1 << 3)
#define RSPAMD_HTML_FLAG_UNKNOWN_ELEMENTS (1 << 4)
#define RSPAMD_HTML_FLAG_DUPLICATE_ELEMENTS (1 << 5)
+#define RSPAMD_HTML_FLAG_TOO_MANY_TAGS (1 << 6)
/*
* Image flags
@@ -107,6 +108,7 @@ struct rspamd_task;
struct html_content {
GNode *html_tags;
gint flags;
+ guint total_tags;
struct html_color bgcolor;
guchar *tags_seen;
GPtrArray *images;