HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Vanilla 2.0.x - One way spammers manage to post to Activity

businessdadbusinessdad Stealth contributor MVP

We launched our site last month and, as expected, we got a couple of spammers on board. They could not do much "damage", since we require email confirmation and they never confirmed it, but they immediately started posting on their own activity. To stop them, I put together a solution in our main application, as follows:

  • Added a new Garden.Activity.Add permission programmatically (I wanted it to be separated from Profile.edit to have more granularity).
  • Implemented a request filter, so that every request could be inspected and the new permission check be enforced on it.
  • I did not give the permission to post on Activity to anyone, but Administrator (we don't want our members to use it, anyway).

We put the solution in place and, although we saw a reduced amount of spam, we found out that spam activities were still coming in. I reviewed the web server logs, and I found out something unexpected: there are two ways for spammers to post on Activity.

1. ProfileController::Activity()

This method goes through the ProfileController, which does the following (code reformatted to add comments):

public function Activity($UserReference = '', $Username = '', $UserID = '', $Offset = '0') {
  $this->Permission('Garden.Profiles.View');

  // [Rendering stuff...]
  $Comment = $this->Form->GetFormValue('Comment');

  // Check that session is valid
  if ($Session->UserID > 0 && 
    // Check that postback is authenticated
    $this->Form->AuthenticatedPostBack() && 
    // Check that comment is not empty
    !StringIsNullOrEmpty($Comment) && 
   // Check that user has Garden.Profiles.Edit permission. Role "Confirm email" does NOT have it
    CheckPermission('Garden.Profiles.Edit')) {
         // Active user has submitted a valid comment, let's go ahead
         $Comment = substr($Comment, 0, 1000); // Limit to 1000 characters...
    // Further processing

2. ActivityController[::Index()]

This method goes straight to the ActivityController and does a much looser check:

public function Index($RoleID = '', $Offset = FALSE) {
  $this->Permission('Garden.Activity.View');

  // [Rendering stuff...]

  // Comment submission 
  $Session = Gdn::Session();
  $Comment = $this->Form->GetFormValue('Comment');
  $this->CommentData = FALSE;

  // Check that session is valid
  if ($Session->UserID > 0 && 
    // Check that postback is authenticated
    $this->Form->AuthenticatedPostBack() && 
    // Check that comment is not empty
    !StringIsNullOrEmpty($Comment)) {
         // Active user has submitted a valid comment, let's go ahead
         $Comment = substr($Comment, 0, 1000); // Limit to 1000 characters...

The check on Garden.Profiles.Edit is not there in ActivityController, thus practically any logged in user can post to the Activity, unless the Garden.Activity.View is removed from their role. Since it's not intuitive that a "View" permission could grant posting rights, spammers can get through before one can realise what's going on.

Solution

To solve the issue, we extended or request pre-processor to cover ActivityController as well and check that proper permissions are in place, but it would be good to strengthen the validation in the core. I can post this suggestions to Github too, if the team reckons it may be useful.

Comments

  • R_JR_J Ex-Fanboy Munich Admin
    edited January 2014

    I think you should post it to GitHub any way. Even if the team will release a 2.0.18.11 it might not happen very soon and if your proposal is on GitHub, every admin of a Vanilla installation can benefit from your findings immediately.

  • I wish this was a standard option, thank you for posting. I've searched the discussions and i've found little about this topic. Our board in inundated daily with spammers on the activity feed. I've tried all of the different registration methods and it persists (it's still not clear to me why they are able to post).

  • There isn't a plugin to manage this, right? Or even just disable the activity feed?

  • peregrineperegrine MVP
    edited January 2014

    @JamieD said:
    There isn't a plugin to manage this, right? Or even just disable the activity feed?

    This is an aside from businessdad's excellent solution with more granularity. So you could make the changes he suggests or with lesser granularity you can do the following.


    @JamieD

    to digress from businessdad's solution and to provide you an answer to your question.

    if you want applicants and users in confirm role not to spam the activity board.

    for applicant role and confirm email role....

    you can restrict the permissions so they only have

    signin allow. and
    profiles view, and
    discussions view.
    nothing else checked.

    thats all they get and they won't be able to post on activity.

    unfortunately if profile edit is checked - users can share and post on activity wall.

    but if profile edit is not checked they cannot edit their profile (which is unnecessary for confirm email role or applicant (because they are not approved).

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • R_JR_J Ex-Fanboy Munich Admin

    .oO(Sometimes I wish I could click on all reactions at the same time)

  • Thank you, this is invaluable information! What kind of beer? :D

  • you can send the entire beer donation to @businessdad - perhaps guiness :)

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • businessdadbusinessdad Stealth contributor MVP

    @JamieD said:
    Thank you, this is invaluable information! What kind of beer? :D

    Belgian abbey beer, thanks. :)

Sign In or Register to comment.