Link to home
Start Free TrialLog in
Avatar of tfsln
tfslnFlag for New Zealand

asked on

How safe is label text in an asp.net web application?

I need to know whether the following situation is possible...

I have a asp.net label on my web page. This web page displays information about a database record. Said label stores the id of that record so i can refer to the correct database entry back in the server code during postbacks.

My concern is that if i do it this way, someone with malicious intent could potentially modify the html to change the value of the label, so that when they click the Save button, my server side code updates the wrong database entry due to the fact that the label containing the Id was tampered with.

Is this the case? Or will asp.net throw an invalid viewstate error if the client attempts this?
Avatar of bedanand
bedanand
Flag of Nepal image

Instead of label its good to use Hidden field instead.
Avatar of tfsln

ASKER

You're probably right, but i would like an answer to the question regardless.

Thank you.
Check View Source.  Do you see anything that should be 'hidden'/private?  It shoudl be pretty secure.
If You want  the security instead of using any controls. Just put the Id on the viewstate.
Viewstate are secured and encypted so no tempering is possible.

For eg:
ViewState["ID"]= id;


Avatar of tfsln

ASKER

RobertNZana: I dont understand your response. I am familiar with the html source code that is generated by asp.net. Label text's could not possibly be hidden in the html otherwise they would not display, right?

When i view source i can see the text that appears on each label on my form. My question is this; Is there any way for a static label text to be modified outside of the server code, and then posted back to the server so that the server reads the modifed text instead of the original text that was sent out?


bedanand: That is a good idea, and i have other ways of storing the ID securely and so i am not looking for a workaround or solution - i just want to know the answer to my question of whether what i described is possible or not.
I believe they would need access to your server in order to have any type of impact, unless they were manipulating a querystring, or doing sql injection thru a textbox, etc...  But, if you're worried about it why dont you use a session var to store the value?  They are very secure.  Then make the code act upon the session var, which is encrypted.
Avatar of sybe
sybe

> I believe they would need access to your server in order to have any type of impact, unless they were manipulating a querystring

There are Firefox plugins that can manipulate the values of all formfields (even hidden fields). Also Greasemonkey scripts can be used to do things like that.

> when they click the Save button, my server side code updates the wrong database entry due to the fact that the label containing the Id was tampered with

I think that this is mainly an issue of permissions. I suppose your users have to login to change anything in the database (or even have access to mentioned page). This page enables certain people to manage their own content. Of course people could go wild and make their own content unusable, but why should they?

If it is about something like a forum, with many people submitting messages, then make sure that the person who is logged in, is the same person who submitted the original message (so you can only edit your own messages).
Confusion
There seem to be some misconceptions about in this thread. A Label is not a member of the form post family (it is not an input or select element). Hence, it is not send back to the server in the postback event.

Whether your page is secure or not, whether you have viewstate enabled or not, or event validation. Whatever is inside that label: illegal characters, nice numbers, an SQL injection select statement or pink elephants, the server will not see them as they are not sent. End of story.

Background:
An ASP:Label is typically rendered as a span html element. Unless you have created your own control which contains some hidden elements, the data will be pure HTML and will not become part of the HTTP POST collection, or the GET querystring parameters on submit. Using an ASP:Hidden element for the ID of a record is far more dangerous than using an ASP:Label, be it display:hidden or not. The Hidden element will be sent through the HTTP Post collection and can be tampered with (which will not throw a validation exception, so you cannot do much about it). The Label will not and cannot be tampered with.

Does this mean that an ASP:Label is a safe way of storing the ID of a record? No, not really, because the user can see the ID and might be able to exploit that information in another way. If you do not want your user to see the ID, then you should not show it. But that's trivial.

[side note: A common practice is to use a Communication-ID and a Storage-ID. The latter is internal use only, the first is used for communication with clients (through mail, web site etc). Both are unique, but the Storage-ID is your autonumber field with foreign key relations and may contain gaps, the Communication-ID is updated following the rules of your Financial Controller and local Tax authorities (or whatever rule applies for you) and does not contain gaps]

On the server side, the content of the label is remembered in something similar to the session state. This is done by the ASP.NET library and is beyond your control (well, not entirely, but it is 100% server side and not your concern).
Try it yourself:
The code below is a simple situation where a user can tamper with the value of a Label (click on it to add 10). After submitting the value, the original value is used by the server and the original value is raised with 1. Try it out by adding a webform to your project and calling it PostBackTest.aspx.

<%@ Page Language="C#" AutoEventWireup="true" 
	EnableViewState="true" 
	EnableEventValidation="true"
	EnableViewStateMac="false"
	CodeBehind="PostBackTest.aspx.cs" 
	Inherits="WebApplication1.PostBackTest" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
		<p>Click on the red label to update label value. 
		Click on 'add 1' to see whether this effects the postback counter</p>
		<asp:Label runat="server" ID="myLabel" 
			Text="24" onclick="this.innerHTML = 20 + (this.innerHTML * 1);"
			style="background-color:red" />
		<asp:Button runat="server" Text="add 1" />
    </div>
    </form>
