ASP.Net WebForms malformed querystring, ? rather than & - asp.net

In one of our webforms apps we have external links coming to the site where there are 2 querystring parameters, but the second param is also preceded by a ?.
Normally, your querystring will only have one ?, which is at the beginning just before the first param, and any subsequent params are preceded by &. For example:
www.somesite.com?param1=a&param2=b <---- this is properly formed
www.somesite.com?param1=a?param2=b <---- this is malformed
Yes, I know that param values can contain question marks, and it is best to escape them, but we don't have that issue.
These urls are coming from an external source and we can't do anything about them right now, but we do need to parse the querystrings properly.
With the above malformed url, Request.QueryString["param1"] yields:
a?param2=b
But if the url were properly formed it would yield:
a
Also if properly formed, Request.QueryString["param2"] would yield:
b
How best to handle such a situation, if you are unable to fix the source of the problem? I might add that the url comes to the site urlencoded.

This is the solution that I have come up with. Just fix the querystring and redirect back. In the Page_Load, I call this ProcessQS method, and have added the fix qs code to it:
private bool ProcessQS()
{
var param1 = Request.QueryString["param1"];
if (string.IsNullOrWhiteSpace(param1))
return false;
// Workaround for external links that have ? instead of & for querystring parameter beyond the first.
// In this case, id should be preceded by &, this handles those urls that have a ? preceding id.
if (param1.Contains("?param2="))
{
var qs = Request.ServerVariables["QUERY_STRING"];
qs = HttpUtility.UrlDecode(qs);
Response.Redirect($"~/somepage.aspx?{qs.Replace("?param2=", "&param2=")}", true);
}
return true;
}

Related

How to force unencoded url to show in users browser?

I'm using ASP.NET and am looking to redirect users to a page that includes an easily human readable URL. Every method I've tried takes in the URL and encodes it.
Since none of the parameters are taken in to the page or processed in any way, I don't believe there's any security concerns with turning the %20 into a space. If there is an IIS rule this would work on, I would be fine to turn off encoding on this one page, but I can't turn it off for the whole page as this is a special use case.
I've already tried having Response.Redirect and Server.Transfer, and I cannot use Literals as putting the query into the page somewhere could allow an XSS vulnerability.
Expected:
example.com/test?message=Hello World
Actual:
example.com/test?message=Hello%20World
Edit For More Clarity:
<script>
console.log(window.location.pathname + window.location.search);
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
console.log(window.location.pathname + replaceAll(window.location.search, '%20', ' '));
window.history.pushState(window.location.search, "Title", window.location.pathname + replaceAll(window.location.search, '%20', ' '));
</script>
This will write the current URL to the console, then the URL I'd like to see, but then the pushState does not actually update the URL to one without the encoding - it automatically re-encodes it.
I understand this may be impossible, but if someone could explain why then I will at least be able to stop trying so hard to find a solution.
As per Brando Zhang's comment this appears impossible.

Get the full QueryString from URL in ASP.NET

I have an URL with the following format:
http://www.mysite.com/login.aspx?ref=~/Module/MyPage.aspx?par=1&par2=hello&par3=7
I use the content of the QueryString it to Redirect the user back to the page he was before logging in. In order to keep also the status of the page I need the parameters in the QueryString. The number of parameters changes depending on the Page calling the Login and its status.
Let's say I want to store everything in the URL after ref in the redirectURL variable. I tried:
redirectURL = Request.QueryString("ref") // "~/Module/MyPage.aspx?par=1"
it gets everything after ref but ignores everything after the &(included). If I use:
redirectURL =Request.Url.Query // "ref=~/Module/MyPage.aspx?par=1&par2=hello&par3=7"
it gets everything, ref included. In order to achieve my goal I need just to remove the first 4 characters from the redirectURL. But I think this solution is a bit "forced" and I am sure there should be some ASP.NET function that accomplish this task.
The &s in your URL are creating additional querystring arguments.
You need to escape the value of the ref parameter before putting it in the querystring.
This will replace the &s with %26.
To do this, call Uri.EscapeDataString().
When you fetch the property from Request.QueryString, it will automatically decode it.
Consider Encoding "~/Module/MyPage.aspx?par=1&par2=hello&par3=7" before passing it to the url.
Eg.:
String MyURL = "http://www.mysite.com/login.aspx?ref=" +
Server.UrlEncode("~/Module/MyPage.aspx?par=1&par2=hello&par3=7");
And then, you can get the redirectURL using:
String redirectURL = Request.QueryString("ref");

What is the use of =? in links?

