We have Ruby script that fetch and parse reply emails from our clients and putting them on appropriate client object in application.
For that purpose we send email to client with specific "hidden" code/id inside 1x1 pixel img tag (in similar way tracking pixel technology works) when clients reply to email, they quote our original email with code/id inside. And when we get client reply we can detect that hidden code from img tag, and process it accordingly. This works fine except when clients are replying from Outlook 2013.
Outlook 2013 removes image data containing code/id, and put something like "Image removed by sender." so we cannot detect see code/id anymore.
Also tried, making a image from base64 and even encoding code/id inside base64 image, but we got same result.
We tried different solutions, like making custom tags with class name contain code/id. Those custom tags are removed too, and replaced with something like < o:p >< /o:p >
We tried to put code/id inside invisible div, in inline css and various css tricks, and in this case Outlook just removes invisibility of div, and code/id is visible in email content.
There is a option that code/id is visible text inside body or subject, but we would like that this code/id be stays invisible to the clients.
It seems like its almost impossible to pass some hidden data trough reply email from MS Outlook.
Is there any way that we can pass this code/id trough reply email from outlook, without outlook removing it or making it visible?
Thank you.
Unless the data is visible (one way or another), chances are Outlook (or rather Word-light used for editing emails) will remove it.
White text on white background would probably work...
<img src=3D"https://t.yesware.com/t/58c8a29bcdf01103c9661815ef20eff8d=
f34a1b3/556ad713ae0cb0b15199a455f1fa5dfd/spacer.gif" style=3D"border:0; wid=
th:0; height:0; overflow:hidden;" width=3D"0" height=3D"0"><img src=3D"http=
://t.yesware.com/t/58c8a29bcdf01103c9661815ef20eff8df34a1b3/556ad713ae0cb0b=
15199a455f1fa5dfd/spacer.gif" style=3D"border:0; width:0; height:0; overflo=
w:hidden;" width=3D"0" height=3D"0">
I will address this dry-snitching code in a bit
Yesware is a paid service that allows you to track when and where the recipient of your email opens that email, every single time that they do or if they forward it to someone else, you will get the IP address and device type of each of those opens as well.
I've used Yesware for years, this is the first time that it has peeked it's little head out. In an email chain involving my Gmail hosted email and someone we will call Quarles. The first email I sent Quarles went normally, I received notification from Yesware that Quarles opened it from an iPhone. No further notifications came from YesWare which is impossible because he has replied twice.
I discovered in the latest email thread, under my second reply, Image removed by sender.Image removed by sender.
Below my third reply, Error! File name not specified.Error! Filename not specified.
I viewed the headers and, damn the luck, Quarles is using Outlook on a Mac Microsoft-MacOutlook/10.c.0.180410
What I am curious about is what Quarles sees on his end. Because the gif is not gone, the code is still there in our thread untouched. I know because if I open the email thread from another device (non-sending device) I get the notification that someone opened the email. So, what is preventing the code from calling home? Is it his MacOutlook? Is it an add-on he's got?
I am seriously considering having my husband write something better than Yesware. He's not a programmer but he is a SysAdmin so he'll figure it out. Besides, the stupid programs he has designed looked like crap anyway so why not write code for something that is supposed to remain unseen.
Oops, gotta go, if he catches me on stackoverflow he's gonna freak.. ;)
I'm sending an HTML mail from my app, this mail contains URLs, is there a way to prevents from mail clients to show these URLs as links?
for example:
<table>
<tbody>
<tr>
<td>http://www.google.com</td>
</tr>
</tbody>
</table>
will generate" http://www.google.com
instead I want it to generate a static text.
any thoughts?
This is a feature of some mail clients and there's no foolproof way to stop them from doing whatever they want with the message contents.
You could try to trick the mail clients by wrapping the addresses in empty tags and hope that they aren't smart enough to see through it:
<td><span>http</span><span>://</span>www.<span>google.</span>com</td>
Use a "zero width space" character:
It does as the name implies. It adds a space in your string but the space takes up zero width so instead of looking like two strings, it looks like one.
I have found the accepted answer doesn't work for Outlook 2013. I have had success with the following:
http<a href='#' style='text-decoration:none; color:#000;'>://www.google.</a>com
Setting the style cursor:default is not honored by Outlook 2013, but if you only make the middle of the url a hyperlink then a user can still select the link text without the cursor pointer appearing.
I'd say that largely depends on the mail client and thus is beyond your control. The only option would be to not make it a URL. E.g. write www.google.com (which the user can copy/paste just like the URL.
I didn't have any luck in preventing MacMail and Yahoo Mail from creating links out of any text string ending in .com (or other domain extension). After hours of testing (even 'href=""' and 'href="#"' did not work), I finally inserted my own URL and then manipulated the CSS and inline styles to remove the mail clients' link styling.
Adding in hidden line break elements in the right places seems to have fixed this for me (for now) in almost all clients, including desktop Outlook, according to Litmus's tests (Apple Mail desktop looks like the main exception).
https:<br style="display: none;"/>//www.w3<br style="display: none;"/>.org/TR/2020/WD-WCAG22-20200227/
tl;dr
Hide email address from bots without using scripts and maintain mailto: functionality. Method must also support screen-readers.
Summary
Email obfuscation without using scripts or contact forms
Email address needs to be completely visible to human viewers and maintain mailto: functionality
Email Address must not be in image form.
Email address must be "completely" hidden from spam-crawlers and spam-bots and any other harvester type
Desired Effect:
No scripts, please. There are no scripts used in the project and I'd like to keep it that way.
Email address is either displayed on the page or can be easily displayed after some sort of user interaction, like opening a modal.
The user can click on on the email address which in turn would trigger the mailto: functionality.
Clicking the email will open the user's email application.
In other words, mailto: functionality must work.
The email address in not visible or not identified as an email address to bots (This includes the page source)
I don't have an inbox that's full of spam
What does NOT Work
Adding a contact form - or anything similar - instead of the email address
I hate contact forms. I rarely fill up a contact form. If there's no email address, I look for a phone number, and if that's not there, I start looking for an alternative service. I would only fill up a contact form if I absolutely have to.
Replacing the address with an image of the address
This creates a HUGE disadvantage to someone using a screenreader (please remember the visually impaired in your future projects)
It also removes the mailto: functionality unless you make the image clickable and then add the mailto: functionality as the href for the link, but that defeats the purpose and now the email is visible to bots.
What might work:
Clever usage of pseudo-elements in CSS
Solutions that make use of base64 encoding
Breaking up the email address and spreading the parts across the document then putting them back together in a modal when the user clicks a button (This will probably involve multiple CSS classes and the usage of anchor tags)
Alterting html attributes via CSS
#MortezaAsadi gracefully brought up the possibility in the comments below. This is the link to the full - The article is from 2012:
What if We Could Use CSS to Alter HTML Attributes?
Other creative solutions that are beyond my scope of knowledge.
Similar Questions / Fixes
JavaScript: Protect your email address by Joe Maller
(This a great fix suggested by Joe Maller, it works well but it's script based. Here's what it looks like;
<SCRIPT TYPE="text/javascript">
emailE = 'example.com'
emailE = ('yourname' + '#' + emailE)
document.write('' + emailE + '')
</script>
<NOSCRIPT>
Email address protected by JavaScript
</NOSCRIPT>
Looking for a PHP only email address obfuscator function
(A Clever solution using both PHP and CSS to first reverse the email using PHP then reverse it back with CSS) A very promising solution that Works great! But it's too easy to solve.
Is it worth obfuscating email addresses on the web these days?
(JavaScript fix)
Best way to obfuscate an e-mail address on a website?
The selected answer works. It actually works really well. It involves encoding the email as html entities. Can it be improved?
Here's what it looks like;
<A HREF="mailto:
yourname#domain.com">
yourname#domain.com
</A>
Does e-mail address obfuscation actually work?
(The selected answer to this SuperUser question is great and it presents a study of the amount of spam received by using different obfuscation methods.
It seems that manipulating the email address with CSS to make it rtl does work. This is the same method used in the first question I linked to in this section.
I am uncertain what effects adding mailto: functionality to the fix would have on the results.
There are also many other questions on SO which all have similar answers. I have not found anything that fits my desired effect
The Question:
Would it be possible to increase the efficiency (ie as little spam as possible) of the email obfuscation methods above by combining two or more of the fixes (or even adding new fixes) while:
A- Maintaining mailto: functionality; and
B- Supporting screen-readers
Many of the answers and comments below pose a very good question while indicating the impossibility of doing this without some sort of js
The question that's asked/implied is:
Why not use js?
The answer is that I am allergic to js
Joking aside though,
The three main reasons I asked this question are:
Contact forms are becoming more and more accepted as a replacement
for providing an email address - which they should not.
If it can be done without scripting then it should be done without
scripting.
Curiosity: (as I am in fact using one of the js fixes currently) I wanted to see if discussing the matter would lead to a better way of doing it.
The issue with your request is specifically the "Supporting screen-readers", as by definition screen readers are a "bot" of some sort. If a screen-reader needs to be able to interpret the email address, then a page-crawler would be able to interpret it as well.
Also, the point of the mailto attribute is to be the standard of how to do email addresses on the web. Asking if there is a second way to do that is sort of asking if there is a second standard.
Doing it through scripts will still have the same issue as once the page is loaded, the script would have been run and the email address rendered in the DOM (unless you populate the email address on click or something). Either way, screen readers will still have issues with this since it's not already loaded.
Honestly, just get an email service with a half decent spam filter and specify a default subject line that is easy for you to sort in your inbox.
Email me
What you're asking for is if the standard has two ways to do something, one for bots and the other for non-bots. The answer is it doesn't, and you have to just fight the bots as best you can.
Defeating email bots is a tough one. You may want to check out the Email Address Harvesting countermeasures section on Wikipedia.
My back-story is that I've written a search bot. It crawled 105,000+ URLs during it's initial run many years ago. From what I've learned from doing that is that web crawling bots literally see EVERYTHING that is text, which appears on a web page. Bots read everything except images.
Spam can't be easily stopped via code for these reasons:
CSS & JS are irrelevant when using the mailto: tag. Bots specifically look at HTML pages for that "mailto:" keyword. Everything from that colon to the next single quote or double quote (whichever comes first) is seen as an email address. HTML entity email addresses - like the example above - can be quickly translated using a reverse ASCII method/function. Running the JavaScript code snippet above, quickly turns the string which starts with: your... into... yourname#example.com. (My search bot threw away hrefs with mailto:email addresses, as I wanted URLs for web pages & not email addresses.)
If a page crashes a bot, the bot author will tune the bot to fix the crash with that page in mind, so that the bot won't crash at that page again in the future. Thus making their bot smarter.
Bot authors can write bots, which generate all known variations of email addresses... without crawling pages & never using any starter email addresses. While it may not be feasible to do that, it's not inconceivable with today's high-core count CPUs (which are hyper-threaded & run at 4+ GHz), plus the availability of using distributed cloud-based computing & even super computers. It's conceivable that someone can now create a bot-farm to spam everyone, without knowing anyone's email address. 20 years ago, that would have been incomprehensible.
Free email providers have had a history of selling their free user accounts to their advertisers. In the past, simply signing up for a free email account automatically guaranteed them a green light to start delivering spam to that email address... without ever using that email address online. I've seen that happen multiple times, with famous company names. (I won't mention any names.)
The mailto: keyword is part of this IETF RFC, where browsers are built to automatically launch the default email clients, from links with that keyword in them. JavaScript has to be used to interrupt that application launching process, when it happens.
I don't think it's possible to stop 100% of spam while using traditional email servers, without using filters on the email server and possibly using images.
There is one alternative... You can also build a chat-like email client, which runs internally on a website. It would be like Facebook's chat client. It's "kind of like email", but not really email. It's simply 1-to-1 instant messaging with an archiving feature... that auto-loads upon login. Since it has document attachment + link features, it works kind of like email... but without the spam. As long as you don't build an externally accessible API, then it's a closed system where people can't send spam into it.
If you're planning to stick with strictly traditional email, then your best bet may be to run something like Apache's SpamAssassin on a company's email server.
You can also try combining multiple strategies as you've listed above, to make it harder for email harvesters to glean email addresses from your web pages. They won't stop 100% of the spam, 100% of the time... while also allowing 100% of the screen readers to work for blind visitors.
You've created a really good starting look at what's wrong with traditional email! Kudos to you for that!
A good screen reader is JAWS from Freedom Scientific. I've used that before to listen to how my webpages are read by blind users. (If you hear a male voice reading both actions [like clicking on a link] & text, try changing 1 voice to female so that 1 voice reads actions & another reads text. That makes it easier to hear how the web page is read for the visually impared.)
Good luck with your Email Address Harvesting countermeasure endeavours!
Here is an approach that does make use of JavaScript, but with a rather small foot-print. It's also very "ghetto", and generally I would not recommend an approach with inline JS in the HTML except you have an extreme reluctance to use JS, at all.
<a
href="#"
data-contact="bGUtZW1haWxAdGhlLWRvbWFpbi5jb20="
data-subj="QW4gQW1hemluZyBTdWJqZWN0"
onfocus="this.href = 'mailto:' + atob(this.dataset.contact) + '?subject=' + atob(this.dataset.subj || '')"
>
Send an email
</a>
data-contact is the base64 encoded email address. And, data-subj is an optional base64 encoded subject.
The main challenge with doing this without JS is that CSS can't alter HTML attributes. (The article you linked is a "pie-in-the-sky" musing and does not have any bearing on what is possible today or in the near future.)
The HTML entities approach you mentioned, or some variation of it, is likely the simplest option that will have some efficacy. Additionally, the iframe approach is clever and the server redirect approach is pretty awesome. But, all three are vulnerable to bots:
The HTML entities just need to be converted (and detecting that is simple)
The document referenced by the iframe might simply be followed
The server redirect might simply be followed, as well
With the approach outlined above, the use of a base64 encoded email address in a data-contact attribute is very "one-off" – as long as the scraper is not specifically designed for your site, it should work.
Simple + Lot of # + Editable without tools
<a href="mailto:user#domain##com"
onmouseover="this.href=this.href.replace('##','.')">
Send email
</a>
Have you considered using google's recaptcha mailhide?
https://www.google.com/recaptcha/admin#mailhide
The idea is that when a user clicks the checkbox (see nocaptcha below), the full e-mail address is displayed.
While recaptcha is traditionally not only hard for screen readers but also humans as well, with the roleout of google's nocaptcha recaptcha which you can read about
here as they relate to accessibility tests. It appears to show promise with to screen readers as it renders as a traditional checkbox from their view.
Example #1 - Not secure but for easy illustration of the idea
Here is some code as an example without using mailhide but implementing something using recaptcha yourself: https://jsfiddle.net/43fad8pf/36/
<div class="container">
<div id="recaptcha"></div>
</div>
<div id="email">
Verify captcha to get e-mail
</div>
function createRecaptcha() {
grecaptcha.render("recaptcha", {sitekey: "6LcgSAMTAAAAACc2C7rc6HB9ZmEX4SyB0bbAJvTG", theme: "light", callback: showEmail});
}
createRecaptcha();
function showEmail() {
// ideally you would do server side verification of the captcha and then the server would return the e-mail
document.getElementById("email").innerHTML = "email#example.com";
}
Note: In my example I have the e-mail in a JavaScript function. Ideally you would have the recaptcha validated on the server end, and return the e-mail, otherwise the bot can simply get it in the code.
Example #2 - Server side validation and returning of e-mail
If we use an example more like this, we get additional security: https://designracy.com/recaptcha-using-ajax-php-and-jquery/
function showEmail() {
/* Check if the captcha is complete */
if ($("#g-recaptcha-response").val()) {
$.ajax({
type: ‘POST’,
url: "verify.php", // The file we’re making the request to
dataType: ‘html’,
async: true,
data: {
captchaResponse: $("#g-recaptcha-response").val() // The generated response from the widget sent as a POST parameter
},
success: function (data) {
alert("everything looks ok. Here is where we would take 'data' which contains the e-mail and put it somewhere in the document");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("You’re a bot");
}
});
} else {
alert("Please fill the captcha!");
}
});
Where verify.php is:
$captcha = filter_input(INPUT_POST, ‘captchaResponse’); // get the captchaResponse parameter sent from our ajax
/* Check if captcha is filled */
if (!$captcha) {
http_response_code(401); // Return error code if there is no captcha
}
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=YOUR-SECRET-KEY-HERE&response=" . $captcha);
if ($response . success == false) {
echo ‘SPAM’;
http_response_code(401); // It’s SPAM! RETURN SOME KIND OF ERROR
} else {
// Everything is ok, should output this in json or something better, but this is an example
echo 'email#example.com';
}
People who write scrapers want to make their scrapers as efficient as possible. Therefore, they won't download styles, scripts, and other external resources. There's no method that I know of to set a mailto link using CSS. In addition, you specifically said you didn't want to set the link using Javascript.
If you think about what other types of resources there are, there's also external documents (i.e. HTML documents using iframes). Almost no scrapers would bother downloading the contents of iframes. Therefore, you can simply do:
index.html:
<iframe src="frame.html" style="height: 1em; width: 100%; border: 0;"></iframe>
frame.html:
My email is me#example.com
To human users, the iframe looks just like normal text. Iframes are inline and transparent by default, so we just need set its border and dimensions. You can't make the size of the iframe match its content's size without using Javascript, so the best we can do is giving it predefined dimensions.
First, I don't think doing anything with CSS will work. All bots (except Google's crawler) simply ignore all styling on websites. Any solution has to work with JS or server-side.
A server-side solution could be making an <a> that links to a new tab, which simply redirects to the desired mailto:
That's all my ideas for now. Hope it helps.
Short answer to fulfill all your requirements is that it's impossible
Some of the script-based options answered here may work for certain bots, but you wanted no-script, so, no, you can't.
based on the code of MaanooAk, here is my version:
<a href="mailto: Mike Myers"
onclick="this.href=this.href.replace(' Mike ','MikeMy'); this.href=this.href.replace('Myers','ers#vwx.yz')">✉ Send Email</a>
The difference to MaanookAks version is, that on hover you don't see mailto: and a broken email adress but mailto: and the name of contact. And when you click on it, the name is replaced by the email adress.
In the code the email adress is splitted into two parts. Nowhere in the code the email adress is visible complete.
Here is my new solution for this. I first build the email adress string by addition of small pieces and then use this string also as title:
adress = 'mailt' + 'o:MikeM' + 'yers#v' + 'wx.yz';
document.getElementsByClassName('Email')[0].title = adress;
function mail(){window.location.href = adress;}
<a class='Email' onclick='mail()'>✉ Send Email</a>
I use this in a footer of a website. Many pages with all the same footer.
PHP solution
function printEmail($email){
$email = ''.$email.'';
$a = str_split($email);
return "<script>document.write('".implode("'+'",$a)."');</script>";
}
Use
echo printEmail('test#example.com');
Result
<script>document.write('<'+'a'+' '+'h'+'r'+'e'+'f'+'='+'"'+'m'+'a'+'i'+'l'+'t'+'o'+':'+'t'+'e'+'s'+'t'+'#'+'g'+'m'+'a'+'i'+'l'+'.'+'c'+'o'+'m'+'"'+'>'+'t'+'e'+'s'+'t'+'#'+'g'+'m'+'a'+'i'+'l'+'.'+'c'+'o'+'m'+'<'+'/'+'a'+'>');</script>
P.S. Requirement: user must have JavaScript enabled
The one method I found effective is using it with CSS like below:
<a href="mailto:myemail#ignore-domain.com">myemail#<span style="display:none;">ignore-</span>example.com
and then write a JavaScript to remove the ignoreme- word from the href="mailto:..." attribute with regex. This will hide email from bot as it will append ignore- word before real domain and this will work on screen reader and when user clicks on the link custom JS function will remove the ignore- word from href attribute so it will open the real email.
This method has been working very effectively for me till date. you can read more on this - http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/
I need to hide a 30 character string inside the HTML of an e-mail so when a user replies, their reply can be linked on our server to that 30 character string. We don't want to add the string to the subject or body of the e-mail where it's visible to the user. We also don't want to hide the text which would result in accidental selecting of the 30 character string.
The problem:
Many e-mail clients (like gmail) reduce HTML e-mail content to just the basic tags, making it difficult to find a tag that can hold an arbitrary string. This means we can't create an arbitrary tag, only use standard tags.
Our best solution:
Hide the string in the "title" tag of a table in the e-mail, like this -
<table title="30_character_string">
The solution above works in most cases. Most e-mail clients don't strip out the title tag, making it a viable option.
Why we're stuck: This isn't the best solution because sometimes e-mail clients get very restrictive and eliminate even the title attribute.
Can you help? What is the most successful way to hide an arbitrary string in the body of an HTML e-mail? Is there a better solution for this sort of linking?
If you put the value in markup, plain text replies won't work. Consider a "smallprint" section on the bottom of your email below your signature.
Dear User,
Email content
Regards,
Logo and such
ReplyIdentifer-xxxxxxxx.
If you don't care for that, add a div to the bottom of the email (again below the sig). ANd again, it will be on the bottom of the email where the user will rarely even care to look.
<style>.hide{display:none;}</style>
<div style="display:none" class="hide">ReplyIdentifer-xxxxxxxx.</div>
In this case, you only see it if the email client removes css AND style tags.
Checking some HTML emails I've received & Gmail seems to allow a <head> tag within the e-mail HTML. You could include the info in a <meta> tag within the head of the email.
What type of account are you reading mail in to? If it's also Gmail, you could make use of their ability to allow abritary strings in your emails address after a plus symbol. Override the reply-to header that you set on your out-going mail to youraddress+uniqueID#gmail.com
EDIT: Staying along the lines of e-mail headers though (which feels like it should be the right way to do this), if you make sure to generate a unique Message ID header for each copy of the mail going out, the In-Reply-To header that you get back should be unique to that recipient and that message. Gmail respects the Message ID header & provides the appropriate reply header in response, as should most (all?) mainstream clients/services
I'm trying to use an html email signature that pulls the html from another site. So, imagine I have the html hosted at blahblah.com/blah.html, and blah.html is:
<html>
<body>
Jon Jones
jon#blahblah.com
</body>
</html
And then my html signature would be something like <embed src="blahblah.com/blah.html/> that way I can manipulate the signature without having to constantly change the actual signature in Outlook (which I use to check my email).
I can't figure out any html that will do what I'm trying to do. The embed tag that I posted above doesn't do the trick. What simple line of html can I use to say "display what you find at blahblah.com/blah.html"
I would venture a guess and say this isn't the best way to do this.
From a security standpoint, I wouldn't want to be viewing any email sent by you that also brings in somesite.com/signature.htm. Even if it did, it would invoke a "click to view linked elements in this email" banner, and hide it until I did so (but chances are I'm not clicking).
From a recipient stand point, some spam filters block emails with externally-linked content (your intended recipient may not even get your email, or (best-case) see it with [spam] in the subject line.)
If you want an easy up-keep, you could place the signature in your my documents/some other folder and link to it via outlook's settings, but that about the least intense method (while also not causing concerns or issues to anyone viewing your email.)
It looks like instructions for what you want are here: http://www.emailaddressmanager.com/tips/html-email.html
Under "How to add HTML links in Outlook HTML emails," point to blahblah.com/blah.html
On the other hand, HTML in emails is generally not a great thing because it often isn't very secure (you could send me a page with HTML that would load a virus), so many clients won't be able to recieve it or will flag it as spam.