Can malicious users modify viewstate? - asp.net

If ViewStatemac is enabled in an ASP.NET application can a user modify what is in ViewState and successfully pass it back to the server?
I have an applicaiton (that someone else wrote) that is using what is in ViewState to create an non-parameterized ORDER BY clause in a SQL query. Should I be worried about SQL Injection?

If ViewStateMAC is enabled the attacker would need to be able to crack the "machine key" in order to alter the ViewState, so it should be reasonably secure if this value is kept private.
Is the value set in the code behind (e.g. ViewState["OrderBy"]) rather than via a control? If so this will not be subject to Event Validation.

Yes you can modify the viewstate, and post it back, by simple copy paste the page to a local site as html, and modify it.
How ever on post back the validation will be fail and not accepted by the asp.net if you have open the EventValidation Property - it is open by default.
asp.net saves a hash file for every control and every event on the page on this property, and validate it on post back. If this fail, then is not continue. If you have this close then it can do what you say.
Look this simple html form:
<form name="input" action="someaction.asp" method="post">
<select name="sel">
<option value="1" >Milk</option>
<option value="2" >Coffee</option>
<option value="3" >Tea</option>
</select>
<input type="submit" value="Submit">
</form>
anyone can change the <option value="1" >Milk</option> to <option value="1 OR 1=1" >Milk</option> and post it back as it is, so you need to add a hash code before render it and post it back together with the rest, and validate that the values that is the same (return the same hash).
Some sites, and coders select to encrypt every single value on post back, if you for example see the amazon, you notice lines like:
<input name="offeringID.1" value="y3A0L7tSnS%2B7LBLvI....morehere" type="checkbox" id="fbt_x_check" style="display: none;" class="check" checked="checked">
And you if you use custom html control you need to add your personal validation of the values, to avoid been modified.
asp.net developers have decide to make a total hash values of all controls, and keep it on the EventValidation.
So keep the EventValidation on, and the modification will fail.

Related

Trying to use a select value to save information

I used a select dropdown that is filled dynamically, based on conditions on country>state. But I can not get it out on context for the backend to properly save it to the database (selected value).
I can show the dropdowns correctly and save differently and correctly if I use a asp dropdownlist. Thing is, this code is imported and apparently all I can use if the select value.
<label for="country" class="col-form-label">Country: </label>
<select name="txtAddress_Country" class="countries order-alpha form-control" id="txtAddress_Country" runat="server">
<option value="">Select Country</option>
</select>
<label for="txtPersonal_FirstName" class="col-form-label">State: </label>
In the backend... this function works wonders with dropdownlist and text.
dbCampos.Save(u, new ASF.HC.JobApplication.Entity.Campo("txtAddress_Country", txtAddress_Country.Text));
So I am guessing the place to modify is the frontend.
I am guessing that I am missing some attribute but can not seem to find it. Says that it does not contain a definition for "Text" or accepting a first argument.
Maybe an initial value?
It is better to use instead of html with runat server.
secondly you can try as below:
dbCampos.Save(u, new ASF.HC.JobApplication.Entity.Campo("txtAddress_Country", txtAddress_Country.SelectedValue));
instead of:
dbCampos.Save(u, new ASF.HC.JobApplication.Entity.Campo("txtAddress_Country", txtAddress_Country.Text));

How can I create Simple aspx webpage which will send me parameters in the link

