diff --git a/SPEC.md b/SPEC.md
index 76f716a..7695c7b 100644
--- a/SPEC.md
+++ b/SPEC.md
@@ -1139,10 +1139,12 @@ The changes hold in front of every app, and no setting undoes them:
- `source` in the JSON body of `/rest.php/`.
- The passwords when signing in, signing up and changing a password:
- `wpPassword` on MediaWiki's pages;
- - `password` and `retype` on `Special:ChangeCredentials`;
- - `retype` on `Special:CreateAccount`;
- - `retype` on `Special:UserLogin`, where a password reset sets the new
- password;
+ - `password` and `retype` on `Special:ChangeCredentials`, whose form
+ sends `authAction=change`;
+ - `retype` on `Special:CreateAccount`, whose form sends
+ `authAction=create`;
+ - `retype` on `Special:UserLogin`, where a password reset or an expired
+ password sets the new password with `authAction=login-continue`;
- `lgpassword`, `password` and `retype` on `/api.php`.
They skip each rule that random passwords set off:
@@ -1156,9 +1158,12 @@ The changes hold in front of every app, and no setting undoes them:
`
` sent as a password reach MediaWiki;
`` and `javascript:alert(1)` are still refused.
- The path must name the special page, or be `/index.php` with a `title`
- that names it. Other apps use `password` and `retype` too, so on any
- other page those two fields keep every rule.
+ Other apps use `password` and `retype` too. So those two fields skip
+ these rules only when `authAction` names the form that sends them. The
+ page's name does not count, because a wiki in another language posts
+ these forms to its own names, such as `Spezial:Benutzerkonto_anlegen`.
+ The page's title must have a namespace, such as `Special:`. The title is
+ after the path, or in the `title` of `/index.php`.
These body exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None
applies when the query has a parameter of the same name.
diff --git a/internal/coreruleset/mediawiki.conf b/internal/coreruleset/mediawiki.conf
index 10fc915..e0f49ba 100644
--- a/internal/coreruleset/mediawiki.conf
+++ b/internal/coreruleset/mediawiki.conf
@@ -194,18 +194,26 @@ SecRule REQUEST_FILENAME "@rx ^/(?:w/)?api\.php$" \
ctl:ruleRemoveTargetById=944150;ARGS:/^(?:lgpassword|password|retype)$/"
# Other apps use the names password and retype too, and these exclusions apply
-# in front of every app. So these two fields skip the same rules only on the
-# pages that take them:
-# password, retype: changing the password at Special:ChangeCredentials
-# retype: signing up at Special:CreateAccount
-# retype: setting the new password after a reset at Special:UserLogin
-# The path names the page, or the path is /index.php and title names it. A title
-# on any other path does not count, so another app's paths under /index.php/
-# keep every rule.
-SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/(?:(?:w/)?index\.php|wiki)/Special:ChangeCredentials(?:/|$)" \
- "id:900919,phase:1,pass,nolog,chain"
- SecRule REQUEST_FILENAME|ARGS_GET:title "@rx ^(?:/(?:(?:w/)?index\.php|wiki)/)?Special:ChangeCredentials(?:/|$)" "chain"
- SecRule &ARGS_GET:/^(?:password|retype)$/ "@eq 0" \
+# in front of every app. So these two fields skip the same rules only in the
+# forms that send them. Each of these forms sends the field authAction, whose
+# value is the same in every language:
+# password, retype: authAction=change, changing the password at
+# Special:ChangeCredentials
+# retype: authAction=create, signing up at Special:CreateAccount
+# retype: authAction=login-continue, setting a new password at
+# Special:UserLogin after a reset or once the old one expired
+# A wiki in another language posts these forms to its own names for the pages,
+# such as Spezial:Benutzerkonto_anlegen on a German wiki. So the page's name
+# does not count, but its title must have a namespace, such as Special: or
+# Spezial:. The title is after the path, or in title on /index.php. A title on
+# any other path does not count, so another app's paths under /index.php/ keep
+# every rule. These rules are in phase 2, because the forms send authAction in
+# the body.
+SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/(?:(?:w/)?index\.php|wiki)/[^/:]+:" \
+ "id:900919,phase:2,pass,nolog,chain"
+ SecRule REQUEST_FILENAME|ARGS_GET:title "@rx ^(?:/(?:(?:w/)?index\.php|wiki)/)?[^/:]+:" "chain"
+ SecRule &ARGS_GET:/^(?:password|retype)$/ "@eq 0" "chain"
+ SecRule ARGS:authAction "@streq change" \
"ctl:ruleRemoveTargetById=920270;ARGS:/^(?:password|retype)$/,\
ctl:ruleRemoveTargetById=920540;ARGS:/^(?:password|retype)$/,\
ctl:ruleRemoveTargetById=921200;ARGS:/^(?:password|retype)$/,\
@@ -242,10 +250,11 @@ SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/(?:(?:w/)?index\.php|wiki)/
ctl:ruleRemoveTargetById=942550;ARGS:/^(?:password|retype)$/,\
ctl:ruleRemoveTargetById=944150;ARGS:/^(?:password|retype)$/"
-SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/(?:(?:w/)?index\.php|wiki)/Special:(?:CreateAccount|UserLogin)(?:/|$)" \
- "id:900920,phase:1,pass,nolog,chain"
- SecRule REQUEST_FILENAME|ARGS_GET:title "@rx ^(?:/(?:(?:w/)?index\.php|wiki)/)?Special:(?:CreateAccount|UserLogin)(?:/|$)" "chain"
- SecRule &ARGS_GET:retype "@eq 0" \
+SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/(?:(?:w/)?index\.php|wiki)/[^/:]+:" \
+ "id:900920,phase:2,pass,nolog,chain"
+ SecRule REQUEST_FILENAME|ARGS_GET:title "@rx ^(?:/(?:(?:w/)?index\.php|wiki)/)?[^/:]+:" "chain"
+ SecRule &ARGS_GET:retype "@eq 0" "chain"
+ SecRule ARGS:authAction "@rx ^(?:create|login-continue)$" \
"ctl:ruleRemoveTargetById=920270;ARGS:retype,\
ctl:ruleRemoveTargetById=920540;ARGS:retype,\
ctl:ruleRemoveTargetById=921200;ARGS:retype,\
diff --git a/internal/coreruleset/mediawiki_test.go b/internal/coreruleset/mediawiki_test.go
index 8e0ae88..e9a7bfb 100644
--- a/internal/coreruleset/mediawiki_test.go
+++ b/internal/coreruleset/mediawiki_test.go
@@ -248,26 +248,52 @@ func TestMediaWikiSignUpAndPasswordChangeFieldsPass(t *testing.T) {
// The form that changes a password posts to this subpage.
const subpage = "/MediaWiki%5CAuth%5CPasswordAuthenticationRequest"
+ // The forms send authAction in the body, and MediaWiki reads it from the
+ // query too. These requests send it in the query, so that the body holds
+ // only the passwords. The recorded requests send it in the body.
+ const (
+ create = "authAction=create"
+ loginContinue = "authAction=login-continue"
+ changeAction = "authAction=change"
+ )
+
change := []string{passwordKey, retypeKey}
retype := []string{retypeKey}
wantPasswordFieldsPass(t, []passwordFields{
- {mediawikiSignUp, formData, retype},
- {"/index.php/Special:CreateAccount", formData, retype},
- {"/index.php?title=Special:CreateAccount&returnto=Main_Page", formData, retype},
- {"/wiki/Special:UserLogin", formData, retype},
- {mediawikiSignIn, formData, retype},
- {mediawikiAccountChange, formData, change},
- {mediawikiAccountChange + subpage, formData, change},
- {"/index.php/Special:ChangeCredentials", formData, change},
- {"/index.php?title=Special:ChangeCredentials" + subpage, formData, change},
- {"/w/index.php?title=Special:ChangeCredentials", formData, change},
+ {mediawikiSignUp + "?" + create, formData, retype},
+ {"/index.php/Special:CreateAccount?" + create, formData, retype},
+ {
+ "/index.php?title=Special:CreateAccount&returnto=Main_Page&" + create,
+ formData, retype,
+ },
+ {"/wiki/Special:UserLogin?" + loginContinue, formData, retype},
+ {mediawikiSignIn + "&" + loginContinue, formData, retype},
+ {mediawikiAccountChange + "?" + changeAction, formData, change},
+ {mediawikiAccountChange + subpage + "?" + changeAction, formData, change},
+ {"/index.php/Special:ChangeCredentials?" + changeAction, formData, change},
+ {
+ "/index.php?title=Special:ChangeCredentials" + subpage + "&" + changeAction,
+ formData, change,
+ },
+ {"/w/index.php?title=Special:ChangeCredentials&" + changeAction, formData, change},
+ // A German wiki's names for the same pages.
+ {"/index.php/Spezial:Benutzerkonto_anlegen?" + create, formData, retype},
+ {
+ "/index.php?title=Spezial:Anmelden&returnto=Hauptseite&" + loginContinue,
+ formData, retype,
+ },
+ {
+ "/wiki/Spezial:Anmeldeinformationen_%C3%A4ndern" + subpage + "?" + changeAction,
+ formData, change,
+ },
{mediawikiAPI, formData, retype},
})
}
// Other apps use the names password and retype too. So these fields keep every
-// rule on any page that does not take them, whatever title the query names.
+// rule unless the page is MediaWiki's, its title has a namespace, and
+// authAction names a form that sends the field.
func TestMediaWikiPasswordFieldsStayCheckedOffTheirPages(t *testing.T) {
t.Parallel()
@@ -277,15 +303,17 @@ func TestMediaWikiPasswordFieldsStayCheckedOffTheirPages(t *testing.T) {
for _, sent := range []struct{ target, name string }{
{appPath, passwordKey},
- {appPath, retypeKey},
- {appPath + "?title=Special:ChangeCredentials", passwordKey},
- {appPath + "?title=Special:CreateAccount", retypeKey},
- {"/index.php?title=Main_Page", passwordKey},
- {"/index.php/Main_Page", retypeKey},
- {"/wiki/Main_Page", passwordKey},
- {"/wiki/Special:ChangeCredentialsExample", passwordKey},
- {mediawikiSignUp, passwordKey},
- {"/index.php?title=Special:CreateAccount", passwordKey},
+ {appPath + "?authAction=create", retypeKey},
+ {appPath + "?title=Special:ChangeCredentials&authAction=change", passwordKey},
+ {appPath + "?title=Special:CreateAccount&authAction=create", retypeKey},
+ {"/index.php?title=Main_Page&authAction=change", passwordKey},
+ {"/index.php/Main_Page?authAction=create", retypeKey},
+ {"/wiki/Main_Page?authAction=change", passwordKey},
+ {mediawikiAccountChange, passwordKey},
+ {mediawikiAccountChange + "?authAction=login", passwordKey},
+ {mediawikiSignUp + "?authAction=create", passwordKey},
+ {"/index.php?title=Special:CreateAccount&authAction=create", passwordKey},
+ {"/index.php/Spezial:Anmelden?authAction=login", retypeKey},
} {
r := request{http.MethodPost, sent.target, []string{formData}}
diff --git a/internal/coreruleset/testdata/mediawiki-requests.txt b/internal/coreruleset/testdata/mediawiki-requests.txt
index 8224e74..2419501 100644
--- a/internal/coreruleset/testdata/mediawiki-requests.txt
+++ b/internal/coreruleset/testdata/mediawiki-requests.txt
@@ -600,3 +600,14 @@
{"method": "POST", "target": "/index.php/Special:EditWatchlist/raw", "headers": ["Host: example.com", "Content-Length: 161", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Origin: http://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php?title=Special:EditWatchlist/raw", "Accept-Encoding: gzip, deflate", "Cookie: my_wiki_session=ed9592ia2u8ub3tdanl6632jbgboksr9; my_wikiUserID=2; my_wikiUserName=Admin; cpPosIndex=2%401794271545%23fad50a8505bea134cc843d03608984cc; UseDC=master"], "body": "title=Special%3AEditWatchlist%2Fraw&wpTitles=Lighthouse+notes%0D%0APython3+notes%0D%0APowershell+notes&wpEditToken=b2872c8548fbba5f193e80b549d5da2f6af26939%2B%5C"}
{"method": "POST", "target": "/index.php/Special:EditWatchlist/raw", "headers": ["Host: example.com", "Content-Length: 179", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Origin: http://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php?title=Special:EditWatchlist/raw", "Accept-Encoding: gzip, deflate", "Cookie: my_wiki_session=ed9592ia2u8ub3tdanl6632jbgboksr9; my_wikiUserID=2; my_wikiUserName=Admin; UseDC=master; cpPosIndex=3%401794271545%23fad50a8505bea134cc843d03608984cc"], "body": "title=Special%3AEditWatchlist%2Fraw&wpTitles=Lighthouse+notes%0D%0APowershell+notes%0D%0APython3+notes%0D%0ALs+-la+notes&wpEditToken=b2872c8548fbba5f193e80b549d5da2f6af26939%2B%5C"}
{"method": "POST", "target": "/index.php/Special:EditWatchlist/raw", "headers": ["Host: example.com", "Content-Length: 200", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Origin: http://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php?title=Special:EditWatchlist/raw", "Accept-Encoding: gzip, deflate", "Cookie: my_wiki_session=ed9592ia2u8ub3tdanl6632jbgboksr9; my_wikiUserID=2; my_wikiUserName=Admin; UseDC=master; cpPosIndex=4%401794271545%23fad50a8505bea134cc843d03608984cc"], "body": "title=Special%3AEditWatchlist%2Fraw&wpTitles=Lighthouse+notes%0D%0ALs+-la+notes%0D%0APowershell+notes%0D%0APython3+notes%0D%0A.htaccess+notes&wpEditToken=b2872c8548fbba5f193e80b549d5da2f6af26939%2B%5C"}
+# From a German wiki without short URLs, whose forms post to the German names of
+# the special pages: signing up, changing the password, and setting a new
+# password at sign-in once the old one expired. Each password is random.
+{"method": "GET", "target": "/index.php/Spezial:Benutzerkonto_anlegen", "headers": ["Host: example.com", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9"], "body": ""}
+{"method": "POST", "target": "/index.php/Spezial:Benutzerkonto_anlegen", "headers": ["Host: example.com", "Content-Length: 328", "Cache-Control: max-age=0", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Origin: http://example.com", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php/Spezial:Benutzerkonto_anlegen", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=n6eeeqk2f317s76jc5710hofe2o5pk65"], "body": "title=Spezial%3ABenutzerkonto+anlegen&wpName=Beispielnutzer&wpPassword=+%2F%22j14y%5B%25%5C%28iM%5DzmG%25%3D%5E&retype=+%2F%22j14y%5B%25%5C%28iM%5DzmG%25%3D%5E&email=&realname=&wpEditToken=%2B%5C&authAction=create&force=&wpCreateaccountToken=e75eca0539b22c74e93948a1d4631c466af3953d%2B%5C&wpCreateaccount=Benutzerkonto+erstellen"}
+{"method": "GET", "target": "/index.php/Spezial:Anmeldeinformationen_%C3%A4ndern/MediaWiki%5CAuth%5CPasswordAuthenticationRequest", "headers": ["Host: example.com", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=gfiqj1icq48j4cu6ghubpfc7n5css8ee; my_wikiUserID=3; my_wikiUserName=Beispielnutzer; cpPosIndex=1%401794348350%2383f0234f558f9a2917ed83d7eb2c1095; UseDC=master"], "body": ""}
+{"method": "POST", "target": "/index.php/Spezial:Anmeldeinformationen_%C3%A4ndern/MediaWiki%5CAuth%5CPasswordAuthenticationRequest", "headers": ["Host: example.com", "Content-Length: 333", "Cache-Control: max-age=0", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Origin: http://example.com", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php/Spezial:Anmeldeinformationen_%C3%A4ndern/MediaWiki%5CAuth%5CPasswordAuthenticationRequest", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=gfiqj1icq48j4cu6ghubpfc7n5css8ee; my_wikiUserID=3; my_wikiUserName=Beispielnutzer; cpPosIndex=1%401794348350%2383f0234f558f9a2917ed83d7eb2c1095; UseDC=master"], "body": "title=Spezial%3AAnmeldeinformationen+%C3%A4ndern%2FMediaWiki%5CAuth%5CPasswordAuthenticationRequest&password=Z%3E%22%7BZ%5CQDwqBQs%25v%7D%60nBu&retype=Z%3E%22%7BZ%5CQDwqBQs%25v%7D%60nBu&wpusername=&wpEditToken=a0fa962ce1b1e7c743ff500b3a740c236af3953e%2B%5C&wpAuthToken=2ea5e8a20a3cfa31cce14265135edf856af3953e%2B%5C&authAction=change"}
+{"method": "GET", "target": "/index.php/Spezial:Anmelden", "headers": ["Host: example.com", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9"], "body": ""}
+{"method": "POST", "target": "/index.php/Spezial:Anmelden", "headers": ["Host: example.com", "Content-Length: 219", "Cache-Control: max-age=0", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Origin: http://example.com", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php/Spezial:Anmelden", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=49u0bk921kv5dan4pc4i86e1nvbqerur"], "body": "title=Spezial%3AAnmelden&wpName=Beispielnutzer&wpPassword=Z%3E%22%7BZ%5CQDwqBQs%25v%7D%60nBu&wpEditToken=%2B%5C&authAction=login&force=&wpLoginToken=d5a70412545c3a0a18b18e04dbf80c636af3953e%2B%5C&wploginattempt=Anmelden"}
+{"method": "POST", "target": "/index.php/Spezial:Anmelden", "headers": ["Host: example.com", "Content-Length: 272", "Cache-Control: max-age=0", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Origin: http://example.com", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php/Spezial:Anmelden", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=49u0bk921kv5dan4pc4i86e1nvbqerur"], "body": "title=Spezial%3AAnmelden&wpName=&wpPassword=gJ%3CEcT%29jhZ%27%60GC%3EcX%7EhM&retype=gJ%3CEcT%29jhZ%27%60GC%3EcX%7EhM&wpEditToken=%2B%5C&authAction=login-continue&force=&wpLoginToken=d5a70412545c3a0a18b18e04dbf80c636af3953e%2B%5C&wploginattempt=Mit+der+Anmeldung+fortfahren"}
+{"method": "GET", "target": "/index.php/Hauptseite", "headers": ["Host: example.com", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/index.php/Spezial:Anmelden", "Accept-Encoding: gzip, deflate", "Accept-Language: de-DE,de;q=0.9", "Cookie: my_wiki_session=hd06l4sbv7mprq1ogl7ia3p62rm2o68n; my_wikiUserID=3; my_wikiUserName=Beispielnutzer; cpPosIndex=3%401794348350%2383f0234f558f9a2917ed83d7eb2c1095; UseDC=master"], "body": ""}