tempesta-tech / tempesta

All-in-one solution for high performance web content delivery and advanced protection against DDoS and web attacks
https://tempesta-tech.com/
GNU General Public License v2.0
624 stars 103 forks source link

WordPress CMS authentication doesn't work over HTTP/2 #1980

Closed krizhanovsky closed 9 months ago

krizhanovsky commented 1 year ago

Tempesta FW configuration:

cache 2;
cache_fulfill * *;
cache_methods GET HEAD;
cache_ttl 3600;

listen 443 proto=h2;
listen 80;

srv_group default {
        server 192.168.122.1:80;
}

tls_certificate /etc/tempesta/fullchain.pem;
tls_certificate_key /etc/tempesta/privkey.pem;
req_hdr_add X-Forwarded-Proto "https";
resp_hdr_set Strict-Transport-Security "max-age=31536000; includeSubDomains";

vhost default {
        tls_match_any_server_name;
        proxy_pass default;
}

frang_limits {
        request_rate 200;
        http_method_override_allowed true;
        http_methods post put get;
}

cache_purge;
cache_purge_acl 192.168.122.1 127.0.0.1;

access_log on;

block_action attack reply;
block_action error reply;

http_chain {
        -> default;
}

With a WordPress on the backend. A request to /wp-admin fails with this log

