From f5d45686957bd4dd34ea221dcc90e78dec2bff39 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Tue, 16 Jan 2024 19:56:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96XSS=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E7=9A=84=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libinjection/src/libinjection_xss.c | 41 ++++++++++++++++--- .../waf/injectionutils/libinjection_xss.c | 2 +- internal/waf/injectionutils/utils_xss_test.go | 14 ++++--- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/internal/waf/injectionutils/libinjection/src/libinjection_xss.c b/internal/waf/injectionutils/libinjection/src/libinjection_xss.c index 6c9f515..24497e2 100644 --- a/internal/waf/injectionutils/libinjection/src/libinjection_xss.c +++ b/internal/waf/injectionutils/libinjection/src/libinjection_xss.c @@ -15,7 +15,7 @@ typedef enum attribute { } attribute_t; -static attribute_t is_black_attr(const char* s, size_t len); +static attribute_t is_black_attr(const char* s, size_t len, int strictMode); static int is_black_tag(const char* s, size_t len, int strictMode); static int is_black_url(const char* s, size_t len); static int cstrcasecmp_with_null(const char *a, const char *b, size_t n); @@ -451,7 +451,7 @@ static stringtype_t BLACKATTREVENT[] = { * data: * javascript: */ -static stringtype_t BLACKATTR[] = { +static stringtype_t STRICT_BLACKATTR[] = { { "ACTION", TYPE_ATTR_URL } /* form */ , { "ATTRIBUTENAME", TYPE_ATTR_INDIRECT } /* SVG allow indirection of attribute names */ , { "BY", TYPE_ATTR_URL } /* SVG */ @@ -475,6 +475,31 @@ static stringtype_t BLACKATTR[] = { , { NULL, TYPE_NONE } }; +static stringtype_t BLACKATTR[] = { + { "ACTION", TYPE_ATTR_URL } /* form */ + , { "ATTRIBUTENAME", TYPE_ATTR_INDIRECT } /* SVG allow indirection of attribute names */ + , { "BY", TYPE_ATTR_URL } /* SVG */ + , { "BACKGROUND", TYPE_ATTR_URL } /* IE6, O11 */ + , { "DATAFORMATAS", TYPE_BLACK } /* IE */ + , { "DATASRC", TYPE_BLACK } /* IE */ + , { "DYNSRC", TYPE_ATTR_URL } /* Obsolete img attribute */ + , { "FILTER", TYPE_STYLE } /* Opera, SVG inline style */ + , { "FORMACTION", TYPE_ATTR_URL } /* HTML 5 */ + , { "FOLDER", TYPE_ATTR_URL } /* Only on A tags, IE-only */ + , { "FROM", TYPE_ATTR_URL } /* SVG */ + , { "HANDLER", TYPE_ATTR_URL } /* SVG Tiny, Opera */ + , { "HREF", TYPE_ATTR_URL } + , { "LOWSRC", TYPE_ATTR_URL } /* Obsolete img attribute */ + , { "POSTER", TYPE_ATTR_URL } /* Opera 10,11 */ + , { "SRC", TYPE_ATTR_URL } + , { "TO", TYPE_ATTR_URL } /* SVG */ + , { "VALUES", TYPE_ATTR_URL } /* SVG */ + , { "XLINK:HREF", TYPE_ATTR_URL } + , { NULL, TYPE_NONE } +}; + + + /* xmlns */ /* `xml-stylesheet` > , */ @@ -674,7 +699,7 @@ static int is_black_tag(const char* s, size_t len, int strictMode) return 0; } -static attribute_t is_black_attr(const char* s, size_t len) +static attribute_t is_black_attr(const char* s, size_t len, int strictMode) { stringtype_t* black; @@ -706,7 +731,11 @@ static attribute_t is_black_attr(const char* s, size_t len) //} } - black = BLACKATTR; + if (strictMode == 1) { + black = STRICT_BLACKATTR; + } else { + black = BLACKATTR; + } while (black->name != NULL) { if (cstrcasecmp_with_null(black->name, s, len) == 0) { /* printf("Got banned attribute name %s\n", black->name); */ @@ -779,7 +808,7 @@ int libinjection_is_xss(const char* s, size_t len, int flags, int strictMode) return 1; } } else if (h5.token_type == ATTR_NAME) { - attr = is_black_attr(h5.token_start, h5.token_len); + attr = is_black_attr(h5.token_start, h5.token_len, strictMode); } else if (h5.token_type == ATTR_VALUE) { /* * IE6,7,8 parsing works a bit differently so @@ -810,7 +839,7 @@ int libinjection_is_xss(const char* s, size_t len, int flags, int strictMode) return 1; case TYPE_ATTR_INDIRECT: /* an attribute name is specified in a _value_ */ - if (is_black_attr(h5.token_start, h5.token_len)) { + if (is_black_attr(h5.token_start, h5.token_len, strictMode)) { return 1; } break; diff --git a/internal/waf/injectionutils/libinjection_xss.c b/internal/waf/injectionutils/libinjection_xss.c index e61e26f..82150a6 100644 --- a/internal/waf/injectionutils/libinjection_xss.c +++ b/internal/waf/injectionutils/libinjection_xss.c @@ -3,4 +3,4 @@ #include "libinjection/src/libinjection_xss.c" #include "libinjection/src/libinjection_html5.c" -#define GOEDGE_VERSION "24" // last version is for GoEdge change \ No newline at end of file +#define GOEDGE_VERSION "25" // last version is for GoEdge change \ No newline at end of file diff --git a/internal/waf/injectionutils/utils_xss_test.go b/internal/waf/injectionutils/utils_xss_test.go index 752f7dd..91ef826 100644 --- a/internal/waf/injectionutils/utils_xss_test.go +++ b/internal/waf/injectionutils/utils_xss_test.go @@ -32,16 +32,18 @@ func TestDetectXSS(t *testing.T) { `, true)) // included in some photo files - a.IsFalse(injectionutils.DetectXSS(` - -`, true)) + a.IsFalse(injectionutils.DetectXSS(``, false)) } func TestDetectXSS_Strict(t *testing.T) { var a = assert.NewAssertion(t) - a.IsFalse(injectionutils.DetectXSS(` - -`, false)) + a.IsFalse(injectionutils.DetectXSS(``, false)) + a.IsTrue(injectionutils.DetectXSS(``, true)) + a.IsFalse(injectionutils.DetectXSS(``, false)) + a.IsFalse(injectionutils.DetectXSS(``, true)) + a.IsFalse(injectionutils.DetectXSS(``, true)) + a.IsFalse(injectionutils.DetectXSS(``, false)) + a.IsTrue(injectionutils.DetectXSS(``, true)) } func BenchmarkDetectXSS_MISS(b *testing.B) {