I am a PHP developer trying to solve a problem in ASP/ASP.net (.aspx). We have a very old application that is having many security issues (on multiple pages, everywhere, big mess).
To solve this problem, I was thinking on adding some code to the top of every page to escape any POST/GET request before getting it processed by the application.
If it was PHP, I would prepend a PHP file (using .htaccess - auto_preppend) and basically do:
foreach($_POST as $myval => $anything)
{
$_POST[$myval] = htmlspecialchars($_POST[$myval]);
.. other escaping ..
}
Is there such a thing in ASP? Just want to escape any user input before passing to that mess of code that nobody wants to touch :(
Is this ASP or ASP.NET? Different beasts entirely. If you're using .NET you could use something like:
in VB
For Each item In Request.Form.Keys
newVal = Server.HtmlEncode(Request.Form(item))
Next
or C#
foreach (var item in Request.Form.Keys) {
var newVal = Server.HtmlEncode(Request.Form(item));
}
From an individual control perspective, this might help: Prevent special characters in a TextBox
If you are wanting to protect your entire form from script-injection attacks then take a look at RequestValidation: http://www.asp.net/learn/whitepapers/request-validation
Related
Making an ad manager plugin for WordPress, so the advertisement code can be almost anything, from good code to dirty, even evil.
I'm using simple sanitization like:
$get_content = '<script>/*code to destroy the site*/</script>';
//insert into db
$sanitized_code = addslashes( $get_content );
When viewing:
$fetched_data = /*slashed code*/;
//show as it's inserted
echo stripslashes( $fetched_data );
I'm avoiding base64_encode() and base64_decode() as I learned their performance is a bit slow.
Is that enough?
if not, what else I should ensure to protect the site and/or db from evil attack using bad ad code?
I'd love to get your explanation why you are suggestion something - it'll help deciding me the right thing in future too. Any help would be greatly appreciated.
addslashes then removeslashes is a round trip. You are echoing the original string exactly as it was submitted to you, so you are not protected at all from anything. '<script>/*code to destroy the site*/</script>' will be output exactly as-is to your web page, allowing your advertisers to do whatever they like in your web page's security context.
Normally when including submitted content in a web page, you should be using htmlspecialchars so that everything comes out as plain text and < just means a less then sign.
If you want an advertiser to be able to include markup, but not dangerous constructs like <script> then you need to parse the HTML, only allowing tags and attributes you know to be safe. This is complicated and difficult. Use an existing library such as HTMLPurifier to do it.
If you want an advertiser to be able to include markup with scripts, then you should put them in an iframe served from a different domain name, so they can't touch what's in your own page. Ads are usually done this way.
I don't know what you're hoping to do with addslashes. It is not the correct form of escaping for any particular injection context and it doesn't even remove difficult characters. There is almost never any reason to use it.
If you are using it on string content to build a SQL query containing that content then STOP, this isn't the proper way to do that and you will also be mangling your strings. Use parameterised queries to put data in the database. (And if you really can't, the correct string literal escape function would be mysql_real_escape_string or other similarly-named functions for different databases.)
The problem here is the middle of the line (HTML).
The chain:
I have WinForm program that uses awesomium (alternative to native webBrowser) to view Html page that has a part of asp.net page in it's iframe.
The problem:
The problem is that I need to pass value to asp.net page, it is easily achieved without middle of the chain (Html iframe) by sending hashed and crypted querystring.
How it works:
WinForm do some thing, then use few-step-crypt to code all the needed values into 1 string.
Then it should send this string to asp.net page through the iframe (and that's the problem, it is easy to receive query string in asp.net page, but firstly I need to receive it in Html and send to asp.net).
Acceptable answers:
1) Probably the most easily one - using JavaScript. I have heard it is possible to be done in that way.
How I imagine this - I send query string from WinForm to Html page as http:\\HtmlPage.html?AspNet.aspx?CryptedString
Then Html receive it with JavaScript and put querystring "AspNet.aspx?CryptedString" into iframe's "src=http:\\" resulting in "src=http:\\AspNet.aspx?CryptedString"
And then I easily get it in asp.net page.
2) Somehow create >>>VIRTUAL<<<(NOTE: Virtual, I don't want querystring to be saved on the HDD, even don't suggest) asp.net or html page with iframe source taken directly from WinForm string.
Probably that is possible with awesomium, but I'm new to it and don't know how to (if it is possible ofc).
3) Some web service with which I can communicate between asp.net and WinForm through the existing HTML iframe.
4) Another way that replace one of 3 previous, that doesn't save "values" in querystring/else on HDD nor is visible for the user, doesn't use asp.net page's server to create iframe-page on it. On HTML page's server HTML is only allowed, PhP isn't.
5) If you don't know any of 4 above - suggest free PhP hosting without ads (if such exists, what I highly doubt).
Priority:
The best one would be #3, then #2, then #1, then #5 (#4 is excluded as it is unknown).
And in the end:
Thanks in advance for your help.
P.S.Currently at work, so I'll check/try all answers later on and will report tomorrow if any suits my needs. Thanks again.
Answering my own question. I have found 2 ways that can do what I did want.
The first one:
Creating a RAM file System.IO.MemoryStream or another method (google c# create a file in ram).
The second one:
Creating a hidden+encrypted+system+custom-readable-only-by-program-crypt file somewhere in the far away folder via File.SetAttributes Method and System.IO.StreamWriter/Reader or System.IO.FileStream or System.IO.TextWriter, etc. depending on what it should be.
Once this file was used for needs delete it + delete on exit + delete on start using
if (File.Exists(path)
{
File.Delete(path);
}
(Need more reputation to post few links -_-, and I don't want to post only part of them, either all or no at all, so use google if you'll need anything from here).
If you'll need to store "Small temp file" and not for a long time use first one, if "Heavy" use second one, unless you badly need to use RAM for it.
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.
I want to create an html page inside a asp.net page using c# and then request that html page. The flow is, I'll be creating a request that will give me a response with some values. Those values will be stored in hidden fields in the html page I'm creating on the fly and then requesting. I figure it would be something like below but I'm not sure if it would work, I've also received some "Thread Aborting" errors. So, does anyone know the proper way to do this or at least direct me to a nice article or something?
StringBuilder builder = new StringBuilder();
builder.Append("<html><head></head>");
builder.Append("<body onload=\"document.aButton.submit();\">");
builder.Append("<input type=\"hidden\" name=\"something\" value=\"" + aValue + "\">");
HttpContext.Current...Response.Write(builder.ToString());
... end response
This is a very common request and is almost never a good idea. What are you trying to do?
That said: you write out a file with a temporary name and redirect to that file. Later you have to figure out when it's safe to delete the file.
Edit That method points out one of the problems: you have to do your own garbage collection, deciding how long files must be kept around and deleting them appropriately.
I think it's possible with jQuery, but any ASP.NET serverside code is good for my situation too.
With jQuery I can load a page to for example a div, and filter the div for <title> tag, but I think for heavy pages, it is not good to first read all of the content and then read the title tag..
or maybe it has a very simple solution? anyways I couldnt find anything about that from internet.
thanks
okay thanks to cjjer and Boo, I've just read more about regex and finally the code below is working for me.
Dim qq As New System.Net.WebClient
Dim theuri As New Uri(TextBox1.Text)
Dim res As String = qq.DownloadString(theuri)
Dim re As Regex = New Regex("<title\b[^>]*>(.*?)</title>", RegexOptions.Singleline)
Dim ma As Match = re.Match(res)
If Not ma Is Nothing And ma.Success Then
Response.Write(ma.Groups(1).Value.ToString())
Else
Response.Write("error")
End If
but anyways, the problem remains, this code is downloading the whole page and seeking through it, which one heavy websites it took more than 2 or 3 secconds to complete, but seems it is the only way as far as I know :|
Is there any suggestions to refine this code?
cjjer almost got it right.
First, change the regex to: <title>(?<Content>.*?)?</title>
Second, you need to create a match object first (just in case your URI does not have a title).
Match tMatch = new RegEx(#"<title>(?<Content>.*?)?</title>").Match(new System.Net.WebClient().DownloadString(url));
if ((null != tMatch) && (tMatch.IsSuccess)) {
// yay.
title = tMatch.Groups("Content").value;
}
Titles usually appear within the first few hundred bytes, so you could try a range request for the first 1KiB or so, try parsing that (with an error-correcting parser, since some closing tags will be missing) and if that fails fall back to loading the whole page.
It would be security risk for you to load any other web page into yours, just for title read... You should do this with server side scripting (asp.net, php, ...) and just output the title to your web page. Thing of some kind of caching because it is seamless to fetch titles on every request.
There is no simple clean way to retrieve an external page's title. You could do it server side using a WebClient and parsing the response.
However it may be worth reviewing the requirement, is it really necessary, how much extra traffic and latency is it going to generate. Consider also that you could be generating load on the external site which is unaware all you want is a title, the page creation may be quite expensive.
string title=Regex.Match(new System.Net.WebClient().DownloadString(url),(#"<title>(.*?)</title>"))[0].Groups[1].ToString();
try.i am not sure.
I am not sure whether all servers support this.
See, if this helps
char[] data = new char[299];
System.Net.HttpWebRequest wr =(HttpWebRequest)WebRequest.Create("http://www.yahoo.com");
wr.AddRange("bytes", 0, 299);
HttpWebResponse wre = (HttpWebResponse)wr.GetResponse();
StreamReader sr = new StreamReader(wre.GetResponseStream());
sr.Read(data, 0, 299);
Console.WriteLine((data));
sr.Close();
EDIT: Try checking with some network monitoring tool to find out what is the text that servers send out. I used fiddler to see the output & wrote it to console.
EDIT2: I am assuming the title to be in the beginning of the page.