Gmail strips body out of mailto links - email

I've been seeing this issue on a website I support, and have confirmed it is the case elsewhere as well.
When using a mailto link for sharing a URL, I see that some clients are fine with displaying the body field from the mailto link in the email, while Gmail strips it out.
I've seen a few related questions here but none suggesting a fix or workaround.
I've also seen some mention that the body field is non-standard, but it seems that it is required that it be honored in the spec.
https://www.rfc-editor.org/rfc/rfc6068#page-7
The creator of a 'mailto' URI cannot expect the resolver of a URI
to understand more than the "subject" header field and "body".
Clients that resolve 'mailto' URIs into mail messages MUST be able
to correctly create [RFC5322]-compliant mail messages using the
"subject" header field and "body".
Is Gmail therefore non-compliant?
To demonstrate the behavior I am seeing, with Gmail as your default email client, paste the following into your browser url bar: mailto:?subject=qux&body=xyzzy
If your experience is consistent with mine, you will not have a body in the Gmail message, and will only have a subject. Upon inspection, you may see that the url bar for the Gmail webapp reads something like the following: https://mail.google.com/mail/u/0/?view=cm&fs=1&tf=1&source=mailto&su=qux, with su representing the subject field from the original mailto url, and sure enough, no field representing body.
Now, changing your default email client (I tried with the Mail macOS application) you will see both subject and body populated.
Has anyone had any luck getting the specified behavior working in Gmail?

Gmail omits all query string parameters after the first one separated by an unencoded ampersand. So if you put ?subject first, you get only subject; if you put ?body first, you get only the body. I changed this:
<a href="mailto:?body=https%3A%2F%2Fexample.com&subject=Testing">
to this, with the ampersand encoded as %26:
<a href="mailto:?body=https%3A%2F%2Fexample.com%26subject=Testing">
...and it works in Gmail, but Mail.app gets the entire query string as the email body. But as I said, Gmail omits everything after the first unencoded ampersand. So I repeated both body and subject with unencoded ampersands, and this seems to work everywhere:
<a href="mailto:?body=https%3A%2F%2Fexample.com%26subject=Testing&body=https%3A%2F%2Fexample.com&subject=Testing">
Put more clearly, in JavaScript, if bodyText is your URL encoded body text, and subjectText is your URL-encoded subject line, then the format you need for full compatibility with Gmail and others is this:
const emailUrl = `mailto:?body=${bodyText}%26subject=${subjectText}&body=${bodyText}&subject=${subjectText}`;
Here also is a Twig version. This Twig file gets unencoded url and title variables for the body and subject respectively:
{% set body %}body={{ url|escape('url') }}{% endset %}
{% set subject %}subject={{ title|escape('url') }}{% endset %}
{% set query_string %}?{{ body }}%26{{ subject }}&{{ body }}&{{ subject }}{% endset %}
<a class="share__button" href="mailto:{{ query_string }}"><span>{{ 'Email this article'|t }}</span></a>

Related

Render HTML string in Azure Communication Services Hero chat application

I am trying to render html string into the chat application based on Azure Communication Services. The boilerplate code is taken from Azure Samples GitHub repo https://github.com/Azure-Samples/communication-services-web-chat-hero.
I have the string in format:
"str1</br>str2</br>str3</br>".
What I want is I want to render this string as html in ChatArea component of the app so that it looks like
str1
str2
str3
I have also set SendMessageOptions.type to 'html' in sendMessageHelper method in sideEffects.ts file but still getting the output as string only. Only difference is now I am getting sanitized string without / in br tags.
Any help would be greatly appreciated.
Thanks so much in advance.
By default this sample trivially assume messages are one-line strings and react doesn't automatically handle \n characters or <br />.
To do multiline, inside ChatThread where the messages are rendered, you will want to ensure the appropriate JSX is generated:
To support multiline where lines are seperated by \n you will need to update
{renderHyperlink(message.content.message)}
to something like:
{message.content.message.split(/\n/g).map((line: string) => <p>{renderHyperlink(line)}</p>)}
More information and other solutions can be found here: How to add a <br> tag in reactjs between two strings?
To support rendering any arbitrary HTML from messages you will need to adapt this line to load the message string as html. However using arbitrarily sent html can be dangerous in an application, a malicious user could embed malicious scripts html or scripts, so avoid doing this. For more information search up Cross-Site Scripting attacks: https://owasp.org/www-community/attacks/xss/.

Where to set Content Language for email?

