Monday, December 28, 2009

Secure values stored in hidden fields

It is a common practice to store values in hidden fields when items are edited. Value like id are a common candidate for these operations. Most times modifying these values from client side by script can be dangerous. Here we will look for a solution where in the complete set of values which we have to store and avail on postbacks be saved in a secure way.

The suggested solution is as follows.

First we will define a dictionary which can hold string key value pairs. We will also provide methods for storing and retrieving these values.

private string _KeyStoreName = "__KeyValueStore__";
private Dictionary<string, string> _KeyValues = new Dictionary<string, string>();
public void SetKeyValue(string name, string value)
{
   if (_KeyValues.ContainsKey(name))
    _KeyValues[name] = value;
   else
    _KeyValues.Add(name, value);
}
public string GetValue(string name)
{
   if (_KeyValues.ContainsKey(name))
    return _KeyValues[name];
   return "";
}

public Dictionary<string, string> GetKeyValues()
{
   Dictionary<string, string> keyVals = new Dictionary<string, string>();
   foreach (string key in _KeyValues.Keys)
    keyVals.Add(key, _KeyValues[key]);
   return keyVals;
}

On pre-render, we will serialize the dictionary and encrypt it. This value will be stored in a hidden field which will be generated dynamically.

protected override void OnPreRender(EventArgs e)
{
   StringWriter sw = new StringWriter();
   los.Serialize(sw, _KeyValues);
   string valueToStore = sw.GetStringBuilder().ToString();
   // Encrypt valueToStore to make it secured.
   HtmlInputHidden hid = new HtmlInputHidden();
   hid.ID = _KeyStoreName;
   hid.Name = _KeyStoreName;
   hid.Value = valueToStore;
   Page.Form.Controls.Add(hid);
   base.OnPreRender(e);
}

On pre-init, we will retrieve the hidden field value, decrypt it and deserialize it.
protected override void OnPreInit(EventArgs e)
{
   string storedValue = Request.Form[_KeyStoreName];
   if (!string.IsNullOrEmpty(storedValue))
   {
    // Decrypt storedValue, if you have encrypted it.
    LosFormatter los = new LosFormatter();
    _KeyValues = los.Deserialize(storedValue) as Dictionary<string, string>;
   }
   base.OnPreInit(e);
}

Happy coding!!!

1 comment:

  1. WOW!!!!! saved my day ...... Thank you.

    I used the idea to store the selected values for a dynamically generated radiobuttonlist and restore them back between postbacks ...Thank you

    ReplyDelete