In our Global.asax
file we have:
protected void Application_Error()
{
Errors.Functions.HandleException(HttpContext.Current);
}
On a 404
error, the following code is executed:
context.Server.Transfer("~/pages/errors/404.aspx");
context.ClearError();
context.ApplicationInstance.CompleteRequest();
This works absolutely fine for every 404 exception. However, we’re seeing odd requests in our logs to paths that don’t exist such as:
https://www.example.com/en/meta.json
Visiting this page serves a normal 404
response page as above, and doesn’t throw any exceptions.
However, these requests (I’m guessing from some vulnerability scanner or crawler) throw this exception on a daily basis:
TYPE: HttpException
BASE TYPE: ExternalException
MESSAGE: Error executing child request for /pages/errors/404.aspx.
SOURCE:
System.Web
STACK TRACE:
at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
at System.Web.HttpServerUtility.Execute(String path, TextWriter writer, Boolean preserveForm)
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at System.Web.HttpServerUtility.Transfer(String path)
at C3.Code.Controls.Application.Errors.Functions.HandleException(HttpContext context) in ...HandleHTTPException.cs:line 81
Line 81 is the context.Server.Transfer(..
line.
The inner exception is:
TYPE: NullReferenceException
BASE TYPE: SystemException
MESSAGE:
Object reference not set to an instance of an object.
SOURCE:
C3Alpha2
STACK TRACE:
at C3.Pages.Errors._404.Page_Load(Object sender, EventArgs e) in ...PagesErrors404.aspx.cs:line 12
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Where line 12 is on of the Page_Load
lines:
public partial class _404 : System.Web.UI.Page
{
public Master_Pages.Main MP => (Master_Pages.Main) Master;
protected void Page_Load(object sender, EventArgs e)
{
MP.IsErrorPage = true;
MP.SEOPageHeader.Title = "File not found";
}
}
The requests throwing the error are normal HTTP GET
requests, and logging details about the headers etc doesn’t show anything that looks too unusual.
Does anyone know what could be causing this to throw these exceptions?
Edit: As requested, the 404.aspx page:
<%@ Page Language="C#" ValidateRequest="false" EnableViewState="false" MasterPageFile="~/Pages/Master Pages/Main.master" AutoEventWireup="True" Inherits="C3.Pages.Errors._404" Codebehind="404.aspx.cs" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Head" runat="server">
<base href="<%= C3.Code.Settings.Hosts.SecureRootDomain %>"/>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="server">
<span class="preH1">Ahhhh nuts!</span>
<h1>We Couldn't Find That!</h1>
<div class="singleCol">
<Controls:ResponsiveImageFixedSize
runat="server"
ImagePath="/errors/404.jpg"
Width="700"
/>
<p>The server returned an HTTP 404 error. That requested URL could not be found.</p>
</div>
</asp:Content>
2
Answers
What I want to say is not the exact answer to your question, but it may help to investigate your problem (because the text was a bit long, I did not write it in the comments).
This problem of yours reminded me of our problem.
My problem:
A few years ago, I wrote an "MVC ASP .NET Core 3.1" application for a company using "KendoUI" and with the company’s development tool, which was "Visual Studio 2019" and "Windows 10". This program received information about the user’s browser and client IP at some point of the operation based on the received request and was logged in the "Microsoft SQL" database (the program could only be used in LAN and the users were inside the company, but the program also had access to the Internet).
Sometimes we come across strange things in the logs:
For example, instead of the client’s full domain, a web address was inserted, and that address was mostly the same.
I think the basic information for the full name of the client was obtained with the following method:
As far as I know, the program’s system was never hacked, but the following possibilities are possible:
Suggestion:
Based on the OP’s problem-description, the long-and-short of it is that when a
Server.Transfer()
request is made to"~/pages/errors/404.aspx"
something causes aNullReferenceException
on one of these two lines (the OP didn’t specify exactly which line the stack-trace pointed at):The
this.MP
property returns thePage.Master
property, cast toMaster_Pages.Main
.It is possible but unlikely that
this.MP
is returningnull
– because that will only happen inPage_Load
if thePage.MasterPageFile
property is set tonull
despite ASP.NET setting it to a valid virtual-path due to the<%@ Page Master="" %>
directive property.It’s more likely that
MP.SEOPageHeader
is returningnull
, which means the next operation (setting.Title = "File not found"
) will fail with aNullReferenceException
.The OP declined to share the details of what exactly happens in the
SEOPageHeader
property’sget
accessor – and their description only fuels speculation because it seems to have a big scope of responsibility "it’s a helper that sets various header meta tags for each page (canonical URLs, rel=next/prev etc etc), icon files, page titles etc etc".Unable to diagnose the problem thoroughly, the next-best-thing I can do is suggest setting-up appropriate logging – and splitting-up can-fail operations (like
this.MP.SEOPageHeader.Title
) with intermediate variables which can be safely inspected fornull
and log accordingly:So I advocate updating
Page_Load
to this: