Implementing "Report this content" and detecting spammer or robot triggered event - robots.txt

I'm creating a forum for a website, and plan on implementing a "Report this content" function.
In all honesty, I'm not sure how useful (lit. necessary) the feature will be, since a user account (created by admin) will be required for posting, but the solution interests me.
So in short, this is the scenario:
For all users, there will be read-only access to all (non-restricted) content on the forum. For unidentified users there will be a reply button and report this content button present. The former will proceed to require a login, while I had planned that the latter wouldn't, so that anyone would be able to flag suspicious or offensive content.
The problem I'm thus facing is basically "robot clicks", or rather how to implement the system so it won't be fooled by "robot clicks".
There are a few methods that come to mind:
1) User-agent
2) Requiring several flags (in a predefined timespan?) before reacting in any way
3) robots.txt
4) Requiring human input on a second form (captcha or "specify reason")
What I think of them:
1) Unreliable (as sole solution)
2) This requires a mass of users which might lead to the event never being triggered
3) This is probably the "right" way to go, but will only work for those who respect it
4) Meh, I hate captcha and requiring a reason might raise the bar too high to keep the function useful
What methods would the (highly enlightened) community have to share with me?

You could append the 'report this' <form> to the DOM with javascript's appendChild();.
This would prevent a lot of spam.
It would also prevent users not running javascript from seeing the report button. But since this is a feature that does not hinder the user-experience, it is probably an acceptable option.
window.onload = function() {
var f = document.createElement('FORM');
f.method = 'post';
f.action = 'report.cgi';
var b = document.createElement('INPUT');
b.type = 'submit';
b.value = 'Report this';
f.appendChild(b);
document.body.appendChild(f);
}
Note:
The rel="nofollow" attribute makes sure search engines do not 'count' the link, they do however follow it (yes, the name suggests differently).
If you want the search engines not to touch a certain file, use robots.txt
Note 2:
Reporting something is an action that 'changes' something on the server. Thus, it should not be a GET request Instead it should be a POST request. In other words: do not use a <a href""> but instead submit a <form> with its method argument set to "post".

You could simply redirect to a form where the user needs to enter a reason for reporting the content. A robot probably would not enter anything here and the form would not be processed if the user didn't enter anything.

You missed making the link a nofollow one, but I'd opt for a combination of requiring human input (reason, details of complainant) to counter robots and requiring a number of flags to stop people just flagging people they disagree with/don't like on the forum.

Related

In Facebook messenger API, how to prevent button postback payload text from being logged to chat window on click?

TLDR; # bottom
I asked the following question in the Facebook bugs section
NOTE: This is more of a platform design suggestion than a bug, as I failed to find a Chat API feedback portal
Currently I'm building a Chat bot that allows the user to track a goal. It will say something like "Did you go for a walk on July 12, 2016 ?" and have Yes/NO buttons below.
Currently in order to pass the intent, the day and the achievement boolean I need to template a string like this "==GOAL== achieved? <<<{goal_achieved}>>>, date tracked [[[{date_tracked}]]]" and use regex to capture the delimited variables. This is prone to parsing error in other cases where the templated strings in the payload are user-input variables i.e. if the '{goal_achieved}' were replaced with the goal variable '>>meditated" then the regex that captures the templated variable could fail.
One could use the postback payload to store a JSON-encoded string but the problem with this is that the payload string gets logged into the user output and JSON strings are a bit ugly and confusing. The challenges I face could be easily remedied if the payload was not logged to the user Instead log the text for the button to help the user confirm the button was clicked.
If that is not possible, is there any other advice for encoding data into button payload ?
The following answer was offered (Mark Wiltse)
Hi Justin,
Unfortunately at this time our payload structure does not support the functionality that you are trying to implement. From my understanding you want to use the Payload to inform your backend if the user accomplished their 'goal' on that specific date. I would suggest that you create your payload response for the button on your end before passing it to us, which is basically the JSON idea that you had initially.
I know this is a bit cumbersome to handle but the payload response passed back is independent of the text that was provided with the messenger thread.
I would suggest that you also attempt to sanitize your strings if you are worried a user has previously provided you would cause an issue with your regex. You should be able to implement this functionality if the prior user data is sanitized to avoid any issues with regex/json parsing.
Since this is an implementation question I will have to close this report as Invalid. If you are still looking for additional insights and concrete tips for implementing this flow please post to our stack overflow where we have Facebook Engineers and a wide range of community members who also contribute.
http://facebook.stackoverflow.com/
Take care and best wishes with your messenger bot.
Mark
This sentence was particularly unclear:
I know this is a bit cumbersome to handle but the payload response
passed back is independent of the text that was provided with the
messenger thread.
TLDR;
Can anyone inform me of how to prevent the button from logging the payload string so that I can use it to pass JSON to my app without the user seeing it ?
Make sure to comment out sendTextMessage() in your receivedPostback() call :
function receivedPostback(event){
sendTextMessage(senderID, event.postback.payload);
}
From my understanding you're saying that when you press a button the PAYLOAD instead of the button's text is showing up.
Are you defining your buttons like this?
{
type: "postback",
title: "View Details",
payload: "details:12345"
}
I'd recommend removing any special characters that would mess with the parsing of your payload. As long as the special characters are not crucial to the user experience this is probably a fine solution.
If this doesn't solve your issue:
Can you add a screenshot showing the button you are pressing, and the log message you are talking about? From my understanding you're saying that when you press a button the PAYLOAD instead of the button's text is showing up. That's not the case for me, my buttons text shows up when I press a button.

Better Honeypot Implementation (Form Anti-Spam)

How do we get rid of these spambots on our site?
Every site falls victim to spambots at some point. How you handle it can effect your customers, and most solutions can discourage some people from filling out your forms.
That's where the honeypot technique comes in. It allows you to ignore spambots without forcing your users to fill out a captcha or jump through other hoops to fill out your form.
This post is purely to help others implement a honeypot trap on their website forms.
Update:
Since implementing the below honeypot on all of my client's websites, we have successfully blocked 99.5% (thousands of submissions) of all our spam. That is without using the techniques mentioned in the "advanced" section, which will be implemented soon.
Concept
By adding a invisible field to your forms that only spambots can see, you can trick them into revealing that they are spambots and not actual end-users.
HTML
<input type="checkbox" name="contact_me_by_fax_only" value="1" style="display:none !important" tabindex="-1" autocomplete="off">
Here we have a simple checkbox that:
Is hidden with CSS.
Has an obscure but obviously fake name.
Has a default value equivalent 0.
Can't be filled by auto-complete
Can't be navigated to via the Tab key. (See tabindex)
Server-Side
On the server side we want to check to see if the value exists and has a value other than 0, and if so handle it appropriately. This includes logging the attempt and all the submitted fields.
In PHP it might look something like this:
$honeypot = FALSE;
if (!empty($_REQUEST['contact_me_by_fax_only']) && (bool) $_REQUEST['contact_me_by_fax_only'] == TRUE) {
$honeypot = TRUE;
log_spambot($_REQUEST);
# treat as spambot
} else {
# process as normal
}
Fallback
This is where the log comes in. In the event that somehow one of your users ends up being marked as spam, your log will help you recover any lost information. It will also allow you to study any bots running on you site, should they be modified in the future to circumvent your honeypot.
Reporting
Many services allow you to report known spambot IPs via an API or by uploading a list. (Such as CloudFlare) Please help make the internet a safer place by reporting all the spambots and spam IPs you find.
Advanced
If you really need to crack down on a more advanced spambot, there are some additional things you can do:
Hide honeypot field purely with JS instead of plain CSS
Use realistic form input names that you don't actually use. (such as "phone" or "website")
Include form validation in honeypot algorithm. (most end-user will only get 1 or 2 fields wrong; spambots will typically get most of the fields wrong)
Use a service like CloudFlare that automatically blocks known spam IPs
Have form timeouts, and prevent instant posting. (forms submitted in under 3 seconds of the page loading are typically spam)
Prevent any IP from posting more than once a second.
For more ideas look here: How to create a "Nuclear" honeypot to catch form spammers
We found that a slight (though simple) variation on the suggestions here made a huge difference in the effectiveness of our contact form honeypot. In short, change the hidden field to a text input, and make the bot think it's a password. Something like this:
<input type="text" name="a_password" style="display:none !important" tabindex="-1" autocomplete="off">
You'll note that this mock-password input keeps to the same basic guidelines as the checkbox example. And yes, a text input (as opposed to an actual password input) seems to work just fine.
This apparently minor change resulted in a drastic drop in spam for us.
One suggestion to really force the no-autocompletion :
change autocomplete="off" by autocomplete="nope" OR autocomplete="false"
Since the given value is not a valid one (values for autocomplete are only on or off), the browser will stop trying to fill the field.
For more details, How to Turn Off Form Autocompletion.
Hope this helps.
SYA :)
If you are using Ruby on Rails, you can try invisible_captcha gem. A solution based on this honeypot technique.
It works pretty well! At least for small/medium sites... I'm using it in production, for years, in several Rails apps with very good results (we hardly receive spam since its implementation in "contact" forms, sign-up, etc).
It also provides some extras (already listed in https://stackoverflow.com/a/36227377/3033649):
time-sensitive submissions
IP based spinner validation
Basic usage
In your form:
<%= form_for(#user) %>
<%= invisible_captcha %>
...
<% end %>
In your controller:
class UsersController < ApplicationController
invisible_captcha only: [:create]
...
end
And you're done! Hope it helps!

GWT RequestFactory: check if members have been set without permission

I am working with GWT / RequestFactory and a set of customer requirements regarding permissions. Let me explain a basic example:
Every user is assigned to a company. Every user should be able to edit company's core data - but only e.g contact information, website etc. Security-relevant ones like BIC/SWIFT, IBAN, Company name and so on can only be changed if the user has a certain permission XY.
So far so good, on the client side I can check the permissions and disable those fields the user is not allowed to edit. But what would be the most elegant way to ensure on the server side that those fields have not been set without permission?
My problem is that I cannot track changes on the server side. Having #PreAuthorize on every setter is not an option too, because it would end in an authorization-massacre in each and every entity.
At the moment I am following a workaround: every field that is secured / depends on a given permission is passed as an argument to the entity-method and is excluded from the proxy. That way, values cannot be set using the proxy and I can check in my server code if the user has permissions. If not, nothing happens. If user has permissions, I set the values manually. But that produces a lot of boilerplate-code and ugly method signatures because the number of values passed to the method could get large.
I hope you understand my issue. I'm looking forward for your opinions and tips. Thank you in advance.
Well, you can receive many answers (different each other), and all of them could be right, so, at the end is your call. Wait for others answers. I am going to give you the approach that I followed (and it worked pretty well). :D.
Under my opinion, the server should do less as possible, so keep the logic for allowing modify each param on the server I think it is not a scalable solution (if your system has 1M users modifying everything at the same time, will your server work fluent?). I prefer let the client do the job (like Roomba :D).
For solving that problem, in our system we implemented an Access Control List solution. You can store in your db, on each user entity, a list with granted permissions. So, when that information arrives to the client (after user's log in, for example), you can get them, and show the fields that he/she is allow to modify.
Something like:
if (canModifyPersonalDetails(user.getAcls(), ...) ) {
//show labels ...
}
if (canModifyBankDetails(user.getAcls(), ...) ) {
//show labels
}
You can not avoid server call for log in, so it is not a big deal send the extra information (think about the ACLs could be simple list of integers 0 means personal details, 1 bank details....).
If you are dealing with very compromised information and you prefer do some stuff on the server, in that case probably I'd set up a security level, when you are persisting/updating your proxy, I'd do something like:
if (isAllowForPersonalDetails(user.getSecurityCode()) {
//update the modified personal details
}
if (isAllowForBankDetails(user.getSecurityCode()) {
//update the modified bank details
}
user.update();
I am a big fan of clear User GUI's, and a very big fan of let the server free as much as possible, so I prefer the first option. But if you have constraints for modifying user entity in db, or you prefer do not modify your views, or any constraint with security, maybe the second option is the best one for you.
Hope that helps!

Google Chrome Inspect Element Issue With Hidden ID's

I am not 100% sure if this is as big an issue has I seem to think it is right now but I think I may of found an issue or at else an hole within the Inspect Element viewer within Chrome.
I was using (I have now changed my settings) hidden ID's to set a number of defaults, one was users levels, another was to make the user active by default.
However when I view these ID's within the inspect Element view and then changed the values, submitting the form would submit the NEW value to the server and not the value I had given it.
For Example:
I had something like the following within my code,
<input type="hidden" name="data[user][level][id]" value="1" id="MyID">
I then changed it within the Inspect view to,
<input type="hidden" name="data[user][level][id]" value="2" id="MyID">
Then I submitted the form and was surprised that the NEW value was submitted, I was always under the inpresion that hidden ID's where not changeable and the browser should only submit the default values held within.
I have now changed this to letting the database default to a basic user and then I can change the users setting has I want to. But in some cases this may not be an option, so I was hoping for an answer or some feedback about how to make this more safe.
Am I just a bit slow, are there better methods (different ones) to passing 'hidden' data from forms to the server?
I was thinking about maybe using JQuery to add the needed hidden fields to the forms once the user had selected / submitted the form, but i am not sure if this is 100% safe or even if its a good idea.
Any ideas / feedback are very welcome.....
Many Thanks,
Glenn.
I had the same problem passing the database data into a modal,the solution i know is to use jquery ajax to get the informations from the database requesting a file,adding them into variables and compare the variables
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$(this).addClass("done");
});
I used this code sample to do it.
Of course there are a few modifications to be done depending on your script
I found a better way of doing this, at lest in CakePHP. The CakePHP framework has inbuilt security calls. These in-built functions when added give you all sorts of stuff but the main reason I used them was to stop this sort of form tampering.
I am not 100% sure how it does this, but it adds a token to all forms and it checks to see if the form being submitted is right? Again not sure how the token works.
But here is the code I used ::
public function beforeFilter() {
$this->Auth->allow('index', 'SystemAccess');
$this->Security->blackHoleCallback = 'blackhole';
}
public function blackhole($type) {
$this->Auth->logout();
$this->Session->setFlash('Sorry a security issue has been detected, please try again or contact us for support.', 'default', array(), 'bad');
$this->redirect($this->Auth->redirect('/'));
}
Now I will add that the call the Auth logout I added to this for extra added security, as the user maybe have logged in on a system and it just not be them that is trying to do things that they should not.
Hope that helps others out!
But this is only a fix for when CakePHP is in use. I would take it that other frameworks would have their options but if your only using basic HTML? or a CMS like Drupal again there might be in built security.
Many Thanks
Glenn.
The only safe and best solution that I found for this issue is to check on the server side whether the user_id sent with the form is the same user_id logged in with or not.
Although using jquery is good idea, but, did not work with my case as am using data: $(this).serialize(),
However here's my code on the server side (Note, am using Laravel 5.4, but am sure it won't matter with your case)
if ($request->user_id != Auth::user()->id)
return json_encode("F**K YOU ! Don't Play Smart -_- !");
else
raw_material_category::create($request->all());
Hope this helped ;)

Strategies for preserving form data ( on tab/browser close )

I have an issue with a task management application where occasionally users close their browsers/tabs and the information which they type goes away because they accidentally close a browser/tab, resulting in the loss of the text which they've entered ( and some can spend half an hour entering in text ).
So I have to provide a solution, I have a couple ideas but wanted input on the best to go with, or if you have a better solution let me hear ya.
Option 1:
On the window.onunload or possibly window.onbeforeunload event invoke a confirm() dialog and first test whether the task logging area has any text in it and is not blank. If it's not blank, invoke window.confirm() and ask whether the user wants to close the tab/window without saving a log.
My concern with option #1 is that it may be user intrusive.
Option 2:
On the same event, don't invoke any confirm() but instead forcefully save the text in the task logging area in a cookie. Then possibly offer a button that tries to restore any saved task information from the cookie on the same page, so hitting that button would make it parse the cookies and retrieve the information.
The window.onbeforeunload event works a little strangely. If you define a handler for it, the browser will display a generic message about losing data by navigating away from the page, with the string you return from the handler function inserted into the middle of the message. See here:
alt text http://img291.imageshack.us/img291/8724/windowonbeforeunload.png
So what we do: when we know something on the page is unsaved, we set:
window.onbeforeunload = function(){
return "[SOME CUSTOM MESSAGE FROM THE APP]";
}
and once the user saves, and we know we don't need to show them the message, we set:
window.onbeforeunload = null;
It is a little intrusive, but it's better than your users losing data accidentally.
If the user is daft enough to navigate away before submitting what they have been doing, then they shouldn't mind an intrusion to ask if they mean to do something that is apparently stupid.
Also, SO uses a confirmation dialog on navigating away, and most (some) users here are pretty smart.
This is the easiest to use, and will probably help the users more.
If someone writes a long piece of text, then closes the browser without submitting it, they might be more pleased to sort the problem there and then rather than finding out the next morning they didn't do it...
I would research AJAX frameworks for the particular web server/languages you are using. AJAX would allow you to save form data as it is typed (for example, this is how Google Docs works).