</body>
</html>
 
 
 
//////////////////////////////////////////
// CODE BEHIND
//////////////////////////////////////////
 
using System;
 
namespace WebApplication1
{
    public partial class PostBackTest : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            myLabel.Text = (int.Parse(myLabel.Text) + 1).ToString();
        }
    }
}

Open in new window

>>>Viewstate are secured and encypted so no tempering is possible.
ViewState is not a safe place for storing sensitive information because it is only Encoded, not encrypted. Anyone can decode the ViewState to see what is in there. You will need to add custom code to encrypt ViewState.
All server controls on a form will be posted back to server, it is how ASP.NET mantain the control's state. Server keeps the original states of all controls, then upon postback, server compare the stored states to the posted states to determine what action to take.
Use Session to store mission-critical or sensitive information.
 
@prairiedog, sorry but the following statement is not correct:

"All server controls on a form will be posted back to server, it is how ASP.NET mantain the control's state. "
only server controls that van receive user input (or can receive input in another way) are posted back to the server. I.e., an asp:Label and an asp:Literal are server controls, but they are not posted back. On the contrary, asp:Button, asp:TextBox and asp:ListBox are posted back.

This means that:

"then upon postback, server compare the stored states to the posted states to determine what action to take."
is only true for elements that contain editable information. Which again an asp:Label is not.

This is easily tested by running the page I showed on a test environment. You can test all HTTP headers using some HTTP Sniffer to be sure. You can inspect the created HTML etc, you will find that many controls, including asp:Label do not post data back to the server.

Even if you set EnableViewState to true on the asp:Label, this behavior will not change. Nor will this data automatically end up in the viewstate. You can easily test that the same way.

So back to the original question: can you tamper with an asp:Label: yes. Is the data you read out of the label text (in page_load or whatever) reliable: yes. Because tampering is nice but will have no effect on what is sent to the server.
ASKER CERTIFIED SOLUTION
Avatar of prairiedog
prairiedog
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> If a Label is not posted back, then how does ASP.NET maintain the Label's view state, or the Label's hierarchy?

You are right, it does that in the viewstate, apologies, I got drifted away. My statement however holds: by setting a value in the asp:Label and setting its viewState to false, will keep that value (because you knew that value in the first place). It is "kept" in the form_load of wherever.

If you set the viewstate to true, and the data is tampered with, it must be tampered with in the viewstate. You can protect this tampering to a higher level by setting EnableViewStateMac to True. This is an encryption method, not only an encoding, quote:

A view-state MAC is an encrypted version of the hidden variable that a page's  view state is persisted to when sent to the browser.
So, the viewstate is send back to the server. You can protect it, but it can be tampered with. Advice in the case of wanting to rely on the value of a label is to set its envableviewstate to false.

(wondering why my comparison of the viewstate earlier today showed nothing... apologies again for jumping too quickly to conclusions here)
>>>My statement however holds: by setting a value in the asp:Label and setting its viewState to false, will keep that value (because you knew that value in the first place). It is "kept" in the form_load of wherever.
Just want to clarify that it only happens if you set the value in ASP:Label's HTML markup. If you have a Label whose value will be changed in code-behind, you will need to set EnableViewState=True, otherwise, you will lose the value upon postback.
Agree that ViewState is tamper-protected (ASP.NET will throw exception if attempt of tempering ViewState is detected), but it does not mean it is a good and safe place to store sensitive information. For example, if you store someone's SSN in the ViewState, although the value of SSN can't be tampered, but it is visible to anyone.
clear. But the question was about whether a label can be used for data. If you use a label, you show it already. And if you use a label without enableviewstate, it can be used without security problems.
>>>If you use a label, you show it already.
You can use a hidden label to store data (Visible=False). For example, you can store a record's primary key in a Label with Visible=False and EnableViewState=True. The data stored in this kind of Label is persisted in ViewState and is accessible to the code-behind functions, but it will not be rendered to HTML because Visible=False, and you will not see it in page source. However, the assumption is, in this example, that the record's primary key is not sensitive.
Avatar of tfsln

ASKER

Thank you abel you have provided me with the information i was looking for.

So as it turns out, storing data in a label is actually reasonably secure in the sense that it cant be modified by the client? So ideally i wouldnt store the actual database id in there, just a generated id that is linked internally to the actual database id (via session state maybe)? But the question that you seem to have answered is that said generated id on the label can not be tampered with and there is no way that you are aware of that someone can change the value, and have the server recognize the new value when the page is posted back?
Avatar of tfsln

ASKER

Actually upon reading again maybe i got it wrong... So you're saying that the label is secure if its EnableViewState property is False (but as prariedog said, it wouldnt remember its value for roundtrips which would render it useless for storing an id).

