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);
}
*/
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);
} 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;
}
$reply = Reply::pkeyGet(array('notice_id' => $this->id,
'profile_id' => $profile->id));
-
+
if (!$reply instanceof Reply) {
return false;
}
$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);
+ }
}