[73478.360797] [tempesta fw] 7.1.7.1 "default" "GET /wp-admin/ HTTP/2.0" 302 0 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0"
[73478.966370] [tempesta fw] Warning: HTTP/2: too many headers (duplicates) in HTTP/1.1-response (header id: 13, header dups: 17
[73478.968258] [tempesta fw] Warning: Parser error: state=RGen_CR input(-8)=0xa(' path=/
[73478.968258] Set-Cookie: wp-postpass_42fb2087226d3f4') data_len=5091 off=2205
[73478.970796] [tempesta fw] Warning: response dropped: processing error: 7.1.7.1
[73478.972145] [tempesta fw] 7.1.7.1 "default" "GET /wp-login.php?redirect_to=https%3A%2F%2Ftempesta-tech.com%2Fwp-admin%2F&reauth=1 HTTP/2.0" 502 0 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0"
mbabitski-t commented 1 year ago

Tempesta built with make DEBUG=10

[   94.327992] [tempesta fw]   client was found in tdb
[   94.329799] [tempesta fw]     client 0000000023ab4238, users=14
[   94.582021] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x31 len=1 r=1
[   94.582484] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x64 len=8 r=8
[   94.582844] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x6e len=8 r=8
[   94.583165] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x6e len=4 r=4
[   94.583434] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x3f len=2 r=2
[   94.583704] [tempesta fw]     Matching request: 00000000bddbd0a5, list: 000000007213dd3d
[   94.584025] [tempesta fw]     Matching request: 00000000bddbd0a5, list: 000000008f2708e9
[   94.584426] [tempesta fw]     rule: 000000008e49b42f, field: 0x5, op: 0x2, arg:5:6'/index'
[   94.584801] [tempesta fw]     rule: 000000006a64db37, field: 0x5, op: 0x2, arg:5:21'/development-services'
[   94.585141] [tempesta fw]     rule: 0000000071d6b08c, field: 0x5, op: 0x2, arg:5:11'/index.html'
[   94.585466] [tempesta fw]     rule: 00000000254fe664, field: 0x5, op: 0x2, arg:5:9'/services'
[   94.585912] [tempesta fw]     rule: 000000001fe9cb98, field: 0x5, op: 0x2, arg:5:14'/services.html'
[   94.586255] [tempesta fw]     rule: 00000000f1b82d5f, field: 0x5, op: 0x2, arg:5:13'/c++-services'
[   94.586649] [tempesta fw]     rule: 0000000002c7b621, field: 0x5, op: 0x2, arg:5:13'/company.html'
[   94.587276] [tempesta fw]     rule: 0000000058484ded, field: 0x5, op: 0x2, arg:5:52'/blog/fast-programming-languages-c-c++-rust-assembly'
[   94.587731] [tempesta fw]     rule: 00000000fff12570, field: 0x1, op: 0x1, arg:1:0''
[   94.588236] [tempesta fw]   frang: check request for client 192.168.122.1, acc=000000001af81ac5
[   94.588692] [tempesta fw]   frang: check incomplete request headers for client 192.168.122.1, acc=000000001af81ac5
[   94.589303] [tempesta fw]       enter frang FSM at state 0x0(Frang_Req_0)
[   94.589820] [tempesta fw]       enter frang FSM at state 0x1(Frang_Req_Hdr_Method)
[   94.590270] [tempesta fw]       enter frang FSM at state 0x2(Frang_Req_Hdr_UriLen)
[   94.590790] [tempesta fw]       enter frang FSM at state 0x3(Frang_Req_Hdr_Check)
[   94.591399] [tempesta fw]       enter frang FSM at state 0x5(Frang_Req_Body_Start)
[   94.592267] [tempesta fw]   frang: check incomplete request body for client 192.168.122.1, acc=000000001af81ac5
[   94.592826] [tempesta fw]       enter frang FSM at state 0x6(Frang_Req_Body)
[   94.593354] [tempesta fw]       enter frang FSM at state 0x8(Frang_Req_Trailer)
[   94.593889] [tempesta fw]       enter frang FSM at state 0x9(Frang_Req_Done)
[   94.594788] [tempesta fw]   frang: checks done for client 192.168.122.1
[   94.595422] [tempesta fw]       Finish frang FSM at state 0x9, ret=0
[   94.596570] [tempesta fw]   client was found in tdb
[   94.597101] [tempesta fw]     client 000000005094cb74, users=49
[   94.598068] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x20 len=528 r=18
[   94.598589] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x41 len=463 r=22
[   94.599258] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x68 len=429 r=34
[   94.599753] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x74 len=358 r=29
[   94.600382] [tdb]   Least significant bits 8 collision for key 0x2fc14e6c98b19f6e and new record (len=803) - burst the node 00000000e7057f6c
[   94.600884] [tdb]   alloc iblk 0x664c0
[   94.601363] [tdb]   burst: link bckt=00000000e7057f6c w/ iblk=0x1993 by 0x6 (key=0x1e66d1a4b206c66e)
[   94.601826] [tdb]   link iblk=0000000086ac807e w/ iblk=00000000d73ed6cd (0x1993) by idx=0x6
[   94.602430] [tdb]   Create a new htrie node for key=0x2fc14e6c98b19f6e len=803 bits_used=8
[   94.603081] [tdb]   alloc dblk 0x18d000 for len=803(896)
[   94.604040] [tempesta fw]     Matching request: 00000000bddbd0a5, list: 000000007213dd3d
[   94.604513] [tempesta fw]     Matching request: 00000000bddbd0a5, list: 000000008f2708e9
[   94.604933] [tempesta fw]     rule: 000000008e49b42f, field: 0x5, op: 0x2, arg:5:6'/index'
[   94.605338] [tempesta fw]     rule: 000000006a64db37, field: 0x5, op: 0x2, arg:5:21'/development-services'
[   94.605806] [tempesta fw]     rule: 0000000071d6b08c, field: 0x5, op: 0x2, arg:5:11'/index.html'
[   94.606208] [tempesta fw]     rule: 00000000254fe664, field: 0x5, op: 0x2, arg:5:9'/services'
[   94.606586] [tempesta fw]     rule: 000000001fe9cb98, field: 0x5, op: 0x2, arg:5:14'/services.html'
[   94.607085] [tempesta fw]     rule: 00000000f1b82d5f, field: 0x5, op: 0x2, arg:5:13'/c++-services'
[   94.607640] [tempesta fw]     rule: 0000000002c7b621, field: 0x5, op: 0x2, arg:5:13'/company.html'
[   94.608437] [tempesta fw]     rule: 0000000058484ded, field: 0x5, op: 0x2, arg:5:52'/blog/fast-programming-languages-c-c++-rust-assembly'
[   94.609343] [tempesta fw]     rule: 00000000fff12570, field: 0x1, op: 0x1, arg:1:0''
[   94.610273] [tempesta fw]   frang: check request for client 192.168.122.1, acc=000000001af81ac5
[   94.611011] [tempesta fw]   frang: check incomplete request headers for client 192.168.122.1, acc=000000001af81ac5
[   94.611774] [tempesta fw]       enter frang FSM at state 0x0(Frang_Req_0)
[   94.612573] [tempesta fw]       enter frang FSM at state 0x1(Frang_Req_Hdr_Method)
[   94.613171] [tempesta fw]       enter frang FSM at state 0x2(Frang_Req_Hdr_UriLen)
[   94.613766] [tempesta fw]       enter frang FSM at state 0x3(Frang_Req_Hdr_Check)
[   94.614223] [tempesta fw]       enter frang FSM at state 0x5(Frang_Req_Body_Start)
[   94.614655] [tempesta fw]   frang: check incomplete request body for client 192.168.122.1, acc=000000001af81ac5
[   94.615202] [tempesta fw]       enter frang FSM at state 0x6(Frang_Req_Body)
[   94.615768] [tempesta fw]       enter frang FSM at state 0x8(Frang_Req_Trailer)
[   94.616275] [tempesta fw]       enter frang FSM at state 0x9(Frang_Req_Done)
[   94.616682] [tempesta fw]   frang: checks done for client 192.168.122.1
[   94.617094] [tempesta fw]       Finish frang FSM at state 0x9, ret=0
[   94.617654] [tempesta fw]   client was found in tdb
[   94.618147] [tempesta fw]     client 000000005094cb74, users=50
[   95.226935] [tempesta fw]   client was found in tdb
[   95.227924] [tempesta fw]     client 0000000091929b67, users=2
[   95.228960] [tempesta fw]       new client socket: sk=0000000051ceb65f, state=1
[   95.229945] [tempesta fw]   client was found in tdb
[   95.230935] [tempesta fw]     client 0000000091929b67, users=3
[   95.231768] [tempesta fw]       new client socket is accepted: sk=0000000051ceb65f, conn=00000000ead5886a, cli=0000000091929b67
[   95.232696] [tempesta tls] Warning: [::ffff:10.201.210.8] ClientHello: cannot find matching ALPN for http/1.1
[   95.234685] [tempesta fw]       connection lost: close client socket: sk=0000000051ceb65f, conn=00000000ead5886a, client=0000000091929b67
[   95.235640] [tempesta fw]     put client 0000000091929b67, users=3
[   95.238077] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x20 len=374 r=6
[   95.238882] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x41 len=321 r=22
[   95.239610] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x57 len=189 r=9
[   95.240290] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x68 len=168 r=105
[   95.240987] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x74 len=28 r=24
[   95.241649] [tempesta fw] 192.168.122.1 "default" "GET /wp-admin/ HTTP/2.0" 302 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0"
[   95.252977] [tempesta fw]     Matching request: 00000000a024b64a, list: 000000007213dd3d
[   95.253823] [tempesta fw]     Matching request: 00000000a024b64a, list: 000000008f2708e9
[   95.254349] [tempesta fw]     rule: 000000008e49b42f, field: 0x5, op: 0x2, arg:5:6'/index'
[   95.255064] [tempesta fw]     rule: 000000006a64db37, field: 0x5, op: 0x2, arg:5:21'/development-services'
[   95.255666] [tempesta fw]     rule: 0000000071d6b08c, field: 0x5, op: 0x2, arg:5:11'/index.html'
[   95.256169] [tempesta fw]     rule: 00000000254fe664, field: 0x5, op: 0x2, arg:5:9'/services'
[   95.256632] [tempesta fw]     rule: 000000001fe9cb98, field: 0x5, op: 0x2, arg:5:14'/services.html'
[   95.257105] [tempesta fw]     rule: 00000000f1b82d5f, field: 0x5, op: 0x2, arg:5:13'/c++-services'
[   95.257871] [tempesta fw]     rule: 0000000002c7b621, field: 0x5, op: 0x2, arg:5:13'/company.html'
[   95.258653] [tempesta fw]     rule: 0000000058484ded, field: 0x5, op: 0x2, arg:5:52'/blog/fast-programming-languages-c-c++-rust-assembly'
[   95.259540] [tempesta fw]     rule: 00000000fff12570, field: 0x1, op: 0x1, arg:1:0''
[   95.260079] [tempesta fw]   frang: check request for client 192.168.122.1, acc=000000001af81ac5
[   95.260784] [tempesta fw]   frang: check incomplete request headers for client 192.168.122.1, acc=000000001af81ac5
[   95.261398] [tempesta fw]       enter frang FSM at state 0x0(Frang_Req_0)
[   95.261975] [tempesta fw]       enter frang FSM at state 0x1(Frang_Req_Hdr_Method)
[   95.262589] [tempesta fw]       enter frang FSM at state 0x2(Frang_Req_Hdr_UriLen)
[   95.263209] [tempesta fw]       enter frang FSM at state 0x3(Frang_Req_Hdr_Check)
[   95.263803] [tempesta fw]       enter frang FSM at state 0x5(Frang_Req_Body_Start)
[   95.264364] [tempesta fw]   frang: check incomplete request body for client 192.168.122.1, acc=000000001af81ac5
[   95.264971] [tempesta fw]       enter frang FSM at state 0x6(Frang_Req_Body)
[   95.265527] [tempesta fw]       enter frang FSM at state 0x8(Frang_Req_Trailer)
[   95.266182] [tempesta fw]       enter frang FSM at state 0x9(Frang_Req_Done)
[   95.266639] [tempesta fw]   frang: checks done for client 192.168.122.1
[   95.267193] [tempesta fw]       Finish frang FSM at state 0x9, ret=0
[   95.267860] [tempesta fw]   client was found in tdb
[   95.268368] [tempesta fw]     client 000000005094cb74, users=51
[   95.335474] [tempesta fw]   client was found in tdb
[   95.336005] [tempesta fw]     client 0000000023ab4238, users=15
[   96.338690] [tempesta fw]   client was found in tdb
[   96.340984] [tempesta fw]     client 0000000023ab4238, users=16
[   96.789597] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x20 len=2884 r=3
[   96.790644] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x41 len=2834 r=22
[   96.791718] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x70 len=2662 r=14
[   96.792744] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x53 len=2629 r=10
[   96.793780] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=2557 r=64
[   96.794744] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=2427 r=64
[   96.795759] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=2301 r=74
[   96.796686] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=2161 r=74
[   96.797595] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=2015 r=56
[   96.798471] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1887 r=56
[   96.799376] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1798 r=56
[   96.800186] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1704 r=56
[   96.800956] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1586 r=56
[   96.801711] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1468 r=56
[   96.802485] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1346 r=56
[   96.803386] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1224 r=56
[   96.804380] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=1102 r=56
[   96.805305] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=980 r=56
[   96.806199] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=858 r=56
[   96.807044] [tempesta fw]       tfw_match_ctext_vchar: str[0]=0x65 len=736 r=56
[   96.807950] [tempesta fw] Warning: HTTP/2: too many headers (duplicates) in HTTP/1.1-response (header id: 13, header dups: 17
[   96.808958] [tempesta fw] Warning: Parser error: state=RGen_CR input(-8)=0xa(' path=/
               Set-Cookie: wp-postpass_42fb2087226d3f4') data_len=2896 off=2217
[   96.810917] [tempesta fw] Warning: response dropped: processing error: 192.168.122.1
[   96.811980] [tempesta fw] 192.168.122.1 "default" "GET /wp-login.php?redirect_to=https%3A%2F%2Ftempesta-tech.com%2Fwp-admin%2F&reauth=1 HTTP/2.0" 502 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0"
[   96.814836] [tempesta fw] Warning: Paired request missing, HTTP Response Splitting attack?
[   96.816430] [tempesta fw]   connection error: 10.201.210.8
[   96.823034] [tempesta fw]   connected: 10.201.210.8
[   97.348900] [tempesta fw]   client was found in tdb
[   97.350920] [tempesta fw]     client 0000000023ab4238, users=17
[   98.357416] [tempesta fw]   client was found in tdb
[   98.358277] [tempesta fw]     client 0000000023ab4238, users=18
[   99.599549] [tempesta fw]   connection error: 10.201.210.8
[   99.607042] [tempesta fw]   connected: 10.201.210.8
mbabitski-t commented 1 year ago

For some reason, WordPress or Apache send Set-Cookie Header duplicates.

$ curl --resolve tempesta-tech.com:443:10.201.210.8 -i -s --insecure 'https://tempesta-tech.com/wp-login.php?redirect_to=https%3A%2F%2Ftempesta-tech.com%2Fwp-admin%2F&reauth=1' | head -n 30
HTTP/1.1 200 OK
Date: Wed, 25 Oct 2023 13:26:36 GMT
Server: Apache/2.4.52 (Ubuntu)
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Set-Cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure
X-Frame-Options: SAMEORIGIN
Set-Cookie: wordpress_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/wp-admin
Set-Cookie: wordpress_sec_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/wp-admin
Set-Cookie: wordpress_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/wp-content/plugins
Set-Cookie: wordpress_sec_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/wp-content/plugins
Set-Cookie: wordpress_logged_in_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpress_logged_in_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wp-settings-0=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wp-settings-time-0=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpress_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpress_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpress_sec_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpress_sec_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpressuser_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpresspass_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpressuser_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wordpresspass_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Set-Cookie: wp-postpass_42fb2087226d3f46392648a70a4cc886=%20; expires=Tue, 25-Oct-2022 13:26:36 GMT; Max-Age=0; path=/
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>