CVE-2017-9365: Cross-Site Request Forgery (CSRF) (CWE-352)
value: CSRF exists in BigTree CMS through 4.2.18 with the force parameter to /admin/pages/revisions.php - for example: /admin/pages/revisions/1/?force=false. A page with id=1 can be unlocked.
CWE description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
CVSS v3 base score: 8.8
Published: 2017-06-02T05:29Z
Repository: https://github.com/bigtreecms/BigTree-CMS
Language: PHP
Files changed: core/admin/auto-modules/forms/_locked.php, core/admin/auto-modules/forms/edit.php, core/admin/modules/pages/_locked.php, core/admin/modules/pages/edit.php, core/admin/modules/pages/revisions.php
Commit date: 2017-05-25 16:40:42 -0400
Commit message: Remove the possibility of a CSRF attack unlocking a page / module entry.
https://github.com/bigtreecms/BigTree-CMS/issues/281

Diff: diff --git a/core/admin/auto-modules/forms/_locked.php b/core/admin/auto-modules/forms/_locked.php
index 20dd47e5c..689061e4b 100755
--- a/core/admin/auto-modules/forms/_locked.php
+++ b/core/admin/auto-modules/forms/_locked.php
@@ -11,10 +11,10 @@
 			<strong><?=$locked_by["name"]?></strong> currently has this entry locked for editing.  It was last accessed by <strong><?=$locked_by["name"]?></strong> on <strong><?=date("F j, Y @ g:ia",strtotime($last_accessed))?></strong>.<br />
 		If you would like to edit it anyway, please click "Unlock" below.  Otherwise, click "Cancel".
 		</p>
 	</section>
 	<footer>
-		<a href="?force=true<?=$view_data?>" class="button blue">Unlock</a>
+		<a href="?force=true<?=$view_data?><? $admin->drawCSRFTokenGET(); ?>" class="button blue">Unlock</a>
 		&nbsp;
 		<a href="javascript:history.go(-1);" class="button white">Cancel</a>
 	</footer>
 </div>
\ No newline at end of file
diff --git a/core/admin/auto-modules/forms/edit.php b/core/admin/auto-modules/forms/edit.php
index 5d86d7fa1..e4d448560 100755
--- a/core/admin/auto-modules/forms/edit.php
+++ b/core/admin/auto-modules/forms/edit.php
@@ -1,8 +1,14 @@
 <?
 	// Check for a page lock
-	$force = isset($_GET["force"]) ? true : false;
+	if (!empty($_GET["force"])) {
+		$admin->verifyCSRFToken();
+		$force = true;
+	} else {
+		$force = false;
+	}
+	
 	$admin->lockCheck($bigtree["form"]["table"],$bigtree["edit_id"],"admin/auto-modules/forms/_locked.php",$force);
 	
 	$pending_entry = BigTreeAutoModule::getPendingItem($bigtree["form"]["table"],$bigtree["edit_id"]);
 	$original_item = BigTreeAutoModule::getItem($bigtree["form"]["table"],$bigtree["edit_id"]);
 		
diff --git a/core/admin/modules/pages/_locked.php b/core/admin/modules/pages/_locked.php
index bd5218331..49c158778 100755
--- a/core/admin/modules/pages/_locked.php
+++ b/core/admin/modules/pages/_locked.php
@@ -10,8 +10,8 @@
 		</p>
 	</section>
 	<footer>
 		<a href="javascript:history.go(-1);" class="button white">Cancel</a>
 		&nbsp;
-		<a href="?force=true" class="button blue">Unlock</a>
+		<a href="?force=true<? $admin->drawCSRFTokenGET() ?>" class="button blue">Unlock</a>
 	</footer>
 </div>
\ No newline at end of file
diff --git a/core/admin/modules/pages/edit.php b/core/admin/modules/pages/edit.php
index dadb2bda2..ed17edf07 100755
--- a/core/admin/modules/pages/edit.php
+++ b/core/admin/modules/pages/edit.php
@@ -4,11 +4,17 @@
 	
 	// Show the properties section
 	include BigTree::path("admin/modules/pages/_properties.php");
 	
 	// Check for a page lock
-	$force = isset($_GET["force"]) ? $_GET["force"] : false;
+	if (!empty($_GET["force"])) {
+		$admin->verifyCSRFToken();
+		$force = true;
+	} else {
+		$force = false;
+	}
+	
 	$admin->lockCheck("bigtree_pages",$page["id"],"admin/modules/pages/_locked.php",$force);
 	
 	// Grab template information
 	$template_data = $cms->getTemplate($page["template"]);
 
diff --git a/core/admin/modules/pages/revisions.php b/core/admin/modules/pages/revisions.php
index 9b0b183f7..91b115b54 100755
--- a/core/admin/modules/pages/revisions.php
+++ b/core/admin/modules/pages/revisions.php
@@ -30,11 +30,17 @@
 <?
 		$admin->stop();
 	}
 	
 	// Check for a page lock
-	$force = isset($_GET["force"]) ? $_GET["force"] : false;
+	if (!empty($_GET["force"])) {
+		$admin->verifyCSRFToken();
+		$force = true;
+	} else {
+		$force = false;
+	}
+
 	$lock_id = $admin->lockCheck("bigtree_pages",$page["id"],"admin/modules/pages/_locked.php",$force);
 	
 	// See if there's a draft copy.
 	$draft = $admin->getPageChanges($page["id"]);
 	

Vulnerable code: 		<a href="?force=true<?=$view_data?>" class="button blue">Unlock</a>
	$force = isset($_GET["force"]) ? true : false;
		<a href="?force=true" class="button blue">Unlock</a>
	$force = isset($_GET["force"]) ? $_GET["force"] : false;
	$force = isset($_GET["force"]) ? $_GET["force"] : false;
Fixed code: 		<a href="?force=true<?=$view_data?><? $admin->drawCSRFTokenGET(); ?>" class="button blue">Unlock</a>
	if (!empty($_GET["force"])) {
		$admin->verifyCSRFToken();
		$force = true;
	} else {
		$force = false;
	}
	
		<a href="?force=true<? $admin->drawCSRFTokenGET() ?>" class="button blue">Unlock</a>
	if (!empty($_GET["force"])) {
		$admin->verifyCSRFToken();
		$force = true;
	} else {
		$force = false;
	}
	
	if (!empty($_GET["force"])) {
		$admin->verifyCSRFToken();
		$force = true;
	} else {
		$force = false;
	}