diff --git a/src/HTMLDocumentProtector.php b/src/HTMLDocumentProtector.php
index 4e8ca9d..6c2b7d5 100644
--- a/src/HTMLDocumentProtector.php
+++ b/src/HTMLDocumentProtector.php
@@ -52,17 +52,24 @@ public function protect(
string $tokenSharing = self::ONE_TOKEN_PER_PAGE
):string {
$forms = $this->document->forms;
+ $tokenArray = [];
- if($forms->length > 0) {
- $token = $this->tokenStore->generateNewToken();
- $this->tokenStore->saveToken($token);
+ $token = null;
+ if($forms->length > 0) {
foreach($forms as $form) {
$formMethod = $form->getAttribute("method");
if(strtolower($formMethod) !== "post") {
continue;
}
+ if($tokenSharing === self::ONE_TOKEN_PER_FORM
+ || is_null($token)) {
+ $token = $this->tokenStore->generateNewToken();
+ $this->tokenStore->saveToken($token);
+ array_push($tokenArray, $token);
+ }
+
$csrfElement = $this->document->createElement(
"input"
);
@@ -82,16 +89,13 @@ public function protect(
$csrfElement,
$form->firstChild
);
-
- if($tokenSharing === self::ONE_TOKEN_PER_FORM) {
- $token = $this->tokenStore->generateNewToken();
- $this->tokenStore->saveToken($token);
- }
}
}
- else {
+
+ if(is_null($token)) {
$token = $this->tokenStore->generateNewToken();
$this->tokenStore->saveToken($token);
+ array_push($tokenArray, $token);
}
$meta = $this->document->querySelector(
@@ -123,8 +127,7 @@ public function protect(
$head->appendChild($meta);
}
- $meta->setAttribute("content", $token);
-
+ $meta->setAttribute("content", implode(",", $tokenArray));
return $token;
}
diff --git a/test/phpunit/HTMLDocumentProtectorTest.php b/test/phpunit/HTMLDocumentProtectorTest.php
index 22c51f3..a8bc9d6 100644
--- a/test/phpunit/HTMLDocumentProtectorTest.php
+++ b/test/phpunit/HTMLDocumentProtectorTest.php
@@ -253,6 +253,19 @@ public function testProtect_metaTagAlreadyExists():void {
self::assertNotEquals($originalValue, $metaTag->content);
}
+ public function testProtect_metaTagMultipleForms():void {
+ $document = new HTMLDocument(self::THREE_FORMS);
+ $sut = new HTMLDocumentProtector($document, new ArrayTokenStore());
+ $sut->protect(HTMLDocumentProtector::ONE_TOKEN_PER_FORM);
+
+ $nodeList = $document->querySelectorAll("head meta[name='" . HTMLDocumentProtector::TOKEN_NAME . "']");
+// There should still only be 1 meta tag...
+ self::assertCount(1, $nodeList);
+// ... but the tag's content should have two values (one per POST form).
+ $tokenArray = explode(",", $nodeList[0]->content);
+ self::assertCount(2, $tokenArray);
+ }
+
public function testProtect_differentTokenName() {
$sut = new HTMLDocumentProtector(new HTMLDocument(self::HAS_META_ALREADY), new ArrayTokenStore());
$tokenName = HTMLDocumentProtector::TOKEN_NAME;