На моем веб-сайте ASP.NET есть глобальный обработчик ошибок, который отправляет электронное письмо мне (и другому разработчику), когда в веб-приложении возникает какая-либо ошибка. Недавно мы получили сообщение об ошибке, содержащее CC на адрес электронной почты, о котором мы никогда не слышали. Страшно то, что список разработчиков, которым отправляется электронное письмо с ошибкой, жестко закодирован в скомпилированном коде ASP.NET. Мы не видим, как можно было добавить CC.
Мы также очень подозрительно относимся к нечестной игре, потому что запрос, вызвавший ошибку, был попыткой использовать одну из наших форм для рассылки спама. IP-адрес, с которого был отправлен запрос, также указан на http://www.projecthoneypot.org/.
Сейчас мы можем предположить, что запрос был каким-то образом искажен, и в него был добавлен заголовок CC в электронное письмо. Проблема в том, что мы не можем понять, как это можно сделать. Мы используем System.Net.Mail для отправки электронных писем, и, похоже, он защищает от подобных вещей. Тема объекта MailMessage принимает только одну строку, поэтому вы не создаете многострочную тему со строкой CC. Установка адресов «to» и «cc» в MailMessage кажется довольно надежной. И я не понимаю, как можно добавить заголовок CC в тело сообщения. Я не могу найти никакой информации по этому поводу и хотел бы знать, действительно ли это проблема.
РЕДАКТИРОВАТЬ: кто-то запросил код. Это немного длинновато, но вот оно:
public class Global : System.Web.HttpApplication
{
protected void Application_Error(Object sender, EventArgs e)
{
// Get the last exception.
Exception objException = Server.GetLastError();
// Work out the error details based on the exception.
string ErrorType = "";
string ErrorDescription = "";
string ErrorHtml = "";
if (objException == null)
{
// This should never occur.
ErrorType = "Unknown Error";
ErrorDescription = "Unknown Error";
}
else if (objException.GetType() == typeof(HttpException))
{
// This will occur when the ASP.NET engine throws a HttpException.
HttpException objHttpException = objException as HttpException;
if (objHttpException.GetHttpCode() == 404)
{
string Resource = Globals.GetFullUrl(this.Context);
Server.ClearError();
Response.Redirect("/ResourceNotFound.aspx?BadUrl=" + Server.UrlEncode(Resource));
return;
}
else
{
ErrorType = objHttpException.GetHttpCode().ToString();
ErrorDescription = objHttpException.Message;
}
}
else if (objException.GetType() == typeof(HttpUnhandledException) && objException.InnerException != null && objException.InnerException.GetType() == typeof(HttpException))
{
// This will occur when the code throws a HttpException (e.g. a fake 404).
HttpException objHttpException = objException.InnerException as HttpException;
if (objHttpException.GetHttpCode() == 404)
{
string Resource = Globals.GetFullUrl(this.Context);
Server.ClearError();
Response.Redirect("/ResourceNotFound.aspx?BadUrl=" + Server.UrlEncode(Resource));
return;
}
else
{
ErrorType = objHttpException.GetHttpCode().ToString();
ErrorDescription = objHttpException.Message;
}
}
else if (objException.GetType() == typeof(HttpUnhandledException))
{
// This will occur when a page throws an error.
HttpUnhandledException objHttpUnhandledException = (HttpUnhandledException) objException;
ErrorType = objHttpUnhandledException.GetHttpCode().ToString();
if (objHttpUnhandledException.InnerException != null)
ErrorDescription = objHttpUnhandledException.InnerException.Message;
else
ErrorDescription = objHttpUnhandledException.Message;
if (objHttpUnhandledException.GetHtmlErrorMessage() != null)
{
ErrorHtml = objHttpUnhandledException.GetHtmlErrorMessage();
}
}
else if (objException.GetType() == typeof(HttpRequestValidationException) && !Globals.IsTtiUser(this.Context))
{
// Do nothing. This is mostly just spider junk and we don't want to know about it.
}
else
{
// This will occur when the ASP.NET engine throws any error other than a HttpException.
ErrorType = objException.GetType().Name;
ErrorDescription = objException.Message;
}
// Send an email if there's an error to report.
if (ErrorType != "" || ErrorDescription != "")
{
Globals.SendErrorEmail(this.Context, ErrorType, ErrorDescription, ErrorHtml);
}
}
public static void SendErrorEmail (HttpContext context, string errorType, string errorDescription, string errorHtml)
{
// Build the email subject.
string Subject = "EM: " + errorType + ": " + context.Request.ServerVariables["SCRIPT_NAME"];
// Build the email body.
string Body;
StringBuilder sb = new StringBuilder("");
sb.Append("Server:\r\n");
sb.Append(Globals.Server.ToString() + "\r\n");
sb.Append("\r\n");
sb.Append("URL:\r\n");
sb.Append(Globals.GetFullUrl(context) + "\r\n");
sb.Append("\r\n");
sb.Append("Error Type" + ":\r\n");
sb.Append(errorType + "\r\n");
sb.Append("\r\n");
sb.Append("Error Description" + ":\r\n");
sb.Append(errorDescription + "\r\n");
sb.Append("\r\n");
sb.Append("Referring Page:\r\n");
sb.Append(context.Request.ServerVariables["HTTP_REFERER"] + "\r\n");
sb.Append("\r\n");
sb.Append("Date/Time:\r\n");
sb.Append(DateTime.Now.ToString() + "\r\n");
sb.Append("\r\n");
sb.Append("Remote IP:\r\n");
sb.Append(context.Request.ServerVariables["REMOTE_ADDR"] + "\r\n");
sb.Append("\r\n");
sb.Append("User Agent:\r\n");
sb.Append(context.Request.ServerVariables["HTTP_USER_AGENT"] + "\r\n");
sb.Append("\r\n");
sb.Append("Crawler:\r\n");
sb.Append(context.Request.Browser.Crawler.ToString() + "\r\n");
sb.Append("\r\n");
sb.Append("Admin User:\r\n");
sb.Append(context.User.Identity.Name + "\r\n");
sb.Append("\r\n");
sb.Append("\r\n");
Body = sb.ToString();
// If there's HTML to represent the error (usually from HttpUnhandledException),
// then stuff the body text into the HTML (if possible).
bool HtmlMessage = false;
if (errorHtml != "")
{
Regex r = new Regex("(?<thebodytext><body.*?>)", RegexOptions.IgnoreCase);
if (r.IsMatch(errorHtml))
{
Body = Body.Replace("\r\n", "<br>");
Body = r.Replace(errorHtml, "${thebodytext}" + Body, 1);
HtmlMessage = true;
}
}
// Send an email to the TTI developers.
MailMessage objMail;
objMail = new MailMessage();
objMail.From = new MailAddress("from-address");
objMail.To.Add(new MailAddress("to-address"));
objMail.CC.Add(new MailAddress("cc-address"));
objMail.CC.Add(new MailAddress("another-cc-address"));
if (HtmlMessage)
objMail.IsBodyHtml = true;
else
objMail.IsBodyHtml = false;
if (errorType == "404")
objMail.Priority = MailPriority.Low;
else
objMail.Priority = MailPriority.High;
objMail.Subject = Subject;
objMail.Body = Body;
try
{
SmtpClient objSmtpClient = new SmtpClient();
objSmtpClient.Send(objMail);
}
finally
{
// Do nothing.
}
}
}