Unable Response.Redirect(url); with many query arguments - asp.net

The '&' that separates query string arguments is getting encoded no mater what I do.
// sitecore ASP.NET server side ascx code...
string url = string.Format("http://other-domain.com/?a={0}&b={1}", "1", "2");
Response.Redirect(url);
// ...
gives my browser the address:
http://other-domain.com/?a=1&b=2
which is not what I want, I simply want:
http://other-domain.com/?a=1&b=2
Is it Response.Redirect() that is HTMLencoding my '&'?
And how do I get it to leave that separator alone?

I am certain of one thing: this is not caused by Response.Redirect() or any of the other code that you posted.
There is probably something else wrong in the actual code.

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.

ASP.Net WebForms malformed querystring, ? rather than &

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;
}

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.

Server side call to webservice in classic ASP

I've .NET webservice, which takes a encoded html-string as a parameter, decodes the string and creates a PDF from the html. I want to make a synchronous server side call to the webservice from a classic asp webpage. It works fine if use a plain text string (with no html tags), but when I send a encoded html string the webservice it seems that the string is empty when it reaches the webservice.
The webservice is working fine when I call it from client side, with both plain text string and an encoded html string.
My code looks like this:
Private Sub SaveBookHtmlToPdf(pHtml, pShopId)
Set oXMLHTTP = CreateObject("Msxml2.ServerXMLHTTP.6.0")
Dim strEnvelope
strEnvelope = "pShopId=" & pShopId & "&pEncodedHtml=" & Server.HTMLEncode(pHtml)
Call oXMLHTTP.Open("POST", "https://mydomain.dk:4430/PdfWebservice.asmx/SaveBookToPdf", false)
Call oXMLHTTP.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
Call oXMLHTTP.Send(strEnvelope)
Set oXMLHTTP = Nothing
End Sub
It smells like some kind of security issue on the server. It's working when posting a asynchronous call from the client side, but not when it comes from server side - it seems that the encoded html string is somehow not allowed in a server side call to the webservice.
Anyone who know how to solve this tricky problem?
This looks all wrong to me:
Server.HTMLEncode(pHtml)
Its quite common for developers to get confused between HTML encoding and URL encoding even though they are quite different. You are posting data that needs to be URL encoded. Hence your code should use URLEncode instead:
strEnvelope = "pShopId=" & pShopId & "&pEncodedHtml=" & Server.URLEncode(pHtml)
Edit:
One thing that URLEncode does that may not be compatible with a URLEncoded post is it converts space to "+" instead of "%20". Hence a more robust approach might be:
strEnvelope = "pShopId=" & pShopId & "&pEncodedHtml=" & Replace(Server.URLEncode(pHtml), "+", "%20")
Another issue to watch out for is that the current value of Response.CodePage will influence how the URLEncode encodes non-ASCII characters. Typically .NET does things by default in UTF-8. Hence you will also want to make sure that your Response.CodePage is set to 65001.
Response.CodePage = 65001
strEnvelope = "pShopId=" & pShopId & "&pEncodedHtml=" & Replace(Server.URLEncode(pHtml), "+", "%20")
This may or may not help but I use a handy SOAP Class for Classic ASP which solved a few problems I was having doing it manually. Your code would be something like this:
Set cSOAP = new SOAP
cSOAP.SOAP_StartRequest "https://mydomain.dk:4430/PdfWebservice.asmx", "", "SaveBookToPdf"
cSOAP.SOAP_AddParameter "pShopId", pShopId
cSOAP.SOAP_AddParameter "pEncodedHtml", Server.HTMLEncode(pHtml)
cSOAP.SOAP_SendRequest
' result = cSOAP.SOAP_GetResult("result")
You will probably need to set your namespace for it to work ("" currently), and uncomment the 'on error resume next' lines from the class to show errors.
AnthonyWJones made the point about URL encoding and HTML encoding, and the original problem being experienced is likely a combine of the two, a race condition if you will. While is was considered answered, it partially wasn't, and hopefully this answers the cause of the effect.
So, as the message get HTMLEncoded, the html entities for the tags become such '<' = '<'.
And as you may know, in URLEncoding, &'s delimit parameters; thus the first part of this data strEnvelope = "pShopId=" & pShopId & "&pEncodedHtml=" & Server.HTMLEncode(pHtml) upto the "&pEncodedHtml" bit, is fine. But then "<HTML>..." is added as the message, with unencoded &'s...and the receiving server likely is delimiting on them and basically truncating "&pEncodedHtml=" as a null assign: "&pEncodedHtml=<HTML>... ." The delimiting would be done on all &'s found in the URL.
So, as far as the server is concerned, the data for parameter &pEncodedHtml was null, and following it were now several other parameters that were considered cruft, that it likely ignored, which just happened to actually be your message.
Hope this provides additional info on issues of its like, and how to correct.

jQuery ajax call containing script-tag in data

I read some values from text boxes and send them via jQuerys post method to an server. If the user enters text containing something like "bla bla", the call fails. The data looks like this in that case:
var data = { myKey: 'bla <script> bla' };
And I send it to the server like this:
$.post(targetUrl, data, function(x) {...});
On the server side (an Asp.Net web form) it looks like the call never reaches the server. Any hint how to solve that? If there's a convenient function which cleans data from bad tags, that would be fine too.
Have you desactivate the validate request of your aspx page?
add this in your page declaration: validateRequest="false"
To strip tags using a jQuery function:
jQuery.fn.stripTags = function() {
return this.replaceWith( this.html().replace(/<\/?[^>]+>/gi, '') );
};
Do you receive a page_load in ASP.NET? If yes, isn't there anything in Request.Params?
I would suggest escaping your values client side using the javascript escape function as shown below
var data = { myKey: escape('bla <script> bla') };
Once you have done that, you can retrieve the correct value on the server side using the following (.Net Code)
HttpUtility.UrlDecode(param_value_to_decode)
I tested this and the correct value is being passed correctly to the server via the post request.
Hope this helps.
Additional Info : I forgot to mention the cause of the error. When inspecting the request using firebug, it returns a "500 Internal Server Error - A potentially dangerous Request.Form value was detected from...". This is a built in protection mechanism from asp.net to protect against script injection. The following page directive ValidateRequest="false" did not solve the problem as expected (Works in traditional WebForms). It might be something specific to the Mvc platform, not to sure. The above solution does work, so just use that.
Regards
G

Resources