But then again... if the label's EnableViewState=True, it should be secure anyway because asp.net will detect if the viewstate has been modified and will throw an invalid viewstate exception.

Is this correct?

As a side note... Having the users know the database id of their records is of no concern to me. If a user knows the id of the record they are dealing with, it doesnt help them at all to gain access to the database. Its just a field in a table just like their name and email address.
>>>Is this correct?
Yes. But keep it in mind that invalid ViewState exception can be caused by other factors, and ViewState tamper is just one of them.
As far as storing data in ViewState, please read my last comment (http://23923049). The bottom line is if the data stored in ViewState is not sensitive, then you can do it with ViewState. I suggest you read the following articles on ViewState to better help you understand ASP.NET ViewState:
http://msdn.microsoft.com/en-us/library/ms972976.aspx
http://authors.aspalliance.com/PaulWilson/Articles/?id=7
http://msdn.microsoft.com/en-us/magazine/cc188774.aspx
http://msdn.microsoft.com/en-us/library/ms972427.aspx
 
To clarify, ViewState is very well tamper-protected (as long as you keep Page.EnableViewStateMac = True, which by default is True) no matter EnableViewState is True or False, because it has nothing to do with it.
> but as prariedog said, it wouldnt remember its value for roundtrips which would render it useless for storing an id

partially true. If you set the value in, say, the Page_Load and you use it somewhere later in your code, it will "feel" like it is there.

If your code references it and updates it (like in my example above) it will not update after the first roundtrip if EnableViewState is off.

I agree fully with prairiedog who pointed me to a hastily and thoughtless error in my story. A Label is save in the way that if the label value is changed on the client side, you will not see that change (see my example code). Simple tampering will have no effect. However, relying 100% on any data from a browser (or whatever client) is something that's not good. Using the ViewStateMac is a good thing. You need to store accessors somewhere. Using a record ID is a bad thing, using a client-viewable ID is a good thing (like an SSN, but only on a secured site, or a ordernumber, these things just need to be visible for the reader of your page).
> no matter EnableViewState is True or False, because it has nothing to do with it.

I missed that bit. Not sure what prairiedog means here. But if you switch EnableViewState off, changed values (again, see my example code) will not stay. The number displayed will always be "25" (24 + 1), while with EnableViewState=true is would increase.

In all cases, still: changing the value by hand and submitting: that is something that is not send to the server, only the viewstate string is used.
Avatar of tfsln

ASKER

> However, relying 100% on any data from a browser (or whatever client) is something that's not good.

While i agree... I just want to be clear. Didnt you say that a label, since it is not a user-input control, is never sent back during postbacks. I mean, the label text is not stored in the viewstate, its stored internally like a session variable - so it wouldnt matter what they did with it, it will always be the same value as what it was when the page was sent out to the client?

In that case, how can it not be secure?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tfsln

ASKER

This is excellent information, i really appreciate it. Just want to clarify...

Lets say viewstate is enabled for the page and the label, and i havent specifically turned off EnableViewStateMac. Basically, a completely default setup.

Under these circumstances, it sounds like what your saying is that it would be extremely difficult for a hacker to modify the contents of an asp:label and have those modified contents posted back to the server so that the server-side code see's the modified label text and not the original that was sent out?
I have yet to see it happening. The EnabelViewStateMac will be on and that means that SHA1 is used. I have seen several hacker attempts on several sites but so far I have only seen them failing. It takes a long time and strong computers + smart software to decrypt SHA1 and then you're not done yet...

If your application is about a banking application, I would choose a different approach all in all, but that's another story.
Avatar of tfsln

ASKER

Yeah i understand. This is great, thanks for your time.
>>>Under these circumstances, it sounds like what your saying is that it would be extremely difficult for a hacker to modify the contents of an asp:label and have those modified contents posted back to the server so that the server-side code see's the modified label text and not the original that was sent out?
Actually, your sever-side code will not see the modified label text at all if a tamper attempt is detected. The reason is simple: ASP.NET framework will catch the tamper in the request and will not continue. You can test it by adding a try/catch block in your code behind and will find the try/catch will not be executed when tamper is detected.
Tx for the points, but....shouldn't you have given some points to prairiedog too, after all, he corrected me and helped me in the right direction.
Avatar of tfsln

ASKER

Yeah i should have... I didnt think about it until i had assigned the anwer but i did feel bad about that. Am i able to change it? Or is it too late?
You can file a request by using the "Request Attention" link next to your question and ask the moderators kindly to reopen the question, plus the reason why. Once reopened, you can reassign the points.
Avatar of tfsln

ASKER

Cool, done!
>>>but i did feel bad about that.
Don't feel bad.
It really does not matter that much to me as far as the points are concerned. Answering questions here help me learn more things and remember what I have learned.
Avatar of tfsln

ASKER

I understand, but im still keen to assign the points correctly - i like to give credit where credit is due