I am trying to do something from scratch in asp
I would like to get something like below. From basic hard coded values.
http://localhost:2478/Default.aspx?phone=905123456&order=123456
After that I want to use this parameter in my variables for SQLquery
I am new to asp.net and vb , I'm learning. Can you please explain me in details? Any helps will be appreciate.
Can you please provide any basic code from where I can start
Based on your latest comments:
<form method="get" action="default.aspx">
<input type="text" name="phone" />
<input type="text" name="order" />
<input type="submit" value="submit" />
</form>
Key points:
method=get (fields are in url instead of body)
note that the form above doesn't have runat=server (more below) - it's a plain HTML Form on plain HTML page
in the context of ASP.Net Web forms, you may run into issues particularly if you are using Master Pages (you can't nest forms, and a Master page is a container for your entire page).
ASP.Net forms do POSTbacks - re: method=post
You can use/add plain forms in an ASP.Net page as long as you don't nest them (outside of the server side ASP.Net form).
If you have no choice (e.g. Master Page), you'll have to construct the Querystring manually after a POSTback, then Response.Redirect to some other target (adding the querystring manually).
there are other non-ASP.Net-y ways of doing it - e.g. javascript, but that a different story

can't turn off ViewState (asp.net/VS2010), what can be wrong?

I'm working on an application which generates a list of customers from a db. I have disabled ViewState in default.aspx, but now when I viewed the source code of the generated HTML page I saw that the ViewState is on.
I've tried to add both ViewStateMode="Disabled" and EnableViewState="False" (separately and even together) without any luck.
What can be wrong?
ViewState code from the source code if it helps:
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="88luWaDvrTt0+OWLhB and a lots of characters after this...
EDIT: Now when I looked again in the source code I can see the following which I find strange:
There's A LOT of ViewState characters (takes 15-20 seconds to scroll through it)
There's two places with ViewState code, separate from each other
ASP.Net pages have both Control State and View State. Control State is for absolutely critical data that the control can't function without (at least in theory).
View State and Control State are both stored in the same field. A site with View State completely disabled may still have Control State.
Unfortunately, ASP.Net is quite inconsistent as to how it differentiates between the two. For example, a DropDownList will no longer fire change events with View State disabled. I consider that a critical function of a drop down and I would be happy to spend the few bytes of space to store the currently selected value in Control State so that a change could be detected.
If you are wondering about the contents of the hidden field containing state, you can decode it. It can be very useful for detecting View State "leaks".
Looking at the MSDN documentation, even when you disable it, it is still used to detect postbacks:
Even if EnableViewState is false, the page might contain a hidden view
state field that is used by ASP.NET to detect a postback.
You can deserialize the viewstate to see who's putting data in there:
LosFormatter lf = new LosFormatter();
object deserialized = lf.Deserialize("!!! YOUR VIEWSTATE HERE !!!");
Attach a debugger and have a look at the contents of deserialized

Post a form from asp to asp.Net

I have a classic asp application. I want to post a contest form from that page to an Asp.Net form. The reason is that I want to use a lot of logic i have built into an Asp.Net page for validation before entering into the database and I don't know asp very well. Not to mention asp.Net being more secure.
What's the best way to accomplish this goal? My thoughts are as follows:
My asp Page:
<html>
<body>
<form action="/Contests/entry.aspx" method="post">
Name: <input type="text" name="fname" size="20" />
Last Name: <input type="text" name="lname" size="20" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
aspx page is running in a Virtual Directory and would handle anything posted to it.
Is this possible, or does aspx prevent this kind of thing?
I ( preferably ) don't want to create the form in aspx as my colleague wants to have control of the page and build the html himself and I don't want the hassle of constantly changing it.
Are there caveats I need to consider?
What roadblocks will I run into?
How do I access the Posted Form Values? Request.Form?
Yes it is possible. In general, a POST is a POST. So you can post from a PHP page to a .NET page if you wanted. You would access the Request.Form variables just as you do now. You will have to look at the ASP Classic page to see the names of the post items but in general, you can access them as if you had pasted from .NET page.
This can be done and works fine. You will access the Posted Form values as you said via Request.Form.
I think the biggest caveat is that you will need to handle invalid data in some way - typically with a webform the .aspx page would be displayed again with validation errors, but that would likely be inappropriate for your circumstance. Probably you will need to redirect them back to the .asp page with query string parameters indicating the failures and the page will need code allowing it to fill in the form fields with their previous values and display the error message.
How about calling an ASP.NET webservice from classic asp?
https://web.archive.org/web/20210125161040/http://www.4guysfromrolla.com/webtech/070302-1.shtml

Viewstate Compression Issues

I'm currently fighting with the .NET Viewstate and it is starting to wear me down. Having found that some of the pages in one of our applications is made up of around 80% viewstate I have looked into reducing this where I can.
I have looked at (and am happy with) disabling viewstate for controls that do not need it (labels, buttons etc) and have made some small gains here.
I'm now looking at viewstate compression and while I can demonstrate a 40-50% decrease in size it does not seem to be playing well with my application.
Scenario:
Page contains a few dropdown lists, a button and a Grdiview (hence the need to deal with the ViewState!). When the page loads the DDLs are populated and default selections are made. Pressing the OK button results in the Gridview being populated as expected.
Now the problem: With Viewstate Compression enabled, if the user changes the selected items in the DDLs before clicking the OK button they will get a 'Required Field Validator' error indicating that a selection has not been made in one of the DDLs - but this is not the case! Disabling the compression code removes the problem and the page operates as expected (i.e. as it has for months!).
Could the problem be down to the viewstate now being stored in a key other than __VIEWSTATE [the code that I have seen use different key names - VSTATE for instance).
My page sources look like this;
Page Source with Compression (note the empty __VIEWSTATE key):
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VSTATE" id="__VSTATE" value="H4sIAAAAAEAO29B2AcSZYlJ
.
.
MKd2afqdaImFR5UiFXVyQPwLPA//8xt+pMsSQ8vlOklcoNgmZfJd8hHvk6/S/7UbxxAJTjzZfp6Qcm039
h3d3dvvPO7/Oa/7i57uemj1H2a/gw5lJQ+ySjFRtPZUL7A/3o2ImFR5UiFXVyLPA+38At70F1EkwAAA=" />
<input type="hidden" name="__VIEWSTATE" id="
__VIEWSTATE" value="" />
</div>
Page Source without Compression:
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTYxOTM1NDg4N
A9kFgJmD2QWAgIDD2QWAgIFD2QWAmYPZBYKAgEPZBYIAgcPZBYCAgMPDxYCHgRUZXh0BRdEYXduQyBbY2hhbm
dlIHBhc3N3b3JkXWRkAgkPFgIeB1Zpc2libGVoFgQCAQ8PFgIfAAUFQWRtaW5kZAIDDw8WAh8ABQUxNDoyNGR
.
.
.
.
.
.
kAgsPDxYEHwAFWVNlbGVjdGVkIFNlcnZpY2UgVXNlcjogPGEgY2xhc3M9J3N1U2VsZWN0b3InIGhyZWY9J2xp
c3RzZXJ2aWNldXNlcnMuYXNweCc+PGI+bm9uZTwvYj48L2E+HwFoZGQCDw8QZGQWAGQCBQ8UKwADZDwrABQEA
BYSHg9QYXJlbnRJdGVtQ2xhc3MFC2lnbW5fUGFyZW50HhdUb3BMZXZlbFBhcmVudEl0ZW1DbGFzcwUTaWdtbl
Ub3BFBhcmVudB4KSlNGaWxlTmFtZWUeFlRvcExldmVsSG92ZXJJdGVtQ2xhc3MFNGlnbW5fVG9wTGV"
/>
</div>
How does .NET know where the VIEWSTATE is stored and does it know that i have moved it?
Do I need to make any other changes to my code apart from implementing SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium?
hey viewstate compression works for me without any problems. basically i have a baseclass for all my aspx pages which use viewstate. even i am using a different viewstate key to save my viewstate. however you have to override 2 methods for this:
1) - to save viewstate
2) - to load viewstate
as long as you are doing this, you should have no problems. see below code which i am using for my baseclass
using System;
using System.IO;
using System.Web.UI;
namespace XC.UI.WebForms
{
public class PageBase : System.Web.UI.Page
{
protected override object LoadPageStateFromPersistenceMedium()
{
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = XC.Common.ViewStateHelper.Decompress(bytes);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateString = writer.ToString();
byte[] bytes = Convert.FromBase64String(viewStateString);
bytes = XC.Common.ViewStateHelper.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
}
}
}
if you are using ajax in your page please change this line of code. It will solve your problem.
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
replace above statement with ScriptManager.
ScriptManager.RegisterHiddenField(this, "__VSTATE", Convert.ToBase64String(bytes));
There is a constant hidden in .NET that holds the viewstate field name. We did compression by hooking in the methods you describe but keeping the viewstate name same without issues.
This may be overkill, but there is a very cool hardware solution to this problem at www.strangeloop.net. No affiliation, just impressed by the technology.
Back to the page tho - what kinds of controls are generating all this viewstate? Grids? You indicated you went over this already, but do watch out for 'unnecessary runats' with tables, td's, tr's, div's, etc. that have runat="server" set. The entire contents of those controls get persisted in viewstate. We recently chopped 40% off our viewstate payload by recognizing a div was client-side and didn't need runat="server".
Compression didnt work for me as it just got it down by 40%. I had 200-300KB ViewStates and was degrading application performance drastically.
I wrote some viewstate substitution technique which replaced it with a GUID token on the page and saved the actual data on server itself in a database.
Here is the code and technique.
http://ashishnangla.com/2011/07/21/reducing-size-of-viewstate-in-asp-net-webforms-by-writing-a-custom-viewstate-provider-pagestatepersister-part-12/
The following answer is not mine, but OP's (that was included in the question). I'm moving it out of the question and making this a community wiki.
I've got to the bottom of this - well almost, I have it working! For some reason using the ClientScript.RegisterHiddenField method appears to have been the source of the problem. Modifying the code to utilise the base class save method, i.e. base.SavePageStateToPersistenceMedium(compressedBytes) and processing the Pair object returned by base.LoadPageStateFromPersistenceMedium() I now have a working solution. Test show a reduction of aroun 70% on the test page so I'm pretty happy with that.
Now that I have compression working I need to recommend that the next (first proper) Code Review has a focus on removing viewstate where it is not needed.

Resources