I need a url obfuscator that a spider should not extract my links like safe_mailto in codeiginitor... is it possible using PHP if so please give an example.
Construct a script tag, that will concatenate the email out of smaller String.fromCharCode calls, maybe with a combination of html entities as #Dominic suggested, you can make it more complex with various approaches. The point is to stop the majority of email grabbers from finding it out.
Would it stop them? Not totally. Spam bots are becoming smarter day after day, and it will take somebody like 5 mins to emulate your algorithm to reconstruct emails out of your output. As mentioned by #ircmaxell: "Security through obscurity is no security at all".
Any good approach?: Yes! Put all emails in a database table, with ids (in case they weren't already stored in such manner), the user will click something like reveal.php?email=1564, that page will display a recaptcha, or any other good captcha, and if valid, it will show them the email.
$link = 'mailto:example#example.com';
$obfuscatedLink = "";
for ($i=0; $i<strlen($link); $i++){
$obfuscatedLink .= "&#" . ord($link[$i]) . ";";
}
As ircmaxell commented, this is a very primitive obfuscation, and really won't deter many spammers.
Related
first of all: I'm not a professional php developer, I'm just able to scramble together a few bits of code to make basic stuff work.
I also don't know how to properly name all that stuff, so let me give you some background:
A client of ours wants to send an email containing a link to a vcard qr-code, that contains contact details of their clients to every client they have (between 100-5000 clients possibly).
They don't want to do this by hand so they asked me for an automation solution.
They have a marketing tool that allows them to send mass emails containing the customers details.
So entering 'Hello %name%' in the emails text will be replaced with each customers name in their respective email.
So I found an api that does what they need, it takes url query strings to generate a vcard qr-code (as png file).
I made a script that takes custom query strings, some of them are being sent to said api, some of them are just being embed on the page, so people can print the qr-code including some extra information they need.
The whole system will be used as a "entry-ticket-system" for an event they are hosting, that being said, no high requirements, those tickets are free, our customer wants to use the v-card qr code so they can scan the "tickets" on entry and verify who was actually there, to target them with marketing campaigns later on.
Now to get to the technical part:
This is the api we are using:
https://qrcode.tec-it.com/en/VCard
The way we are currently using it, is by displaying the qr-code in html (<img src="https://qrcode.tec-it.com/API/QRCode?data=BEGIN%3aVCARD%0d%0aVERSION%3a2.1%0d%0aN%3aJohn+Doe%0d%0aTEL%3bHOME%3bVOICE%3a555-555-5555%0d%0aTEL%3bWORK%3bVOICE%3a666-666-6666%0d%0aEMAIL%3aemail%40example.com%0d%0aORG%3aTEC-IT%0d%0aURL%3ahttps%3a%2f%2fwww.example.com%0d%0aEND%3aVCARD&backcolor=%23ffffff" />) and then entering the url query strings as a variable.
This looks something like this:
$fname = filter_var($_GET['fname'], FILTER_SANITIZE_STRING);
$lname = filter_var($_GET['lname'], FILTER_SANITIZE_STRING);
$email = filter_var($_GET['email'], FILTER_SANITIZE_EMAIL);
$fullname = $fname . ' ' . $lname;
echo '<br><img src="https://qrcode.tec-it.com/API/QRCode?data=BEGIN%3aVCARD%0d%0aVERSION%3a2.1%0d%0aN%3a'.$fullname.'%0d%0aEMAIL%3a'.$email. (...)
Now we come to the problem: The email service our customer is using is only able to fill in basic strings, which we cannot modify. So if a client's email would theoretically contain a '&' sign, it would break up the url by indicating a new url query string. We cannot encode them, nor can we do http push.
We can't properly access the data either, we could only export everyting into a csv, modify them and re-import all of their customers (last solution)
Is there any solution for this, so we can accept basically any character within the url. A friend of mine suggested to use a json in the url, however json just has different characters that would break everything.
Everything else does work fine, it's just the '&' sign I'm currently aware of.
PS: I do know that the php code isn't proper code, very low quality. This is okay, the customer is aware of that, they just wanted the cheapest possible solution so they don't have to do it by hand, they have been informed about possible bugs and the very much existing security flaws.
I hope someone can give me a push in the right direction, how could one possibly handle this?
Thanks in advance and apologies for low quality code and possibly unclear explanations, I'm trying my best.
I know there is hundreds examples of the question I'm about to ask. But none of them was working for me like a wanted.
So, I have a textarea, in which people can add comments/ reviews. But the commenting box keeps getting spammed.
I guess the regular expression might be the most efficient way to keep spammers out, but I stink at Regex.
Is there any other way to keep the spam out?
Edit: the spammers keep posting something like that:
Brianna
Looking for work Lolita Pics it would of been better if she was fucking in front of the mirror!
its more sexy seeing yourself getting f##$.
just getting horny thinking about it
Preteens Nn Models omg if that
(spoilered, lightly censored to avoid causing folks problems at work)
So i want to block per hyperlink in string
There are many different ways to get rid of spam:
Captcha - for example ReCaptcha, but nowadays you can buy about ~1000 rewritten captcha for less than 3$.
Questions in your language about the most known facts - you can ask your users about some facts that they know, but spammers don't.
Antispam filters - for example Sblam!, Akismet or other anti-spam services. I think it would work best for you.
Alot of Captcha is now bot solvable, and if you're trying to avoid Captcha, then one quick suggestion is to use a simple Text trap.
Under your text area, add a question, such as;
"How many days are in a week?"
Then add another text box, and compare this to say;
7 or Seven etc.
If the test fails, then reject the entry...
You may need to vary your question over time, or even have a list of different questions, but this is a simple and easy method to implement.
The answers here are good, but sometimes fooling bots is a good first step.
The vast majority of bots just read the source code and will fill in all the input fields they can find with garbage, send the request, and then hope it worked. They are pretty stupid, so something like this may fool most bots:
<p style="display:none">Screen readers: Use the next textarea (the first is used to confuse spam bots).</p>
<textarea name="comment" style="display:none"></textarea>
<textarea name="real_comment"></textarea>
And then in your script:
if (isset($_POST['comment']) && strlen($_POST['comment']) > 0) {
die('Bots begone!');
}
$comment = $_POST['real_comment'];
In other words, put a dummy textarea in the HTML, hide it using CSS, and then wait for bots to fill it in.
The simpliest way to do what you want is to search for the string http://
The following if-statement allows up to 3 links in $text
if (substr_count($text,"http://") > 3)
But that's not really a sufficent check, because there is a lot of spam, which doesn't contain any links at all - just rubish.
So the second you have to do, is a black list with "bad words"
$lower = strtolower($text);
foreach ($blockword as $word) {
if (strpos($lower, strtolower($word))>0) {
//handle spam here..
}
}
and after all, you have to maintain a growing list with words and still have to delete a lot of spam..
So you have the option to add an invisible field with random values, which are stored in the session and check if this value is submited correctly
$_SESSION["random_secret"] = //create random string..
and later check
if ($_POST["secret"] == $_SESSION["random_secret"])
with this check, you get rid of a lot of automated spam(but still not all)
and so after all you ended up with captchas
A client contacted us worried about some recent attempts to abuse the contact us form on her site.
Apparently, someone tried to write some code in the message field, most likely, it was an attempt to use the back end script for spam email purposes (email injection using those funky headers).
Currently, the security in place is a JavaScript file that validates the form before it is submitted. There isn't really any checking in the back end.
So, I added some validation in the back end, just some simple stuff, like:
$namePattern = '/^[a-z0-9()\/\'":\*+|,.; \- !?&#$#]{2,75}$/i';
$emailPattern = '/^[^#\s]+#([-a-z0-9]+\.)+[a-z]{2,}$/i';
$phonePattern = '[0-9\.\-]';
$array = $_POST;
//This is the first line of defense.
if (!preg_match ($namePattern, $array['c_firstname']){
die ("Please go back and enter a correct first name");
}
...More if statements to check other fields.
//The second line of defense.
function remove($name){
return( str_ireplace(array( "\r", "\n", "%0a", "%0d", "Content-Type:", "bcc:","to:","cc:" ), " Something Replaced ", $name ) );
}
$array['c_date'] = remove ($array['c_date']);
//Check the rest of the array.
Sorry, if there is something wrong with my logic or my syntax, I haven't actually tested the above yet (since the site is live, I wanted to get as much of the code written as possible before testing).
Is the above enough of a security check? Did I get the pattern checks right (I mostly just copied other peoples patterns because I don't totally understand the notation).
This particular mail form uses Zend Mail, so in theory, it's a bit more secure than regular PHP mail, I think.
Also, this isn't that important, but if someone has the time, could you teach me how to cycle through the array and assign a new value to each element (i.e. instead of writing $array['c_date'] = remove ($array['c_date']); several times, a simple function or something that does the job for me.
Thanks a lot for the help, have a good day!
Generally speaking the key is to ensure that anything coming from user input is not executed. Providing your code generating the email is encoding all the user input then there shouldn't be too many problems.
Pattern matching input can't hurt (unless you specifically want users to be able to enter particular values like html code).
Personally, I would re-assure the client that any script/code inserted to their form isn't executed, and isn't harmful unless executed.
Simply properly sanitize your input should be enough. Use htmlspecialchars() or htmlentities(), You can also strip out any < or > characters, that should be enough.
The most frequent problem with mail forms comes from bad code samples lying around on the web in which the destination email is taken from a hidden field in the form, which allows attackers to replace that email and use the server as a spam hub.
Just make sure the email does not come user input. For the rest, the worst that can happen is that you will receive spam, just will just happen anyway if you want people to contact you.
I have comments enabled on my site and I require users to enter at least 30 characters to publish their comments (Just to get some value because they usualy just submitted "I like it")
But some users now use simple technique to overcome this and enter e.g.:
"I like it. asdsdf dfdsfsdf tt erretrt re"
As you can see the rest of the text is nonsense. Is there a way (algorithm) how to filter these comments out in PHP ?
Get a dictionary of English words from the net. Check the post has a certain % (maybe 50%? maybe 70%?) of words that are in the dictionary. You can't look for 100%, or names and technical jargon will not be found.
users will get around this by entering.
I like it ....................................................
So then add logic to parse out punctuation.
Then users will get around it with
I like it. the the the the the the the the
Then you will need to parse it for proper English grammer
Then no one will be able to post on your site becuase it has too many rules.
Better suggestion: Add comment moderation. Dumb posts get downvoted and go away. Good posts stay.
Check out the Akismet PHP5 class.
$WordPressAPIKey = 'KEYHERE';
$MyBlogURL = 'http://www.example.com/blog/';
$akismet = new Akismet($MyBlogURL ,$WordPressAPIKey);
$akismet->setCommentAuthor($name);
$akismet->setCommentAuthorEmail($email);
$akismet->setCommentAuthorURL($url);
$akismet->setCommentContent($comment);
$akismet->setPermalink('http://www.example.com/blog/alex/someurl/');
if($akismet->isCommentSpam()) {}
You can use a naive bayesian filter for this. http://www.paulgraham.com/better.html
There are probably existing libraries for this kind of thing. Check out spam assassin.
I'd do a simple check on consecutive consonants or vowels. If there are more than four of any in a row, than there is a high probability of nonsense. Furthermore, check for more than two repetitions of the same character. When looking at some nonsense text, I'm sure you'll find some pragmatic reciepes ;-)
Personally, I would say there's not much you can do about it. Even if you had a dictionary and parser, what if I were to leave a comment: "I like it. As do I like your car." Depending on what they're leaving a comment for, that could be complete nonsense. Best I can say is have an edit available for each comment so that you or a mod or whomever can edit it. Sorry that this isn't of any help.
I had this same issue when trying to create password restrictions. Words couldn't be used, so we needed to use a dictionary, but there is never a comprehensive dictionary. And the biggest thing was eliminating l33t speak. :)
Unfortunately not, your best bet is to modify something like this: Get Spelling Corrections From Google. When messages are close to the 80 character limit, you could look up each word individually and if it doesn't have a direct hit, boot out the input.
I need to create a 10 page quiz for a mobile browser. It is only a mobile webpage, so no considerations need to be taken for other browsers.
Here's the problem I'm having: I can't use JavaScript, because not every mobile browser supports it. I'm not very skilled in other languages, but I thought perhaps something could be done in PHP as it is server-side.
If my first URL is domain and I enter the correct quiz answer, the URL to the next page could be domain/?p=1. The URL doesn't need to do anything but hold a count of the number of correct results.
As for the actual code, I was thinking it could be included in the HTML itself, as I'm not very concerned about people viewing the source on their mobile phones.
Is it possible to write a line of code that increments the 'p=' attribute in the URL by one when clicked and only attach it to the correct answers?
Here's an image of what I mean: http://i.imgur.com/HbJ5U.jpg
And, what's to stop me from manually incrementing the "correct answer" counter in my address bar?
Do you not want to use a database because you don't have one available to you in your hosting, or because you don't know how?
I'm not a fan of the idea, but you can get the number of "correct answers" with the following code.
<?php
/* Gets current correct answer Count */
$answer_count = $_GET["p"];
/* checks to see if the submitted answer is the same as the correct answer */
if ($_POST["submitted-answer"] == "correct-answer") {
$answer_count++;
}
?>
Now, you just add the modified answer count to the link to the next question.
Next Question
If this is "just for fun" I don't see why you couldn't do it like this. It's definitely a simple way to solve the problem.
The standard way to do this is to store things in hidden form variables. Of course, if there is anything riding on this, that's a terrible way to do it, because it's really easy for the end user to put his own values in those hidden form values.
Aren't file-based sessions the obvious answer here?