CVE-2021-25954: Incorrect Authorization (CWE-863)
value: In “Dolibarr” application, 2.8.1 to 13.0.4 don’t restrict or incorrectly restricts access to a resource from an unauthorized actor. A low privileged attacker can modify the Private Note which only an administrator has rights to do, the affected field is at “/adherents/note.php?id=1” endpoint.
CWE description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
CVSS v3 base score: 4.3
Published: 2021-08-09T17:15Z
Repository: https://github.com/Dolibarr/dolibarr
Language: PHP
Files changed: htdocs/core/actions_setnotes.inc.php
Commit date: 2021-05-09 12:50:46 +0200
Commit message: Fix vulnerabiity: External users can set a public note
Diff: diff --git a/htdocs/core/actions_setnotes.inc.php b/htdocs/core/actions_setnotes.inc.php
index f2426f6523f0..91e7f4a8aca2 100644
--- a/htdocs/core/actions_setnotes.inc.php
+++ b/htdocs/core/actions_setnotes.inc.php
@@ -65,18 +65,20 @@ if ($action == 'setnote_public' && !empty($permissionnote) && !GETPOST('cancel',
 			if ($result < 0) {
 				dol_print_error($db, $result);
 			}
 		}
 	}
-} elseif ($action == 'setnote_private' && !empty($permissionnote) && !GETPOST('cancel', 'alpha')) {
-	// Set public note
-	if (empty($action) || !is_object($object) || empty($id)) {
-		dol_print_error('', 'Include of actions_setnotes.inc.php was done but required variable was not set before');
-	}
-	if (empty($object->id)) {
-		$object->fetch($id); // Fetch may not be already done
-	}
-	$result = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5), '_private');
-	if ($result < 0) {
-		setEventMessages($object->error, $object->errors, 'errors');
+} elseif ($action == 'setnote_private' && !empty($permissionnote) && !GETPOST('cancel', 'alpha')) {	// Set public note
+	if (empty($user->socid)) {
+		// Private notes (always hidden to external users)
+		if (empty($action) || !is_object($object) || empty($id)) {
+			dol_print_error('', 'Include of actions_setnotes.inc.php was done but required variable was not set before');
+		}
+		if (empty($object->id)) {
+			$object->fetch($id); // Fetch may not be already done
+		}
+		$result = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5), '_private');
+		if ($result < 0) {
+			setEventMessages($object->error, $object->errors, 'errors');
+		}
 	}
 }

Vulnerable code: } elseif ($action == 'setnote_private' && !empty($permissionnote) && !GETPOST('cancel', 'alpha')) {
	// Set public note
	if (empty($action) || !is_object($object) || empty($id)) {
		dol_print_error('', 'Include of actions_setnotes.inc.php was done but required variable was not set before');
	}
	if (empty($object->id)) {
		$object->fetch($id); // Fetch may not be already done
	}
	$result = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5), '_private');
	if ($result < 0) {
		setEventMessages($object->error, $object->errors, 'errors');
Fixed code: } elseif ($action == 'setnote_private' && !empty($permissionnote) && !GETPOST('cancel', 'alpha')) {	// Set public note
	if (empty($user->socid)) {
		// Private notes (always hidden to external users)
		if (empty($action) || !is_object($object) || empty($id)) {
			dol_print_error('', 'Include of actions_setnotes.inc.php was done but required variable was not set before');
		}
		if (empty($object->id)) {
			$object->fetch($id); // Fetch may not be already done
		}
		$result = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5), '_private');
		if ($result < 0) {
			setEventMessages($object->error, $object->errors, 'errors');
		}