We currently has a page that is used to display a generic error message when errors occur on our website. It has no functionality at all other than displaying a label that mentions there was an error.
Here is my issue, our client has ran a security review and tells us our error page contains phishing due to the URL in the query string, now I don't consider this a problem, but to put an end to the question, I'd like to remove the query string.
My web.config entry is this:
<customErrors mode="On" defaultRedirect="~/DefaultErrorPage.aspx">
</customErrors>
When an error occurs, it goes to DefaultErrorPage.aspx?aspxerrorpath=/Website1/LastPage.aspx
How can I prevent this? However, I could just redirect to the page if it contains the query, but I'm more looking for a way to prevent the query string instead of an extra redirection.
you could catch/handle all errors in your global.asax file instead and do the redirect there
protected void Application_Error(object sender, EventArgs e)
{
//Exception ex = Server.GetLastError();
Server.Transfer("~/DefaultErrorPage.aspx");
}
As a quick-fix, I've found that appending "?" onto the end of the defaultRedirect setting worked for me in removing the aspxerrorpath.
Also, I was getting the same issue with the customErrors settings in system.web, and the same solution worked:
<customErrors mode="On" defaultRedirect="~/SystemError.aspx">
<error statusCode="403" redirect="~/Home.aspx?"/>
<error statusCode="404" redirect="~/Home.aspx?"/>
</customErrors>
Alternatively, do the same on system.webServer settings:
<httpErrors errorMode="Custom">
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" path="/Home.aspx?" responseMode="Redirect" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/Home.aspx?" responseMode="Redirect" />
</httpErrors>
You are going to have to take control of the error handling process yourself. One method is get rid of the custom error redirect and use the Application_Error method in global. You can then direct the person, as needed without any query string argument.
Another option is ELMAH, which is designed to avoid the yellow screen of death errors in ASP.NET. You can then tailor a friendly error and not worry about writing error handling code, per se.
A third method is to educate the security team on how ASP.NET works and see if the "security concern" is legitimate (it may be) or not. This does not mean they won't make you do one of the above options anyway, of course.
Related
I have the following code in global.asax which transfers to a static NotFound.aspx file when there is a 404 exception. This works on my development machine, with debug or release builds. When deploying the release build to an azure app service, instead of getting my static NotFound.aspx file I get a page with only the text: The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I have verified that the static files are present on the azure deployment.
The code in global.asax is:
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Response.Clear();
HttpException httpException = exception as HttpException;
if (httpException != null)
{
ErrorLogger.Log(httpException);
Server.ClearError();
switch (httpException.GetHttpCode())
{
case 404:
// page not found
Response.StatusCode = 404;
Server.Transfer("~/NotFound.aspx");
break;
default:
Response.StatusCode = 500;
Server.Transfer("~/Error.aspx");
break;
}
}
}
The problem seems to be that the Azure server environment has it's httpErrors config section defined in a way that intercepts these errors before they get to Application_Error. You can either modify this to let the errors pass through, or use it to deal with the errors in the first place (Which seems to be the best option). Using responseMode="File" you can avoid having to issue a redirect, and just supply a custom error page and the proper status code directly. This seems to be a more efficient and correct approach.
Example:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace" >
<remove statusCode="404"/>
<error statusCode="404" path="NotFound.html" responseMode="File"/>
<remove statusCode="500"/>
<error statusCode="500" path="Error.html" responseMode="File"/>
<remove statusCode="400"/>
<error statusCode="400" path="Error.html" responseMode="File"/>
</httpErrors>
</system.webServer>
For more info:
https://www.iis.net/configreference/system.webserver/httperrors
You could also try specifying the redirect rule in the Web.config:
<configuration>
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough">
<remove statusCode="404"/>
<add statusCode="404" path="/NotFound.aspx" responseMode="Redirect" />
</httpErrors>
</system.webServer>
</configuration>
Then in your Web.Release.config(or other configuration you use in Azure):
<configuration>
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace" xdt:Transform="SetAttributes">
</httpErrors>
</system.webServer>
</configuration>
You can add your code 500 error page in a similar fashion.
Setting responseMode to Redirect makes IIS redirect the user with a 302, setting it to ExecuteURL will replace the response with the error page but keep the URL in the address bar.
Here is nice article about handling errors in this way: http://tedgustaf.com/blog/2011/5/custom-404-and-error-pages-for-asp-net-and-static-files/
Is there an easy way to catch multiple / all http status codes in the web config?
At the moment I have
<customErrors mode="Off">
<error statusCode="500" redirect="~/Account/Error"/>
<error statusCode="404" redirect="~/Account/NotFound"/>
</customErrors>
but lets say I wanted to catch 501, 502, 503 and etc, is there no way I can do a range or handle all status codes? I would prefer not to hard code every single error if possible
Just add the defaultRedirect attribute to the customErrors tag.
Search for examples like:
http://tech.trailmax.info/2013/08/error-handling-in-mvc-and-nice-error-pages/
I have setup a custom error handler to show diagnostic information to a user if a crash occurs. The problem is the custom error page is not shown and I get an exception (according to the webpage) thrown whilst trying to show the error page. I cannot figure out what is causing it though? I have similar pages set up for 500 and 404 errors which work fine.
The error page says Server Error in '/' Application.
Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
Ill show snippets of my setup, if anyone wants to see more please ask. FYI I am throwing the exception by removing the connection string details from my web.config (its an actual error we are seeing during deployment so I want to target this specifically)
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
<remove statusCode="403" />
<error statusCode="403" path="/error/forbidden" responseMode="ExecuteURL" />
<remove statusCode="500" />
<error statusCode="500" path="/error/" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<!-- .... -->
<system.web>
<customErrors mode="On" defaultRedirect="~/Error" redirectMode="ResponseRewrite">
<error redirect="~/Error/NotFound" statusCode="404" />
<error redirect="~/Error/Forbidden" statusCode="403" />
<error redirect="~/Error/" statusCode="500" />
</customErrors>
</system.web>
I then have an ErrorController with a default Index() function (no breakpoint within this controller gets hit)
public ViewResult Index()
{
return View("Error");
}
Note: I have functions for Forbidden() and NotFound() - I just didnt copy them here - these errors work perfectly fine.
Do you have all those roots available you specified in web.config? Seems that your controller just have index action, returning some view, but it supposed to have NotFound and Forbidden actions as well, or at least correct routs such as:
routes.MapRoute(
"NotFound",
"Error/NotFound",
new { controller = "Error", action = "Index" }, //bind all routes to single action
null, controllerNamespaces
);
routes.MapRoute(
"Forbidden",
"Error/Forbidden",
new { controller = "Error", action = "Index" }, //bind all routes to single action
null, controllerNamespaces
);
If you don't have NotFound and Forbidden actions setup those errors are likely throwing a second exception that is going to your index page since it is the default. Trying adding those two others your controller and see if they get hit and perhaps you can find the problem easier.
Also note that ResponseRewrite isn't compatible with mvc, see the answer here: CustomErrors does not work when setting redirectMode="ResponseRewrite"
You cannot use redirectMode="ResponseRewrite" when redirecting to another action, you have to use redirectMode="ResponseRedirect". You will loose the ability to use Server.GetLastError(), but if you don't need that, you will be fine.
This is my first post here, and I have searched for a resolution to this issue here and at many other forums on the web, without success.
I am attempting to create a custom error for directory access denied errors 403.14 for cases where say if someone tries to load the "_assests" directory on a web site. I know I can do a work around by adding a default.aspx page to each directory that I want this to happen with, but was wondering if there is a site wide solution similar to the tag in the web.config file
<configuration>
<system.web>
<customErrors defaultRedirect="/Errors/GenericError.aspx" mode="RemoteOnly">
<error statusCode="401"
redirect="/Errors/401.aspx"/>
<error statusCode="403"
redirect="/Errors/403.aspx"/>
<error statusCode="404"
redirect="/Errors/404.aspx"/>
<!--
<error statusCode="403.14"
redirect="/"/>
-->
</customErrors>
</system.web>
</configuration>
I get the error when coding the web.config that I am unable to use a statusCode with a decimal in it because it's not a datatype Int
I have an IIS 7 on Server 2008.
Any ideas?
Apologies ahead of time if this sounds rather confusing. Happy to clarify.
Added the following to the web.config and it seems to work so far. Don't know why, but if I don't explicitly tell 403 errors to redirect to a custom 403.aspx page, instead of the GenericError.aspx page, I get a 500 error. However, if I redirect 404 errors to my custom 404.aspx page, the GenericError.aspx code is written in place, not as expected, and it seems you are never redirected to the actual 404.aspx page (see commented portion of web.config). Bizarre.
CODE:
web.config file:
<system.webServer>
<httpErrors existingResponse="Replace" errorMode="Custom">
<remove statusCode="403"/>
<remove statusCode="404"/>
<error statusCode="403" path="/Errors/403.aspx" responseMode="Redirect" />
<!-- <error statusCode="403" path="/Errors/GenericError.aspx" responseMode="Redirect" /> -->
<!-- <error statusCode="404" path="/Errors/GenericError.aspx" responseMode="Redirect" /> -->
<error statusCode="404" path="/Errors/404.aspx" responseMode="Redirect" />
</httpErrors>
</system.webServer>
GenericError.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
var ex = HttpContext.Current.Server.GetLastError();
if (ex is HttpException)
{
var nex = ex as HttpException;
//Label in the Main code displays the Error Code from the Error String
this.customErrorMessageCode.Text += "Error Code" + " " + nex.GetHttpCode().ToString();
//Label in the Main code displays the Error Message from the Error String
this.customErrorMessageLabel.Text += ex.Message.ToString();
//DIV ID in the Main code displays the entire error message
this.customErrorMessage.Visible = true;
switch (nex.GetHttpCode())
{
case 404:
this.customErrorMessageCode.Text += " Page Not Found";
this.customErrorMessageImage.Visible = true;
// do somehting cool
break;
case 403:
this.customErrorMessageCode.Text += " Forbidden Access";
this.customErrorMessageImage.Visible = true;
// do somehting cool
break;
case 500:
this.customErrorMessageCode.Text += " Internal Error";
this.customErrorMessageImage.Visible = true;
// do somehting cool
break;
default:
break;
}
}
else {
this.customErrorMessageLabel.Text += ex.Message + ex.GetType().ToString();
}
}
SOURCE:
CustomError in web.config
Perhaps you could use a redirection approach that is based on the actual error code using Server.GetLastError().
In the Global.asax you will have something like this:
protected void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled) {
ShowCustomErrorPage(Server.GetLastError());
}
}
ShowCustomErrorPage would then have a switch statement that reads the HTTP code and redirects to the correct error page.
The is more from the source link, but it might be too MVC specific. As you didn't mention you use MVC, I didn't want to assume and blindly copy-paste.
I am not too familiar with MVC, but the principles here look like they could be adjusted to suit your scenario.
Source: http://www.digitallycreated.net/Blog/57/getting-the-correct-http-status-codes-out-of-asp.net-custom-error-pages
Edit
Found a couple of StackOverflow posts that could help too:
Custom Error Handling in web.config / Global.asax not handling non-existant directory
Custom error handling Asp.Net
I once saw that was possible to do something like adding a key in the web.config file to redirect to a default error page everytime a unhandled exception is found.
Is it possible? how?
Yes the customErrors section of the web.config.
<customErrors defaultRedirect="~/GenericError.aspx" mode="On" />
This will redirect your users to what defaultRedirect (URL) when they encounter an error.
You can also specify where they go based on the HTTP response code
<customErrors defaultRedirect="~/GenericError.aspx" mode="On">
<error statusCode="500" redirect="~/Error.aspx"/>
<error statusCode="404" redirect="~/NotFound.aspx"/>
</customErrors>
Here is the documentation.
Add a CustomErrors section to your web.config.
<customErrors defaultRedirect="ErrorPage.aspx" mode="RemoteOnly" />
<customErrors defaultRedirect="~/serverErrorPage.aspx" mode="On" redirectMode="ResponseRewrite"/>
It's not suitable for real use prior to .NET3.5 service pack 1, as until then the redirectMode attribute wasn't there and it would always act with the default value "ResponseRedirect" which would redirect to the error page instead of showing it directly; so instead of giving an error response it would "successfully" redirect to another page, and then that would return the error!