Sending HTML emails in different languages, such as English and French.
Is it a best practice to set the Content-Language header in the
HTML lang tag: <html lang="fr">
Email header Content-Language
Both
This works:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" />
TL;DR: You can set the Content-Language in the header. If your mail is a multipart message with alternatives in other languages (e.g. when you send a mail with translations), you can set a different one in the headers for those alternatives.
There are two RFC's of interest here RFC 3282 about Content-Language headers and RFC 2045 about message bodies.
From 2045 section 9
Additional MIME Header Fields
Future documents may elect to define additional MIME header fields
for various purposes. Any new header field that further describes
the content of a message should begin with the string "Content-" to
allow such fields which appear in a message header to be
distinguished from ordinary RFC 822 message header fields.
MIME-extension-field := <Any RFC 822 header field which
begins with the string
"Content-">
And from 2045 section 3 you can conclude that an extra Content-Language header can be set on every body part for multipart messages.
If you like seeing examples, the Mozilla comm-central repo (Thunderbird and other MUA's) has some nice test data with examples: https://hg.mozilla.org/comm-central/file/tip/mailnews/test/data
If you are reading this in the future, you may be able to convey the language in the character set RFC 2231.

Simple forms post field specific field values

I am using simpleforms as a subscription form for subscribing to classes. The form uses a use_as and also sends the email to the sender as a confirmation.
I have edited the email twig template and added further informatie about what the subscriber should do next.
My question is if it is possible to set a specific field value in the instruction text. So far I have not yet been able to do this correctly. I would like to only show the field "name:" in this instruction text so that every sender that gets this email is greeted with his own name.
The for loop that is used in the email template is
{% for value in form %} {{ value }} {% endfor %}
And i'm looking for a specific field to be set instead of all the values of the form.
You can directly access the fields in your emailtemplate, you don't need to use a loop for it.
So if you have a field called 'name' in your config file you can use {{ form.name }} in the email template to display the value that the visitor has entered directly.

XSS- Cross-Site Scripting: DOM issue

Fortify scan caught this below error as critical. can some please help ?
switchcontent.loadpage=function(page_request, header){
var innercontent=document.getElementById(header.id.replace("-title", "")) //Reference content container for this header
innercontent.innerHTML=switchcontent_ajax_msg //Display "fetching page message"
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)){
innercontent.innerHTML=page_request.responseText
header.ajaxstatus="loaded"
}
}
what change would be needed to fix this code for avoiding XSS ? Any help is greatly appreciated. thank you.
In the responseText are HTML tags inserted or is it just text you want to insert/change? s a rule of thumb always sanitize/encode all user input and output that is generated from user input. If it's only text that you're inserting use document.createTextNode (example) and append the text to the element's needed (always encoded also), I would recomend using jQuery .text() as with pure javascript it's kind of cumbersome. If it's HTML that is needed to be inserted be sure it's not user input as this is a vulnerability. If the text needs to be from a user use a whitelist to check that the user is only writing tags that you are expecting for example <p></p>.
Fortify treats this as a vulnerability because if a user sends in the responseText <script>alert('XSS')</script> the page will render this as HTML and the script will be executed if you encode this it would just appear as text and not be executed, not only scripts can be executed but HTML will be rendered also and deform your page. You can read more in: OWASP DOM Prevention Sheet
Points:
1: ALWAYS ENCODE USER INPUT!
2: If it's just text create text nodes and append them to the element to make this easier use jQuery if possible function .text() not .html() as the .htlm() function will render the HTML.
3: If it's user generated HTML sanitize malicious tags agains a WHITELIST you can do blacklist but blacklists are not that safe as there are always tags you could forget to check against.
4: If the HTML is server generated and has not user input you should be fine.
5: Know that Fortify is just a scanning tool and it has false positives, so if you have the right countermeasures you should be XSS free.
Whitelisting: Checking agains a list of available tags. Only letting tags that you know the user can use like <p></p><br/>.
Blacklisting: Checking against a list of "not welcome" tags. This means having a list with tags you don't want to let the user use.

Safari encodes already encoded URL on request

I do an HTTP GET request for a page using the following URL in Safari:
mysite.com/page.aspx?param=v%e5r
The page contains a form which posts back to itself.
The HTML form tag looks like this when output by asp.net:
<form method="post" action="page.aspx?param=v%u00e5r" id="aspnetForm" >
When Safari POSTs this back it somehow converts this URL to:
page.aspx?param=v%25u00e5r, i.e. it URL encodes the already URL encoded string, which is then double encoded and the output generated by this parameter is garbled (vår). I am able to get around this some places by URL decoding the parameter before printing it.
Firefox and even IE8 handles this fine. Is this a bug in WebKit or am I doing something wrong?
To summarise:
GET mysite.com/page.aspx?param=v%e5r
HTML: <form method="post" action="page.aspx?param=v%u00e5r" id="aspnetForm" >
POST mysite.com/page.aspx?param=v%25u00e5r
HTML: <form method="post" action="page.aspx?param=v%25u00e5r" id="aspnetForm" >
mysite.com/page.aspx?param=v%e5r
Whilst you can use encodings other than UTF-8 in the query part of a URL, it's inadvisable and will generally confuse a variety of scripts that assume UTF-8.
You really want to be producing forms in pages marked as being UTF-8, then accepting UTF-8 in your application and encoding the string vår (assuming that's what you mean) as param=v%C3%A5r.
page.aspx?param=v%u00e5r
Oh dear! That's very much wrong. %uXXXX is a JavaScript-escape()-style sequence only; it is wholly invalid to put in a URL. Safari is presumably trying to fix up the mistake by encoding the % that isn't followed by a two-digit hex sequence with a %25.
Is ASP.NET generating this? If so, that's highly disappointing. How are you creating the <form> tag? If you're encoding the parameter manually, maybe you need to specify an Encoding argument to HttpUtility.UrlEncode? ie. an Encoding.UTF8, or, if you really must have v%e5r, new Encoding(1252) (Windows code page 1252, Western European).