Check scope, else a privacy leaks happens this way:
authorRoland Haeder <roland@mxchange.org>
Fri, 27 Mar 2015 20:55:45 +0000 (21:55 +0100)
committerRoland Haeder <roland@mxchange.org>
Fri, 27 Mar 2015 20:55:45 +0000 (21:55 +0100)
1) Bob and Alice follow each other and write private notices
   (this->scope=2) to each other.
2) Bob uses tags in his private notice to alice (which she can
   read from him).
3) Alice adds that notice (with tags) to her favorites
   ("faving") it.
4) The tags from Bob's private notice becomes visible in Alice's
   profile.

This has the simple background that the scope is not being
re-checked. This has to be done here at this point because given
above scenario is a privacy leak as the tags may be *really*
private (nobody else shall see them) such as initmate words or
very political words.

Signed-off-by: Roland Haeder <roland@mxchange.org>
classes/Notice.php
lib/activity.php
plugins/Favorite/classes/Fave.php

index 8dc5479b4956b8698f91ec77277c45c49d2fa28d..e04bdbabe65ca08c246cd49a41d6a909702b79dd 100644 (file)
@@ -542,8 +542,7 @@ class Notice extends Managed_DataObject
                 throw new ClientException(_('You cannot repeat your own notice.'));
             }
 
-            if ($repeat->scope != Notice::SITE_SCOPE &&
-                $repeat->scope != Notice::PUBLIC_SCOPE) {
+            if ($repeat->isPrivateScope()) {
                 // TRANS: Client error displayed when trying to repeat a non-public notice.
                 throw new ClientException(_('Cannot repeat a private notice.'), 403);
             }
@@ -2504,6 +2503,38 @@ class Notice extends Managed_DataObject
      */
     public function getTags()
     {
+        // Check default scope (non-private notices)
+        $inScope = (!$this->isPrivateScope());
+
+        // Get current user
+        $user = common_current_user();
+
+        // Is the general scope check okay and the user in logged in?
+        if (($inScope === TRUE) && ($user instanceof User)) {
+            // Get profile from it
+            $profile = $user->getProfile();
+
+            /*
+             * Check scope, else a privacy leaks happens this way:
+             *
+             * 1) Bob and Alice follow each other and write private notices
+             *    (this->scope=2) to each other.
+             * 2) Bob uses tags in his private notice to alice (which she can
+             *    read from him).
+             * 3) Alice adds that notice (with tags) to her favorites
+             *    ("faving") it.
+             * 4) The tags from Bob's private notice becomes visible in Alice's
+             *    profile.
+             *
+             * This has the simple background that the scope is not being
+             * re-checked. This has to be done here at this point because given
+             * above scenario is a privacy leak as the tags may be *really*
+             * private (nobody else shall see them) such as initmate words or
+             * very political words.
+             */
+            $inScope = $this->inScope($profile);
+        }
+
         $tags = array();
 
         $keypart = sprintf('notice:tags:%d', $this->id);
@@ -2515,7 +2546,9 @@ class Notice extends Managed_DataObject
         } else {
             $tag = new Notice_tag();
             $tag->notice_id = $this->id;
-            if ($tag->find()) {
+
+            // Check scope for privacy-leak protection (see some lines above why)
+            if (($inScope === TRUE) && ($tag->find())) {
                 while ($tag->fetch()) {
                     $tags[] = $tag->tag;
                 }
@@ -2720,7 +2753,7 @@ class Notice extends Managed_DataObject
 
                 $reply = Reply::pkeyGet(array('notice_id' => $this->id,
                                              'profile_id' => $profile->id));
-                                                                                
+
                 if (!$reply instanceof Reply) {
                     return false;
                 }
@@ -2973,4 +3006,15 @@ class Notice extends Managed_DataObject
             $notice->_setRepeats($repeats);
         }
     }
+
+    /**
+     * Checks whether this notice is in "private scope" (non-public notice)
+     *
+     * @return $isPrivate Whether this notice is private
+     */
+    public function isPrivateScope ()
+    {
+        return ($this->scope != Notice::SITE_SCOPE &&
+                $this->scope != Notice::PUBLIC_SCOPE);
+    }
 }
index 2d3930df0d85ec46207e6ff63fa9790556f3f664..6b3ccf3519dd496b98b95dafe6107eeea1772bb5 100644 (file)
@@ -107,6 +107,7 @@ class Activity
     public $selfLink; // <link rel='self' type='application/atom+xml'>
     public $editLink; // <link rel='edit' type='application/atom+xml'>
     public $generator; // ActivityObject representing the generating application
+
     /**
      * Turns a regular old Atom <entry> into a magical activity
      *
index 68c36dfaef5b6710ccbf2771f3aa612a498aba5c..f6c64dac0e9529f69d8111f7599d597a130bb39e 100644 (file)
@@ -224,7 +224,7 @@ class Fave extends Managed_DataObject
      *
      * @return array Array of Fave objects
      */
-    static public function byNotice($notice)
+    static public function byNotice(Notice $notice)
     {
         if (!isset(self::$_faves[$notice->id])) {
             self::fillFaves(array($notice->id));