私の ASP.NET Web サイトには、Web アプリで何らかのエラーが発生したときに、私 (および別の開発者) に電子メールを送信するグローバル エラー ハンドラーがあります。最近、聞いたことのない電子メール アドレスへの CC を含むエラーを受け取りました。恐ろしいのは、エラー メールが送信される開発者のリストが、コンパイルされた ASP.NET コードにハード コーディングされていることです。CC がどのように追加されたのかはわかりません。
また、エラーの原因となったリクエストは、フォームの 1 つを使用してスパムを送信しようとしたものであるため、不正行為の可能性も非常に疑われます。リクエストを送信した IP アドレスもhttp://www.projecthoneypot.org/にリストされています。
現時点で最も推測できるのは、リクエストの形式が不正であり、CC ヘッダーが電子メールに挿入されたということです。問題は、これがどのように行われるかを理解できないことです。System.Net.Mail を使用して電子メールを送信していますが、この種のことから保護しているようです。MailMessage オブジェクトの件名は 1 行しか受け付けないため、CC 行で複数行の件名を作成することはありません。MailMessage で to および cc アドレスを設定することは、かなり堅牢なようです。また、メッセージの本文に 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.
}
}
}