71

What do you use to validate an email address on a ASP.NET form. I want to make sure that it contains no XSS exploits.

This is ASP.NET 1.1

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Brian G
  • 53,704
  • 58
  • 125
  • 140

9 Answers9

127

Any script tags posted on an ASP.NET web form will cause your site to throw and unhandled exception.

You can use a asp regex validator to confirm input, just ensure you wrap your code behind method with a if(IsValid) clause in case your javascript is bypassed. If your client javascript is bypassed and script tags are posted to your asp.net form, asp.net will throw a unhandled exception.

You can use something like:

<asp:RegularExpressionValidator ID="regexEmailValid" runat="server" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" ControlToValidate="tbEmail" ErrorMessage="Invalid Email Format"></asp:RegularExpressionValidator>
WebDude
  • 6,125
  • 5
  • 33
  • 44
19

Here is a basic email validator I just created based on Simon Johnson's idea. It just needs the extra functionality of DNS lookup being added if it is required.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.Web.UI;

namespace CompanyName.Library.Web.Controls
{
    [ToolboxData("<{0}:EmailValidator runat=server></{0}:EmailValidator>")]
    public class EmailValidator : BaseValidator
    {

        protected override bool EvaluateIsValid()
        {
            string val = this.GetControlValidationValue(this.ControlToValidate);
            string pattern = @"^[a-z][a-z|0-9|]*([_][a-z|0-9]+)*([.][a-z|0-9]+([_][a-z|0-9]+)*)?@[a-z][a-z|0-9|]*\.([a-z][a-z|0-9]*(\.[a-z][a-z|0-9]*)?)$";
            Match match = Regex.Match(val.Trim(), pattern, RegexOptions.IgnoreCase);

            if (match.Success)
                return true;
            else
                return false;
        }

    }
}

Update: Please don't use the original Regex. Seek out a newer more complete sample.

John_
  • 2,931
  • 3
  • 32
  • 49
  • 5
    Please keep in mind that this excludes some valid e-mail addresses. – Sam Apr 10 '13 at 23:41
  • 2
    The `|` in the character class `[a-z|0-9|]` seems wrong. Are you aware that this will match the `|` character and not work as an alternative? Besides this has failed for my e-mail address (test with 1a@a.com or a@1.com), so it's obviously wrong. – ygoe Sep 17 '16 at 13:49
8

You should always do server side validaton as well.

public bool IsValidEmailAddress(string email)
{
    try
    {
        var emailChecked = new System.Net.Mail.MailAddress(email);
        return true;
    }
    catch
    {
        return false;
    }
}

UPDATE

You can also use the EmailAddressAttribute in System.ComponentModel.DataAnnotations. Then there is no need for a try-catch to it's a cleaner solution.

public bool IsValidEmailAddress(string email)
{
    if (!string.IsNullOrEmpty(email) && new EmailAddressAttribute().IsValid(email))
        return true;
    else
        return false;
}

Note that the IsNullOrEmpty check is also needed otherwise a null value will return true.

VDWWD
  • 35,079
  • 22
  • 62
  • 79
7

You can use a RegularExpression validator. The ValidationExpression property has a button you can press in Visual Studio's property's panel that gets lists a lot of useful expressions. The one they use for email addresses is:

\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
Martin Brown
  • 24,692
  • 14
  • 77
  • 122
5

Validating that it is a real email address is much harder.

The regex to confirm the syntax is correct can be very long (see http://www.regular-expressions.info/email.html for example). The best way to confirm an email address is to email the user, and get the user to reply by clicking on a link to validate that they have recieved the email (the way most sign-up systems work).

RB.
  • 36,301
  • 12
  • 91
  • 131
5

In our code we have a specific validator inherited from the BaseValidator class.

This class does the following:

  1. Validates the e-mail address against a regular expression.
  2. Does a lookup on the MX record for the domain to make sure there is at least a server to deliver to.

This is the closest you can get to validation without actually sending the person an e-mail confirmation link.

Simon Johnson
  • 7,802
  • 5
  • 37
  • 49
4

Preventing XSS is a different issue from validating input.

Regarding XSS: You should not try to check input for XSS or related exploits. You should prevent XSS exploits, SQL injection and so on by escaping correctly when inserting strings into a different language where some characters are "magic", eg, when inserting strings in HTML or SQL. For example a name like O'Reilly is perfectly valid input, but could cause a crash or worse if inserted unescaped into SQL. You cannot prevent that kind of problems by validating input.

Validation of user input makes sense to prevent missing or malformed data, eg. a user writing "asdf" in the zip-code field and so on. Wrt. e-mail adresses, the syntax is so complex though, that it doesnt provide much benefit to validate it using a regex. Just check that it contains a "@".

JacquesB
  • 41,662
  • 13
  • 71
  • 86
1

Quick and Simple Code

public static bool IsValidEmail(this string email)
{
    const string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";    
    var regex = new Regex(pattern, RegexOptions.IgnoreCase);    
    return regex.IsMatch(email);
}
Naveen
  • 1,441
  • 2
  • 16
  • 41
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
using System.Text.RegularExpressions;

/// <summary>
/// Summary description for RegexUtilities
/// </summary>
public class RegexUtilities
{
    bool InValid = false;

    public bool IsValidEmail(string strIn)
    {
        InValid = false;
        if (String.IsNullOrEmpty(strIn))
            return false;

        // Use IdnMapping class to convert Unicode domain names.
        strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper);
        if (InValid)
            return false;

        // Return true if strIn is in valid e-mail format. 
        return Regex.IsMatch(strIn, @"^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$",
               RegexOptions.IgnoreCase);
    }

    private string DomainMapper(Match match)
    {
        // IdnMapping class with default property values.
        IdnMapping idn = new IdnMapping();

        string domainName = match.Groups[2].Value;
        try
        {
            domainName = idn.GetAscii(domainName);
        }
        catch (ArgumentException)
        {
            InValid = true;
        }
        return match.Groups[1].Value + domainName;
    }

}





RegexUtilities EmailRegex = new RegexUtilities();

       if (txtEmail.Value != "")
                {
                    string[] SplitClients_Email = txtEmail.Value.Split(',');
                    string Send_Email, Hold_Email;
                    Send_Email = Hold_Email = "";
    
                    int CountEmail;/**Region For Count Total Email**/
                    CountEmail = 0;/**First Time Email Counts Zero**/
                    bool EmaiValid = false;
                    Hold_Email = SplitClients_Email[0].ToString().Trim().TrimEnd().TrimStart().ToString();
                    if (SplitClients_Email[0].ToString() != "")
                    {
                        if (EmailRegex.IsValidEmail(Hold_Email))
                        {
                            Send_Email = Hold_Email;
                            CountEmail = 1;
                            EmaiValid = true;
                        }
                        else
                        {
                            EmaiValid = false;
                        }
                    }
    
                    if (EmaiValid == false)
                    {
                        divStatusMsg.Style.Add("display", "");
                        divStatusMsg.Attributes.Add("class", "alert alert-danger alert-dismissable");
                        divStatusMsg.InnerText = "ERROR !!...Please Enter A Valid Email ID.";
                        txtEmail.Focus();
                        txtEmail.Value = null;
                        ScriptManager.RegisterStartupScript(Page, this.GetType(), "SmoothScroll", "SmoothScroll();", true);
                        divStatusMsg.Visible = true;
                        ClientScript.RegisterStartupScript(this.GetType(), "alert", "HideLabel();", true);
                        return false;
                    }
                }
Code
  • 679
  • 5
  • 9