简体   繁体   中英

Permissions to delete spam comments sent in via the Podio Email to item feature

We have an awkward, persisting situation of receiving unsolicited comments into our corporate Podio space via the Email to Item feature. We spam arrives sporadically, we get a couple of hundred of them on some days. Removing the offending user from the Podio workspace does not help. We have of course contacted Podio support, but they are unable to help.

I assume others have, or are vulnerable the same breach. It seems Kirsten Campbell-Morris reported in 2014 the same breach.

Our analysis is that the email notification which Podio sends have been captured, and the unique reply-to addresses are used. According to our analysis (and theory), this is a write-only vulnerability.

In our case the spam items are easy to classify as spam/ham: they all come from one user 𝒰, and always arrive via the Email to Item feature. Other than the spam, we never ever need this feature, and would be happy to get rid of this poorly managed feature altogether.

We have sketched three alternate solutions, here in chronological order of development:

  1. A periodic cleanup program
  2. JavaScript program running against the DOM
  3. A webhook endpoint

See below for description of the others (1. and 2.), but we would prefer to use the latest idea (3.), using webhooks . The idea is to create a either one or separate comment-create hook for all the apps in our workspace. It would receive a HTTP request on comment creation, authenticate with the Podio API, fetch the comment in question, decide whether it is spam or not, and delete it if necessary (like said, deciding what is spam is straightforward in our case).

I implemented this idea as a minimal Lumen API endpoint. On receiving the webhook request with the following JSON payload

{
    "item_id": "yyyyyyyyy",
    "hook_id": "zzzzzzz",
    "type":"comment.create"
}

it is passed to PodioComment::get() for decisionmaking.

The problem is that the delete operation [ PodioComment::delete()](https://developers.podio.com/doc/comments/delete-a-comment-22347) receives a PodioForbiddenError`, though it authenticates with token from user 𝒰.

The PHP stacktrace

 PodioForbiddenError in Podio.php line 319 at Podio::request('DELETE', '/comment/xxxxxxxx', array()) in Podio.php line 358 at Podio::delete('/comment/xxxxxxxx') in PodioComment.php line 46 at PodioComment::delete(xxxxxxxx) in CommentController.php line 116 

What is going on here? Am I not authenticating properly? I can do other tasks, eg get comments and other Podio items, and Podio::setup() and Podio::authenticate_with_app() run succesfully, with the client ID and secret, and app id and token.

Our current theory is that the Email to Item feature is a separate application (with it's own app_id ). If this is correct, how can we authenticate as that app to delete comments from it? If not, what else can we do to delete the spam comments? How can we check which permissions our custom program has for various Podio items?

Details of solutions 1. and 2.

Solution sketch 1. A periodic cleanup program (does not work)

The first one (1.) of these is a PHP program was written with the Podio PHP client and was planned to run as cronjob. The idea was to periodically – say every 6 hours – to authenticate, scan all items for new comments, and delete them if they are deemed spam. This didn't work, because though the program was running on API keys of an administrator user, it didn't have permission to delete comments made by user 𝒰.

Solution sketch 2. JavaScript program running against the DOM (works if manually supported)

This is hack with screenscraping and automatically pressing buttons on the web UI.

We login as the user 𝒰, navigate to their activity stream, open the browser developer tools, copy-paste the following program to the console, and go for coffee. This bypasses authentication issues of (1.) and (3.), but is cumbersome to operate and error-prone.

// Add the user id to remove in here. There is a good chance it is
// a six-digit number
var spamUid = 'xxxxxx';

// Consider only comments made after this date
var spamDate = new Date(2018, 04, 01);

var spamUserUrl = 'https://podio.com/users/' + spamUid;

var mnum = {
    'January': 0,
    'February': 1,
    'March': 2,
    'April': 3,
    'May': 4,
    'June': 5,
    'July': 6,
    'August': 7,
    'September': 8,
    'October': 9,
    'November': 10,
    'December': 11
}

var titleToDate = (title) => {
    re = /(\s*\d*) ([A-Za-z]*) (\d{4}) (\d*):(\d*)/;
    [, D, M, Y, h, m] = re.exec(title);
    d = new Date(Y, mnum[M], D, h, m);
    return d;
}

var throttling = 2000;

var spamComments = jQuery('.comment')
    .filter((i, c) => jQuery(c).find('.comment_byline > a')[0].href == spamUserUrl)
    .filter((i, c) => jQuery(c).find('.timestamp > time')[0].title != "")
    .filter((i, c) => titleToDate(jQuery(c).find('.timestamp > time')[0].title) > spamDate);

console.log("Found " + spamComments.length + " comments to delete");

spamComments.each((i, c) => {
    c.style.border = '5px red dotted';
    setTimeout(() => {
    console.log("deleting 💩", c);
    jQuery(c).find('.js-delete-comment').click();
    jQuery('.confirm-button')[0].click();
    }, i * throttling);
});

Please contact Podio support. We have solution to stop this :)

For the record, we did contact Podio support and this time they were responsive and said the issue has been solved. I have no idea what was done on their end, but we have not received the spam messages since. Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM