Stop the user entering ' char - asp.net

I have a search page where I would like to stop the user entering a ' into textboxes, or replace it with a suitable character. Can anyone help me achieve this in asp.net vb ?
For example if a user searches for O'Reilly the search crashes with error:
Line 1: Incorrect syntax near 'Reilly'. Unclosed quotation mark before the character string ' '.
Thanks!

Use parameterized statements properly, and this will be handled for you.

Uh-oh. Use parameterized queries.

Use javascript onKeyDown event for the textbox - if the typed char is an apostrophe, you can simply drop it, so that it is not entered.
On the server side, you should simply replace "'" with "", just to make sure.
Be aware, that this is a very unsecure and unstable solution.

You can escape ' character with two of them '', e.g.
sql += "Surname LIKE '%" & name.Replace("'", "''") & "%' AND "
and SQL will accept it then.
However, I would suggest using parameters.

To actually answer the question, you can put an OnKeyDown javascript event on your textbox, detect the key that was pressed, and potentially cancel the input:
<input class="mainSearchBox" type="text" id="searchTerm" onkeydown="DetectIllegalKeys();">
<script>
function DetectIllegalKeys() {
if (event.keyCode == 222) {
event.returnValue = false;
}
}
</script>
to instead change apostrophes to an alternate character:
<input class="mainSearchBox" type="text" id="searchTerm" onkeyup="ChangeSingleQuote();">
<script>
function ChangeSingleQuote() {
var searchTerm = document.getElementById('searchTerm');
searchTerm.value = searchTerm.value.replace(/'/g, "e");
}
I highly recommend that you not use this approach for this problem!
Far better to fix the application to allow searches for titles of any character string.

You need to understand why the error occurs and not just solve it symptomatically. Read through Microsoft's own document about SQL Injection to find out how to protect yourself from this class of security flaws.
http://msdn.microsoft.com/en-us/library/ms998271.aspx
(As several others pointed out, parameterized statements is the solution.)

Related

asp.net read classic asp cookie

I seem to be having a lot of issues reading a cookie from an old classic asp web application. we are slowly upgrading this web app to .net. The cookie holds some user information which also is used to tell the app that the person has authenticated successfully.
I try and read it like so:
Response.Cookies["mycookie"].Path = "/";
string strCookieText = Request.Cookies["mycookie"].Value;
Sometimes it seems to bring data back other times not but it is not consistent. I have also tried applying the same path when the cookie is created on the classic asp side but that seemed to really throw a wrench in the old app as then the classic asp side had a lot of challenges reading and finding the cookie.
So i figured i would create a function that would read in a classic asp page whos sole intent is to read the cookie. I don't like this method at all but I am out of ideas at this point. The issue here seems to be that it always comes back empty. I know there is data there however via fiddler and if i go to the actual site and hit the page. I am guessing this must be some pathing issue again perhaps or something like that that when i try and read it via .net it finds nothing.
here is my funciton that trys to read the page:
public CCookie validateCookie()
{
CCookie ckCCookie = new CCookie();
string strReadCookiePage = "";
strReadCookiePage = GetHtmlPage("HTTP://MYPAGE/readcookie.asp");
string[] strCarriageReturn = { "\n" }; //we are splitting on this character
string[] strPageSplit;
strPageSplit = strReadCookiePage.Split(strCarriageReturn, StringSplitOptions.RemoveEmptyEntries);
string strCookieLength = "-2";
foreach (string strValue in strPageSplit)
{
if (strCookieLength == "-1")
{
break;
}
if (strValue.Contains("<div id='arrayLength'>"))
{
strCookieLength = findStringValue(strValue, "<div id='arrayLength'>", "</div>");
}
if (strValue.Contains("<div id='VendorID'>"))
{
ckCCookie.UserVendorID = findStringValue(strValue, "<div id='VendorID'>", "</div>");
}
if (strValue.Contains("<div id='UserID'>"))
{
ckCCookie.UserID = Convert.ToInt64(findStringValue(strValue, "<div id='UserID'>", "</div>"));
}
if (strValue.Contains("<div id='LogonType'>"))
{
ckCCookie.LogonType = findStringValue(strValue, "<div id='LogonType'>", "</div>");
}
if (strValue.Contains("<div id='UserType'>"))
{
ckCCookie.UserType = findStringValue(strValue, "<div id='UserType'>", "</div>");
}
}
//not able to validate the cookie
if (strCookieLength == "-1")
{
//Response.Redirect("REDIRECT TO HAVE THEM LOG IN");
}
return ckCCookie;
}
why isn't this working do you guys think. I need this to consistently work. I know i could save state to dbase but I don't want to do this this way as I think i should be able to read this thing.
any ideas or thoughts on how to make this work?
Because of the way that cookies are stored they generally can't be shared between apps, like Classic ASP to ASP.NET.
I did find this article on MSDN that discusses solutions to the problem.
Personally, I would use a hidden field method to pass the cookie over, picking it up from the relevant control on the other side (ASP.NET).
-- EDIT --
Just so long as the hidden control resides in you form tags, you can try something like this (which is pretty much what ASP.NET does for it's __VIEWSTATE)...
<form id="myForm" method="post" action="myAspNetPage.aspx">
<all_the_controls_i_need_on_my_form>
...
...
</all_the_controls_i_need_on_my_form>
<input id="cookieData" name="cookieData" type="hidden" value="<%= cookieData %>" />
</form>
The VBScript...
Dim cookieData
cookieData = Request.Cookie("MyCookie")
Obviously if you have several cookies that you want to pass in this way then you may need to concatenate them for splitting later...
Const C_SEPERATOR = "|"
Dim cookieData
cookieData = _
"MyCookie1=" & Request.Cookie("MyCookie1") & C_SEPERATOR & _
"MyCookie2=" & Request.Cookie("MyCookie2") & C_SEPERATOR & _
"MyCookie3=" & Request.Cookie("MyCookie3") & C_SEPERATOR & _
"MyCookie4=" & Request.Cookie("MyCookie4")
The above example could obviously be automated by introducing a For..Next loop, but this is simply an example. Note, also, that I have simply taken for granted that none of your cookies use the vertical bar character (C_SEPERATOR); if they do, then you'll have to find an alternative character.
On the other side, in your ASP.NET app you can the read the value from the post data and split it up...
Private Const C_SEPARATOR = "|"
...
...
Dim tCook As String = Request.Form("cookieData")
Dim cookeiData() As String
If tCook<>"" Then cookieData = String.Split(tCook, C_SEPERATOR)
It's not the best solution - I'm sure that Lankymart will have something far better up his sleeve, but this will work.
PS: Apologies - I've just realised that I've done all this in VBScript. It should be pretty straightforward to convert to JScript, though.

query string parameter without value, only key

i have question about query string in asp.net:
standart query string with query string parameter is "www.mysity.url?key1=value1&key2=value2", but i need only check has query string key or not...yes, one of the correct decisions: www.mysite.url?reset=true, but this excess syntax for me.
in markup i use something like "<a href='UrlHelper.GetResetUrl()'>Reset</a>", this method return "www.mysity.url?reset", but in user side markup i have "Reset"
If you do not specify the name for a parameter it is taken as null.
Its value would be reset
So you would have to check it as follows:
if(Request.QueryString[null]=="reset")
{
//Take some reset action
}
a Quick and dirty solution is:
if(Request.Url.Query.Contains("?reset"))
{
// ok we have a reset
}
Assuming that you have a standard reset call ask as: www.mysity.url?reset and the reset url not have other parameters. If you have you can simple check for the reset keyword.
This code HttpContext.Current.Request["reset"] is always return null, so the next best thing if you like to make it hard, is to manual analyze your keys after the url.
All code that handles querystring parameters should be case insensitive. Browsers (or parts of internet infrastructure?) may convert the case.
One way to check if reset parameter is present in querystring:
bool reset = Request.Url.Query.IndexOf("reset", StringComparison.CurrentCultureIgnoreCase) > -1;

Password and confirm password

I have a password and confirm password field and I dont want the user to simply copy from the first field and paste in the later field.What should I do for this??
Copy functionality is usually disabled for password-type fields, so you don't need to do anything. There is nothing to stop a user pasting the same text into both fields from elsewhere, however, and there isn't a lot you can do about it. Trying to prevent this would stop some users who want to be sure they have their password right from pasting it in, as well as users that use password generators.
Here is a way...
<asp:TextBox ID="txtEMailVerifyJoin" runat="server" ClientIDMode="Static"
autocomplete="off"
onpaste="pasteEvent('reg_conf_email');return false;"
onkeydown="disablePaste('pasteEvent()','reg_conf_email');"
onkeyup="disablePaste('pasteEvent()','reg_conf_email');"
oninput="disablePaste('pasteEvent()','reg_conf_email');"
></asp:TextBox>
And for javascript
<script>
var charCount = document.getElementById("txtEMailVerifyJoin").value.length;
var oldVal = eval(document.getElementById("txtEMailVerifyJoin")).value;
function disablePaste(methodToCall)
{
newCharCount = document.getElementById("txtEMailVerifyJoin").value.length;
oldCharCount = charCount;
charCount = newCharCount;
if(newCharCount - oldCharCount > 1)
{
eval(methodToCall);
charCount = oldVal.length;
}
else
{
oldVal = eval(document.getElementById("txtEMailVerifyJoin")).value;
}
}
function pasteEvent()
{
document.getElementById("txtEMailVerifyJoin").value=oldVal;
return false;
}
function initDisablePaste()
{
charCount = document.getElementById("txtEMailVerifyJoin").value.length;
oldVal = eval(document.getElementById("txtEMailVerifyJoin")).value;
}
initDisablePaste();
</script>
Its not mine idea, if I find where I see it I will post it here.
See it live here: Join Athineon remove it.
this command works (for this page) on the Confirm email address ! (not for the password)
About the user interface and if this is a good idea, I make a question here: https://ux.stackexchange.com/questions/1488/wondering-if-i-must-let-a-user-copy-paste-the-double-asking-confirm-e-mail-on-the
simple in the password mode user cannot copy the text and cannot paste it in other text box.
so your problem get solved .give the both the textBox in password mode
There is no effective way to stop this that works on all browsers. Even if such a solution existed, a user could just disable JavaScript and just copy and paste if desired. Most users won't copy and paste though, as it's for their own benefit and is to prevent mistakes.
...If there is no way , use this COMPLEX but 100% SECURE classic method:
Declare a variable and on each keypress store the last letter of the textbox in the variable.Then replace textbox's last symbol with <*> symbol.
But then you must write another parts of code for BackSpace and Delete keys to remove letters...
Simple Method Its really working <asp:CompareValidator runat="server" ID="Comp1" ControlToValidate="id" ControlToCompare="ID2" Text="Password mismatch" Font-Size="11px" ForeColor="Red" />
id1 for add your password text box ID
id2 for add your confirm password text box ID

Allowing dangerous query strings

I need to be able to allow query strings that contain characters like '<' and '>'. However, putting something like id=mi<ke into the the URL will output an error page saying:
A potentially dangerous Request.QueryString value was detected from the client (id="mi<ke").
If I first url encode the url (to create id=mi%3Cke) I still get the same error. I can get around this by putting ValidateRequest="false" into the Page directive, but I'd prefer not to do that if at all possible.
So is there anyway to allow these characters in query strings and not turn off ValidateRequest?
EDIT: I want to allow users to be able to type the urls in by hand as well, so encoding them in some way might not work.
I ran into a problem similar to this. I chose to base64 encode the query string to work around it.
using
System.Text.ASCIIEncoding.ASCII.GetBytes
to get the string as bytes
and then
System.Convert.ToBase64String
to turn it into a "safe" string.
To get it back, use:
System.Convert.FromBase64String
and then:
System.Text.ASCIIEncoding.ASCII.GetString
to reverse the polarity of the flow.
A little googling and I don't think so.
The exception seems to happen before your code even runs so you can't trap the exception.
I like the encoding as base64 or something idea.
Instead of URL encode, you could encrypt your id value to get around the issue. You will probably then need to URL encode the encrypted string.
I think you have some options. You could do as you indicate and turn off ValidateRequest. You would then need to take care of any input sanitization on your own. Or you could allow only certain characters and either have the user use a meta language to input them, i.e., instead of '<' use '[' and replace '>' with ']' or re-encoding these before submission yourself to the meta language (or Base64). Doing the re-encoding yourself would require Javascript be available for queries that used forbidden characters. You may still need to do input sanitization.
Quick stab at a jquery implementation:
$(document).ready( function() {
$('form').bind('submit', function() {
$('form' > 'input[type=text]').each( function(i) {
if (this.value) {
this.value = encode(this.value);
}
});
});
});
function encode(value) {
return ...suitable encoding...
}
I was working with the same problem, however i stumbled upon this javascript encoding method:
<script type="text/javascript">
var unencodedText = "This is my text that contains whitespaces and characters like and Ø";
var encodedText = "";
var decodedText = "";
alert('unencodedText: ' + unencodedText);
//To encode whitespaces and the 'Ø' character - use encodeURI
encodedText = encodeURI(unencodedText);
//We see that whitespaces and 'Ø' are encoded, but the '' is still there:
alert('encodedText: ' + encodedText);
//If we decode it we should get our unencodedText back
decodedText = decodeURI(encodedText);
alert('decodedText: ' + decodedText);
//To also encode the '' we use the encodeURIComponent
encodedText = encodeURIComponent(unencodedText);
//Now all the characters have been encoded:
alert('encodedText: ' + encodedText);
//To get our unencodedText back we now need to use the decodeURIComponent
decodedText = decodeURIComponent(encodedText);
alert('decodedText: ' + decodedText);
</script>
If you're dealing with more complicated symbols then you might want to use the encodeURIComponent for the url.
And i steal this gem from this link.

Force ASP.NET textbox to display currency with $ sign

Is there a way to get an ASP.NET textbox to accept only currency values, and when the control is validated, insert a $ sign beforehand?
Examples:
10.23 becomes $10.23
$1.45 stays $1.45
10.a raises error due to not being a valid number
I have a RegularExpressionValidator that is verifying the number is valid, but I don't know how to force the $ sign into the text. I suspect JavaScript might work, but was wondering if there was another way to do this.
The ASP.NET MaskedEdit control from the AJAX Control Toolkit can accomplish what you're asking for.
I know an answer has already been accepted, but I wanted to throw out another solution for anyone with the same problem and looking for multiple workarounds.
The way I do this is to use jQuery format currency plugin to bind user input on the client side. Parsing this input on the server side only requires:
// directive
using System.Globalization;
// code
decimal input = -1;
if (decimal.TryParse(txtUserInput.Text, NumberStyles.Currency,
CultureInfo.InvariantCulture, out input))
{
parameter = input.ToString();
}
The only downfall to this is that the user can have javascript turned off, in which case the RegEx validator running server-side would work as a fall-back. If the control is databound, all you have to do is decimalValue.ToString("{0:c}") , as mentioned by others, in order to display the proper currency formatting.
The cool thing about this is that if the user enters the textbox and it shows $0.00 on the client side, the server-side if statement would return false. If your decimal value isn't nullable in the database, just change decimal input = -1 to decimal input = 0 and you'll have a default value of 0.
Another way to do this might be to place the dollar sign outside to the left of the text box. Is there a real need to have the dollar sign inside of the box or will a simple label do?
decimal sValue = decimal.Parse(txtboxValue.Text.Trim());
// Put Code to check whether the $ sign already exist or not.
//Try making a function returning boolean
//if Dollar sign not available do this
{ string LableText = string.Format("{0:c}", sValue); }
else
{ string LableText = Convert.ToString(sValue); }
string sValue = Convert.ToString(txtboxValue.Text.Trim());
// Put Code to check whether the $ sign already exist or not.
//Try making a function returning boolean
//if Dollar sign not available do this
{ string LableText = string.Format("{0:c}", "sValue"); }
else
{ string LableText = Convert.ToString(sValue); }
In the .CS you could do a pattern match along the lines of,
string value = text_box_to_validate.Text;
string myPattern = #"^\$(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})|\d{1,3}(\.\d{2})|\.\d{2})$";
Regex r = new Regex(myPattern);
Match m = r.Match(value);
if (m.Success)
{
//do something -- everything passed
}
else
{
//did not match
//could check if number is good, but is just missing $ in front
}

Resources