When i visit http://localhost:17357/u/a%2fa/m/ssd-10 and look at HttpContext.Current.Request.Url in Application_BeginRequest i see http://localhost:17357/u/a/a/m/ssd-10 huh? shouldnt i get http://localhost:17357/u/a%2fa/m/ssd-10? i thought the point of escaping urls is so ?, &, / and other special symbols not be confused with their special meaning in urls. Maybe theres a config i need to tweak?
I created 4 usernames, there are
a?#!&ee
a?#!/&ee
as d
クイン
with the links as
a?#!&ee<br>
a?#!/&ee<br>
as d<br>
クイン
The last two work, but the first two i get the exceptio
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Illegal characters in path.
then
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
Additional information: '/u/a?#!&ee' is not a valid virtual path.
and my page says Bad Request. How can i allow these usernames to work. If its impossible how can i write a workaround?
You need to escape it again. Use %252f instead of %2f. To clarify, the URL is unencoded when the server receives it. URL encoding allows you to pass in a / that the server processes as a character instead of the special function that a reserved character would normally trigger. See the Wikipedia page for more info.
Concerning your error with the a?#!&ee username, it seems almost certain that you're running into a problem that ASP.NET has with special characters (even urlencoded properly) that are not in the query string (that is, after the ? part of the URL). Joshua Flanagan talks about it in a blog post, and identifies %, &, *, and : as the problematic characters.
He points to a Dirk.Net blog post that offers a couple of fixes. First, you can edit the registry to allow restricted characters (adding a DWORD key AllowRestrictedChars to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters and setting its boolean value to true). Or, you can ensure that you have the .NET framework 1.1 SP1 and edit the registry to set ASP.NET VErification Compatibility to true (DWORD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET VerificationCompatibility = 1). Third, you can try setting ValidateRequest to false on the ASPX page. Finally, as Joshua decided to do, you can pass the information using the query string, i.e. after the ? as ASP.Net originally (pre MVC) expected.
I wrote my own solution. Its nice to have a username with / but not consider as / when getting a GET request.
Related
I'm currently using the NLog.Web package for writing my .Net logs in my application.
After reading the NLog.Web I've noticed that unlike the ${windows-identity} layout renderer, the ${aspnet-user-identity} layout renderer got no domain parameter for it.
For example, if I want to log the current running windows identity, it logs out: domain\user, but when specifying domain=false, it logs only user.
How do I implement this kind of ability with the ${aspnet-user-identity}? Because when I configured ${aspnet-user-identity:domain=false} it didn't work.
The WindowsIdentity.Name, used in NLog, will always give the full name, including domain.
The logon name is in the form DOMAIN\USERNAME.
https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.name(v=vs.110).aspx
I think you need a custom layout renderer, and split it by-hand on the /.
Something like this: (maybe also add soms checks for outOfIndex)
using NLog.LayoutRenderers;
....
//register ${my-aspnet-user-identity}
LayoutRenderer.Register("my-aspnet-user-identity",
(logEvent) => HttpContext.Current?.User?.Identity?.Name?.Split('/')[1]);
Register it as soon as possible.
I found a different way to solve this issue #Julian
in the NLog.config file, i created a variable:
<variable name="aspnetIdentity" value="${replace:searchFor=^\\w+\\\\:replaceWith=:regex=true:inner=${aspnet-user-identity}}" />
As defined in the variable, the regex searches for at least one word (at the start) and finally searching for a backslash.
the other backslashes are written to escape special characters and also double backslashing. Finally, what was found (it's the domain name) will be replaced with an empty string and therefore I got only the username and not the Domain\Username
Thanks for the help #Julian
Context: ASP.NET MVC running in IIS, with a a UTF-8 %-encoded URL.
Using the standard project template, and a test-action in HomeController like:
public ActionResult Test(string id)
{
return Content(id, "text/plain");
}
This works fine for most %-encoded UTF-8 routes, such as:
http://mydevserver/Home/Test/%e4%ba%ac%e9%83%bd%e5%bc%81
with the expected result 京都弁
However using the route:
http://mydevserver/Home/Test/%ee%93%bb
the url is not received correctly.
Aside: %ee%93%bb is %-encoded code-point 0xE4FB; basic-multilingual-plane, private-use area; but ultimately - a valid unicode code-point; you can verify this manually, or via:
string value = ((char) 0xE4FB).ToString();
string encoded = HttpUtility.UrlEncode(value); // %ee%93%bb
Now, what happens next depends on the web-server; on the Visual Studio Development Server (aka cassini), the correct id is received - a string of length one, containing code-point 0xE4FB.
If, however, I do this in IIS or IIS Express, I get a different id, specifically "î“»", code-points: 0xEE, 0x201C, 0xBB. You will immediately recognise the first and last as the start and end of our percent-encoded string... so what happened in the middle?
Well:
code-point 0x93 is “ (source)
code-point 0x201c is “ (source)
It looks to me very much like IIS has performed some kind of quote-translation when processing my url. Now maybe this might have uses in a few scenarios (I don't know), but it is certainly a bad thing when it happens in the middle of a %-encoded UTF-8 block.
Note that HttpContext.Current.Request.Raw also shows this translation has occurred, so this does not look like an MVC bug; note also Darin's comment, highlighting that it works differently in the path vs query portion of the url.
So (two-parter):
is my analysis missing some important subtlety of unicode / url processing?
how do I fix it? (i.e. make it so that I receive the expected character)
id = Encoding.UTF8.GetString(Encoding.Default.GetBytes(id));
This will give you your original id.
IIS uses Default (ANSI) encoding for path characters. Your url encoded string is decoded using that and that is why you're getting a weird thing back.
To get the original id you can convert it back to bytes and get the string using utf8 encoding.
See Unicode and ISAPI Filters
ISAPI Filter is an ANSI API - all values you can get/set using the API
must be ANSI. Yes, I know this is shocking; after all, it is 2006 and
everything nowadays are in Unicode... but remember that this API
originated more than a decade ago when barely anything was 32bit, much
less Unicode. Also, remember that the HTTP protocol which ISAPI
directly manipulates is in ANSI and not Unicode.
EDIT: Since you mentioned that it works with most other characters so I'm assuming that IIS has some sort of encoding detection mechanism which is failing in this case. As a workaround though you can prefix your id with this char and then you can easily detect if the problem occurred (if this char is missing). Not a very ideal solution but it will work. You can then write your custom model binder and a wrapper class in ASP.NET MVC to make your consumption code cleaner.
Once Upon A Time, URLs themselves were not in UTF-8. They were in the ANSI code page. This facilitates the fact that they often are used to select, well, pathnames in the server's file system. In ancient times, IE had an option to tell whether you wanted to send UTF-8 URLs or not.
Perhaps buried in the bowels of the IIS config there is a place to specify the URL encoding, and perhaps not.
Ultimately, to get around this, I had to use request.ServerVariables["HTTP_URL"] and some manual parsing, with a bunch of error-handling fallbacks (additionally compensating for some related glitches in Uri). Not great, but only affects a tiny minority of awkward requests.
2nd in an occasional series:
Here's the first one
Is CAT.NET correct that the following is a genuine vulnerability in ASP.NET or is it a false positive?
var myInt = Int32.Parse(txtUserInput.Text);
Response.Redirect(string.Format("myPage.aspx?myId={0}", myInt);
CAT.NET is reporting this as a redirect vulnerability needing remediation via encoding myInt.
I wouldn't call that dangerous but its not how I would write it myself
int myInt;
if(Int32.TryParse(txtUserInput.Text,out myInt)){
Response.Redirect(string.Format("myPage.aspx?myId={0}", myInt);
}
Is to my mind cleaner as it wont throw an exception if the parse fails due to bad user input and we are explicitly typing the int.
Any error handling code can be bundled into an else statement on the end.
I don't believe so, it could cause an exception so TryParse might be a better approach. It's just yelling because you are taking user input and redirecting based on it. It's possibly being a little too aggressive which isn't exactly bad.
There is no exploitable vulnerability as a result of this code. Any vulnerability would be a result of what myPage.aspx does with the value of myId, not how your url is built. Anyone could just as easily directly hit myPage.aspx with anything they want in the querystring.
However this is bad practice, assuming that you haven't left anything out of the code between those two lines. You should verify that txtUserInput.Text contains only numeric characters, and falls within allowable values.
Exploits happen because of improper parsing of user-supplied data by the page it's posted to -- not improper generating of URLs. While it's a good idea to try to make sure your web site won't write a broken URL because of something that's put in a form, input validation at the front-end is irrelevant to security. All that matters is what the code that accepts the input does with it, since any post or query string can be forged.
I need to allow the user to submit queries as follows;
/search/"my search string"
but it's failing because of request validation, as outlined in the following 2 questions:
How to include quote characters as a route parameter? Getting "Illegal characters in path" message
How to modify request validation?
I'm currently trying to figure out how to disable request validation for the quote character, but i'd like to know the risks before I actually put the site live with this disabled? I will not disable the request validation unless I can only disable it for the quote character, so I do intend to disallow every other character that's currently not allowed.
According to the URI generic syntax specification (RFC 2396), the double-quote character is explicitly excluded and must be escaped (i.e. %22). See section 2.4.3. The reason given in the spec:
The angle-bracket "<" and ">" and double-quote (") characters are excluded because they are often used as the delimiters around URI in text documents and protocol fields.
You can see easily why this is the case -- imagine trying to create a link in HTML to your URL:
<a href="http://somesite/search/"my search string""/>
That would fail HTML parsing (and also breaks SO's syntax highlighting). You also would have trouble doing basic things with the URL like emailing it to someone (the email client wouldn't parse the URL correctly), posting it on a message board, sending it in an instant message, etc.
For what it's worth, spaces are also explicitly excluded (same section of the RFC explains why).
I pass a vb.net query string to a page with, depending on the parameter, a spanish character on it, wich works perfectly on the development and testing servers, but not in production.
So, inside the query string I encode the name like this:
Server.UrlEncode(name)
And even before it gets to load, the server throws a "500 Internal Server Error"
with this url:
http://website/Dir/Page.aspx?num=CEJMEJINMFCEGICCEH&name=Jose+Bonse%c3%b1or+Del+Rosario
when I replace the %c3%b1 for any other normal letter, it works (%c3%b1 is an "ñ")
Again, its works just fine on the other servers, except on production, I dont even know where to start looking..
The HttpServerUtility class (which "Server" is an instance of in the Page base class) uses ASCII by default to decode and encode URL parameters. ASCII, of course, is not vast enough to handle other localizations. To force Unicode, try using UrlEncodeUnicode function of the HttpUtility class instead...
HttpUtility.UrlEncodeUnicode(name)
There are two things that pop to mind although I cannot say that I've actually tested either in this specific case (request string encoding).
First, how is your page encoded? That is, do you indicate the character sets used?
Second, how is the server computer configured re: localization? I'd compare the "Regional and Language Options" in the Control Panel on the three computers.
Finally (Ok, that's three) there are localization options in Web.Config. As is often true, CodeProject has a great article on the subject.
Good luck!