diff --git a/tests/integration/docker-compose.setup.yml b/tests/integration/docker-compose.setup.yml
index e5050da8f..122966f36 100644
--- a/tests/integration/docker-compose.setup.yml
+++ b/tests/integration/docker-compose.setup.yml
@@ -371,6 +371,11 @@ services:
MYSQL_DATABASE: ${WP_MYSQL_DATABASE}
MYSQL_USER: ${WP_MYSQL_USER}
MYSQL_PASSWORD: ${WP_MYSQL_PASSWORD}
+ # Apache container for the csrf module
+ csrf:
+ <<: [ *default_php_setup, *healthcheck_web ]
+ volumes:
+ - ./test_mod_csrf/php/src:/var/www/html/
# Wordpress container
wordpress:
@@ -463,6 +468,8 @@ services:
condition: service_healthy
http_headers:
condition: service_healthy
+ csrf:
+ condition: service_healthy
wordpress:
condition: service_healthy
backup:
diff --git a/tests/integration/run.sh b/tests/integration/run.sh
index 4d0d6f1a2..6cb2cf4df 100755
--- a/tests/integration/run.sh
+++ b/tests/integration/run.sh
@@ -9,6 +9,7 @@ test_mod_buster \
test_mod_cookieflags \
test_mod_crlf \
test_mod_csp \
+test_mod_csrf \
test_mod_drupal_enum \
test_mod_htaccess \
test_mod_http_headers \
diff --git a/tests/integration/test_mod_csrf/assertions/check.sh b/tests/integration/test_mod_csrf/assertions/check.sh
new file mode 120000
index 000000000..aa85f6fcd
--- /dev/null
+++ b/tests/integration/test_mod_csrf/assertions/check.sh
@@ -0,0 +1 @@
+../../check.sh
\ No newline at end of file
diff --git a/tests/integration/test_mod_csrf/assertions/csrf_fake_protected_form.php.json b/tests/integration/test_mod_csrf/assertions/csrf_fake_protected_form.php.json
new file mode 100644
index 000000000..b83b352a3
--- /dev/null
+++ b/tests/integration/test_mod_csrf/assertions/csrf_fake_protected_form.php.json
@@ -0,0 +1,202 @@
+{
+ "vulnerabilities": {
+ "Cross Site Request Forgery": [
+ {
+ "method": "POST",
+ "path": "/fake_protected_form.php",
+ "info": "CSRF token 'csrf_token' might be easy to predict",
+ "parameter": "",
+ "module": "csrf",
+ "http_request": "POST /fake_protected_form.php HTTP/1.1\ncontent-type: application/x-www-form-urlencoded, application/x-www-form-urlencoded\nhost: csrf\nconnection: keep-alive\nuser-agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0\naccept-language: en-US\naccept-encoding: gzip, deflate, br\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\nreferer: http://csrf/fake_protected_form.php\ncookie: PHPSESSID=1335df1b1b4a2149e8690c7ce5fc3932\ncontent-length: 39\nContent-Type: application/x-www-form-urlencoded\n\ncsrf_token=AAAAAAAAAAAAAAA&name=default",
+ "wstg": [
+ "WSTG-SESS-05"
+ ]
+ }
+ ]
+ },
+ "infos": {
+ "target": "http://csrf/fake_protected_form.php",
+ "crawled_pages": [
+ {
+ "request": {
+ "url": "http://csrf/fake_protected_form.php",
+ "method": "GET",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "
\t\tCSRF protected test ",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "226"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=1335df1b1b4a2149e8690c7ce5fc3932; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ },
+ {
+ "request": {
+ "url": "http://csrf/fake_protected_form.php",
+ "method": "POST",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "content-length",
+ "39"
+ ],
+ [
+ "content-type",
+ "application/x-www-form-urlencoded"
+ ],
+ [
+ "cookie",
+ "PHPSESSID=1335df1b1b4a2149e8690c7ce5fc3932"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "referer",
+ "http://csrf/fake_protected_form.php"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "\t\tCSRF protected test form submitted !",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "232"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=1335df1b1b4a2149e8690c7ce5fc3932; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/test_mod_csrf/assertions/csrf_protected_form.php.json b/tests/integration/test_mod_csrf/assertions/csrf_protected_form.php.json
new file mode 100644
index 000000000..146edeb2a
--- /dev/null
+++ b/tests/integration/test_mod_csrf/assertions/csrf_protected_form.php.json
@@ -0,0 +1,190 @@
+{
+ "vulnerabilities": {
+ "Cross Site Request Forgery": []
+ },
+ "infos": {
+ "target": "http://csrf/protected_form.php",
+ "crawled_pages": [
+ {
+ "request": {
+ "url": "http://csrf/protected_form.php",
+ "method": "GET",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "\t\tCSRF protected test ",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "273"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=ldsu3ighl8der4ujghl3siur1fhgiu; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ },
+ {
+ "request": {
+ "url": "http://csrf/protected_form.php",
+ "method": "POST",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "content-length",
+ "88"
+ ],
+ [
+ "content-type",
+ "application/x-www-form-urlencoded"
+ ],
+ [
+ "cookie",
+ "PHPSESSID=ldsu3ighl8der4ujghl3siur1fhgiu"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "referer",
+ "http://csrf/protected_form.php"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "\t\tCSRF protected test form submitted !",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "279"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=ldsu3ighl8der4ujghl3siur1fhgiu; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/test_mod_csrf/assertions/csrf_unprotected_form.php.json b/tests/integration/test_mod_csrf/assertions/csrf_unprotected_form.php.json
new file mode 100644
index 000000000..3761839da
--- /dev/null
+++ b/tests/integration/test_mod_csrf/assertions/csrf_unprotected_form.php.json
@@ -0,0 +1,202 @@
+{
+ "vulnerabilities": {
+ "Cross Site Request Forgery": [
+ {
+ "method": "POST",
+ "path": "/unprotected_form.php",
+ "info": "Lack of anti CSRF token",
+ "parameter": "",
+ "module": "csrf",
+ "http_request": "POST /unprotected_form.php HTTP/1.1\nhost: csrf\nconnection: keep-alive\nuser-agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0\naccept-language: en-US\naccept-encoding: gzip, deflate, br\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\ncontent-type: application/x-www-form-urlencoded\nreferer: http://csrf/unprotected_form.php\ncookie: PHPSESSID=8f6s47ef68wse4f38esfsfew864fqdez\ncontent-length: 12\nContent-Type: application/x-www-form-urlencoded\n\nname=default",
+ "wstg": [
+ "WSTG-SESS-05"
+ ]
+ }
+ ]
+ },
+ "infos": {
+ "target": "http://csrf/unprotected_form.php",
+ "crawled_pages": [
+ {
+ "request": {
+ "url": "http://csrf/unprotected_form.php",
+ "method": "GET",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "\n\n\n\t\n\tCSRF unprotected test\n\n\n \n\n\n\n",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "206"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=8f6s47ef68wse4f38esfsfew864fqdez; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ },
+ {
+ "request": {
+ "url": "http://csrf/unprotected_form.php",
+ "method": "POST",
+ "headers": [
+ [
+ "accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
+ ],
+ [
+ "accept-encoding",
+ "gzip, deflate, br"
+ ],
+ [
+ "accept-language",
+ "en-US"
+ ],
+ [
+ "connection",
+ "keep-alive"
+ ],
+ [
+ "content-length",
+ "12"
+ ],
+ [
+ "content-type",
+ "application/x-www-form-urlencoded"
+ ],
+ [
+ "cookie",
+ "PHPSESSID=8f6s47ef68wse4f38esfsfew864fqdez"
+ ],
+ [
+ "host",
+ "csrf"
+ ],
+ [
+ "referer",
+ "http://csrf/unprotected_form.php"
+ ],
+ [
+ "user-agent",
+ "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0"
+ ]
+ ]
+ },
+ "response": {
+ "status_code": 200,
+ "body": "form submitted !\n\n\n\t\n\tCSRF unprotected test\n\n\n \n\n\n\n",
+ "headers": [
+ [
+ "cache-control",
+ "no-store, no-cache, must-revalidate"
+ ],
+ [
+ "connection",
+ "Keep-Alive"
+ ],
+ [
+ "content-encoding",
+ "gzip"
+ ],
+ [
+ "content-length",
+ "215"
+ ],
+ [
+ "content-type",
+ "text/html; charset=UTF-8"
+ ],
+ [
+ "expires",
+ "Thu, 19 Nov 1981 08:52:00 GMT"
+ ],
+ [
+ "pragma",
+ "no-cache"
+ ],
+ [
+ "server",
+ "Apache/2.4.56 (Debian)"
+ ],
+ [
+ "set-cookie",
+ "PHPSESSID=8f6s47ef68wse4f38esfsfew864fqdez; path=/"
+ ],
+ [
+ "vary",
+ "Accept-Encoding"
+ ],
+ [
+ "x-powered-by",
+ "PHP/8.1.18"
+ ]
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/test_mod_csrf/php/src/fake_protected_form.php b/tests/integration/test_mod_csrf/php/src/fake_protected_form.php
new file mode 100644
index 000000000..a8cdc4a0b
--- /dev/null
+++ b/tests/integration/test_mod_csrf/php/src/fake_protected_form.php
@@ -0,0 +1,44 @@
+';
+echo '';
+echo '';
+echo ' ';
+echo ' CSRF protected test';
+echo '';
+echo '';
+echo ' ';
+echo '';
+echo '';
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST'){
+ if(isset($_SESSION['csrf_token']) && isset($_POST['csrf_token'])){
+ if ($_POST['csrf_token'] !== $_SESSION['csrf_token']){
+ http_response_code(403);
+ die('CSRF token mismatch');
+ }
+ else{
+ http_response_code(200);
+ echo "form submitted !";
+ }
+ }
+ else{
+ http_response_code(403);
+ echo "CSRF token missing";
+ }
+}
+?>
diff --git a/tests/integration/test_mod_csrf/php/src/index.php b/tests/integration/test_mod_csrf/php/src/index.php
new file mode 100644
index 000000000..c3a2a248b
--- /dev/null
+++ b/tests/integration/test_mod_csrf/php/src/index.php
@@ -0,0 +1,15 @@
+
+
+
+ Index
+
+
+ Index
+ This is a simple PHP web page.
+
+
+
diff --git a/tests/integration/test_mod_csrf/php/src/protected_form.php b/tests/integration/test_mod_csrf/php/src/protected_form.php
new file mode 100644
index 000000000..2e761a792
--- /dev/null
+++ b/tests/integration/test_mod_csrf/php/src/protected_form.php
@@ -0,0 +1,43 @@
+';
+echo '';
+echo '';
+echo ' ';
+echo ' CSRF protected test';
+echo '';
+echo '';
+echo ' ';
+echo '';
+echo '';
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST'){
+ if(isset($_SESSION['csrf_token']) && isset($_POST['csrf_token'])){
+ if ($_POST['csrf_token'] !== $_SESSION['csrf_token']){
+ http_response_code(403);
+ die('CSRF token mismatch');
+ }
+ else{
+ http_response_code(200);
+ echo "form submitted !";
+ }
+ }
+ else{
+ http_response_code(403);
+ echo "CSRF token missing";
+ }
+}
+?>
diff --git a/tests/integration/test_mod_csrf/php/src/unprotected_form.php b/tests/integration/test_mod_csrf/php/src/unprotected_form.php
new file mode 100644
index 000000000..f13b4408d
--- /dev/null
+++ b/tests/integration/test_mod_csrf/php/src/unprotected_form.php
@@ -0,0 +1,23 @@
+
+
+
+
+
+ CSRF unprotected test
+
+
+
+
+
+
diff --git a/tests/integration/wapiti/modules.json b/tests/integration/wapiti/modules.json
index 064714694..ed9ec70b3 100644
--- a/tests/integration/wapiti/modules.json
+++ b/tests/integration/wapiti/modules.json
@@ -998,5 +998,52 @@
"erase_global_supplementary": false
}
]
+ },
+ "test_mod_csrf": {
+ "modules": "csrf",
+ "supplementary_argument": "",
+ "report_filter_tree": {
+ "vulnerabilities": {
+ "Cross Site Request Forgery": [
+ {
+ "method": "",
+ "path": "",
+ "info": "",
+ "parameter": "",
+ "module": "",
+ "http_request": "",
+ "wstg": ""
+ }
+ ]
+ },
+ "infos": {
+ "target": "",
+ "crawled_pages": [
+ {
+ "request": {
+ "url": "",
+ "method": "",
+ "headers": []
+ },
+ "response": {
+ "status_code": 0,
+ "body": "",
+ "headers": []
+ }
+ }
+ ]
+ }
+ },
+ "targets": [
+ {
+ "name": "http://csrf/protected_form.php"
+ },
+ {
+ "name": "http://csrf/fake_protected_form.php"
+ },
+ {
+ "name": "http://csrf/unprotected_form.php"
+ }
+ ]
}
}
\ No newline at end of file