I saw my friend doing some Web Development, and one of his code caught my attention is the Response.Redirect.
What is the use of Home?=, isn't it the LogIn.aspx is the name of the page how come it's still redirecting if it has Home?=. Can someone answer this question of mine please, and explain it very well.
String url = "LogIn.aspx?Home?=" + Username;
Response.Redirect(url);
Update
Working from all your comments, the answer is: The query string parameter name (key) is actually "Home?", not just "Home". Details (including why the code generating that is technically incorrect) below.
how come it's still redirecting if it has Home?=?
Because there's no reason it shouldn't redirect. Granted the URL is invalid (? is a reserved character, it cannot appear unencoded in the query string, so the second ? in the URL is incorrect), but browsers are pretty content to deal with invalid URLs.
Separately, unless Username has already been URL-encoded, the URL could have other errors depending on the content of Username. (All query string parameters must be URL-encoded, in .Net you do that with HttpUtility.UrlEncode.)
Re your comment:
what i mean is i don't know why he use Home?= and what is the use of it
It has no use, it's an error. He probably just meant (no, apparently not, see below after your next comment)
String url = "LogIn.aspx?Home=" + Username;
...which would more correctly be:
String url = "LogIn.aspx?Home=" + HttpUtility.UrlEncode(Username);
(Technically, you have to URL-encode both the keys and values [both "Home" and Username], but the URL-encoded form of "Home" is "Home", so we can get away without making the call for the key. Not true if the key needs to have any of the URL reserved characters in it.)
Re your further comment consisting entirely of this code:
string retrieveValue;
protected void Page_Load(object sender, EventArgs e) {
this.lblUsername.Text = Request.QueryString["Home?";
retrieveValue = this.lblUsername.Text;
}
Assuming the syntax error in the above is fixed (missing ] on line 3), it would appear that he's actually using "Home?" as a key (parameter name). That means the redirect should be:
String url = "LogIn.aspx?" + HttpUtility.UrlEncode("Home?") + "=" + HttpUtility.UrlEncode(Username);
...because the key has a reserved character in it (?). Because that will be decoded for you on receipt, that should make the code above work.
Note that most browsers will probably let you get away with the string as he specified it. It's incorrect, but in a way browsers probably allow.
Regardless of the errors that T.J covered, what he meant to do was load the page LogIn.aspx with the variable "Home" being set to the visitors username. This allows the page to "GET" the variable and use it. Its basically a way of sending data from one page to another.

Open Redirect or Header Manipulation issues from Fortify scan on asp.net

We did a Fortify scan on our ASP.net application. We found that there many header manipulation issues. All the issues are pointing to Response.Redirect(). Please have a look at the below code where I encoded the parameters. Even then the below code is counted as header manipulation issue.
int iCount = 0;
foreach (string Name in Request.QueryString.Keys)
{
iCount++;
if (iCount > 1)
{
url += "&";
}
url += Name;
if (Request.Params[Name]!=null)
{
url += "=" + AntiXss.UrlEncode(Request.Params[Name]);
}
}
Response.redirect(Server.UrlPathEncode(page.root) + "\Test.aspx?" + url);
Can some body let me know what else is required to change here to resolve the issue?
Take off the Server.UrlPathEncode(page.root) portion and use Server.Transfer() instead of Response.Redirect().
Server.Transfer() transfers the user to another page on the same site and poses little to no danger of accidentally directing someone to another site.
Response.Redirect() is good for when you want to redirect someone to another site.
Also, Fortify doesn't tend to like Request.Params[] due to its possible ambiguity. A careful attacker may be able, on some servers, to send a UTF-7 or non-printing version of a name as one of the request variables and let the name of the variable contain the actual XSS injection, or overwrite the GET-request value with a cookie of the same name. Make sure both the name and value are htmlencoded, and consider using Request.QueryString[parametername] instead of Request.Params[parametername] to avoid more issues with Fortify.
Hopefully this gets you past your Fortify issues!
It appears that Fortify percieves Name as user defined and that will triger "Manupulation" error. If it's true try to use predefined list if possible.

Problem with slash within a query string

I'm using the WebRequest class to make a request to some site. The query string contains a slash (/), which cause to the url to be cut by the site, because it doesn't see it as part of the query string.
The query string is: "my params / separated by slash".
The request:
var request = WebRequest.Create(
"http://www.somesime.com/q-my+params+%2f+separated+by+slash"
);
What I missing?
EDIT:
After all answers here are update:
I was wrong about query string, it's not actually query string, but the url should look (without "?"):
"http://www.somesime.com/q-my+params+%2f+separated+by+slash"
The url "http://www.somesime.com/q-my+params+%2f+separated+by+slash" is result of Server.UrlEncode method. The code:
var url = "http://www.somesime.com/q-" +
Server.UrlEncode(#"my params / separated by slash");
EDIT 2:
If I place the resulting url into a browser, everything works.
But if I run it through WebRequest class, the url results as it was called without "/ separated by slash" part
If this is your actual code you are missing the ?:
var request = WebRequest.Create("http://www.somesime.com/?q=my+params+%2f+separated+by+slash");
you forgot to put "?" before key name , so try :
var request = WebRequest.Create("http://www.somesime.com?q=my+params+%2f+separated+by+slash");
You need to have a look at apaches AllowEncodedSlashes option
http://httpd.apache.org/docs/2.0/mod/core.html#allowencodedslashes
You should be able to enable this through .htaccess or httpd_conf
UrlEncode it. (You will need a reference to System.Web )
string url = "http://www.somesime.com/?q=my+params+%2f+separated+by+slash");
var request = WebRequest.Create(HttpUtility.UrlEncode(url));
This part of the URL:
/q=my+params+%2f+separated+by+slash
is actually a continuation of the URL, the website probably uses some kind of URL routing. Query strings are denoted by the '?' and seperated by '&'.
If you did need to remove '/' from a URL then HttpUtility.UrlEncode would be the way to go, but this will not benefit you in your case as any encoding done to the URL will almost definitely cause your WebRequest to fail.
?
(Yes, that is what you are missing. :)
Use like this
$qrypic = 'INSERT INTO tbl_propics (userID,num,imagename,propic) VALUES ("$id","1","http://\graph.facebook.com/\$id/\picture?type=large","1")';

Resources