I have a fortify result saying that the following line needs a secret to prevent CSRF
<form id ="form1test1" runat="server">
I have a random GUID being generated on Page Load, I want to compare it, when the form posts.
I have seen in classic asp putting the token in the action as a query string
I am trying:
<form "form1test1" runat="server"
action='<%# string.Concat(Eval("login.aspx/?Token="),"",Eval(Session["Token"].ToString()))%> '> >
Best I get is a print out of the text but not the values, not doing this in the code behind does not fix the finding in fortify
trying for something like
<form "form1test1" runat="server" action="login.aspx/?Token=12345DEF">
A better way to prevent CSRF attacks (it's working on my projects), is to implement it in your master pages, like this:
Add new Class that will handle the CSRF Validations for you:
public class CsrfHandler
{
public static void Validate(Page page, HiddenField forgeryToken)
{
if (!page.IsPostBack)
{
Guid antiforgeryToken = Guid.NewGuid();
page.Session["AntiforgeryToken"] = antiforgeryToken;
antiforgery.Value = antiforgeryToken.ToString();
}
else
{
Guid stored = (Guid)page.Session["AntiforgeryToken"];
Guid sent = new Guid(antiforgery.Value);
if (sent != stored)
{
// you can throw an exception, in my case I'm just logging the user out
page.Session.Abandon();
page.Response.Redirect("~/Default.aspx");
}
}
}
}
Then implement this in your master pages:
MyMasterPage.Master.cs:
protected void Page_Load(object sender, EventArgs e)
{
CsrfHandler.Validate(this.Page, forgeryToken);
...
}
MyMaster.Master:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:HiddenField ID="forgeryToken" runat="server"/>
...
</form>
Hope you'll find this useful.
Related
I have a ASP.NET page called customer.aspx which has a user control customerdetails.ascx inside of it. This user control reads data from the database and populate some fields. If the loading is successful (if there is some data), the user should stay on the page. Otherwise the page should be redirected to a different page. This redirection is done in the container customer.aspx page and not in the control.
What are the ASP.NET page cycle events (Page_Load Vs Page_Init) that I should use for customer.aspx and customerdetails.ascx for the above logic to work?
If you've established that both options work functionally, then, for performance, you should prefer Page_Init.
If you might end up with a redirect, then you want to give the server the chance to do that redirect as soon as possible in the page lifecycle, to avoid using resources on lifecycle steps that might not be necessary.
I was rereading this - https://web.archive.org/web/20210330142645/http://www.4guysfromrolla.com/articles/092904-1.aspx, old, but good. I think you should be able to do what you need from the Page_Load event of customer.aspx because user controls are loaded by then. simply check the user control's controls for values and redirect, or not.
edit:
Actually, I think it depends. controls prob have to be preloaded, which changes things.
If we need our dynamically added controls to maintain their view state it is paramount that these controls be added before the Load View State stage. That is, these controls must exist within the page's control hierarchy before the view state is loaded. There's only one stage before Load View State - Initialization. That means, if we want our dynamic controls to persist view state we must add them to the control hierarchy in the page's Init event.
One way to make the user control accessible (answer at bottom): https://forums.asp.net/t/1674095.aspx?Loop+through+User+Controls+in+Content+Page
edit:
User Control
<h4>The User Control</h4>
<div>
<asp:Label ID="lblUserCtrl" runat="server" Text="Label"></asp:Label>
</div>
.cs
public partial class Testing_Controls_TestCtrl : System.Web.UI.UserControl
{
// public properties
public Label lbl
{
get { return lblUserCtrl; }
set { lblUserCtrl = value; }
}
public bool isLoaded;
// end public properties.
protected void Page_Init(object sender, System.EventArgs e)
{
lblUserCtrl.Text = "User ctrl loaded at: " + DateTime.Now;
isLoaded = true;
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
container page:
note: I still had to register the control even though I loaded it from code.
<%# Register Src="~/Testing/Controls/TestCtrl.ascx" TagPrefix="uc1" TagName="TestCtrl" %>
...etc...
<form id="form1" runat="server">
<h4>The Container Page</h4>
<div>
<asp:Label ID="lblContainerLabel" runat="server" Text="Label"></asp:Label>
</div>
<br />
<hr />
<asp:PlaceHolder ID="ph1" runat="server"></asp:PlaceHolder>
</form>
.cs
public partial class Testing_user_control_test : System.Web.UI.Page
{
private bool ucIsLoaded;
protected void Page_Init(object sender, System.EventArgs e)
{
Testing_Controls_TestCtrl c = (Testing_Controls_TestCtrl)Page.LoadControl("~/Testing/Controls/TestCtrl.ascx");
ph1.Controls.Add(c);
c.lbl.Text += "<br />This is text appended to the user control by the container page.";
ucIsLoaded = c.isLoaded;
}
protected void Page_Load(object sender, EventArgs e)
{
lblContainerLabel.Text = "Container page loaded at: " + DateTime.Now + "<br />The user control is loaded: " + ucIsLoaded.ToString().ToUpper();
}
}
I'm creating a website which allows users to log in. After logging in successfully, user's name should be displayed across each page, for example, at the top right corner. I have a ContentPlaceHolder on Master Page. An h3 tag would then be created and added into this ContentPlaceHolder.
Master Page:
<asp:ContentPlaceHolder runat="server" ID="UserNamePlaceHolder">
</asp:ContentPlaceHolder>
Login Page:
<%# MasterType VirtualPath="~/Master" %>
Login Class:
protected void Login_LoggedIn(object sender, EventArgs e)
{
ContentPlaceHolder userNamePlaceHolder =
(ContentPlaceHolder)Master.FindControl("UserNamePlaceHolder");
var h3 = new HtmlGenericControl("h3");
h3.InnerHtml = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
I did debugging step by step. Nothing went wrong: no null or empty value, each variable was created. However, the user name was not displayed at all. Does anyone have an idea?
A cleaner and better approach would be to create a public property on the Master page:
public string UserName
{
get
{
return Literal1.Text;
}
set
{
Literal1.Text = value;
}
}
That's it place the literal with ID Literal1 anywhere you want on the master page:
<asp:Literal runat="server" ID="Literal1" />
You are already adding Master directive for strongly typing Master class, so now your login class would look like this:
protected void Login_LoggedIn(object sender, EventArgs e)
{
Master.UserName = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
Hope this helps.
I have a web page that uses single user control and a asp:repeater that uses the same user control and both are created in Page_Load. Both bahave differently in a submit button clicking event. The binding event for each of the repeater (depdentBasicInfo)'s user control is called after submit button clicking before page_load. But the binding event is not for the single user control (spouseBasicInfo). Why? Also the user control create a runtime control (assuming a TextBox). I found there is no way to retrieve the runtime control's Text property after clicking the submit as the control becomes null after PostBack. How to retrieve the property easily? Could any one help me? Thanks.
<!--USER CONTROL -->
<asp:Panel runat="server" ID="PnlSpouseInformation" Visible="true">
<h3 id="ApplicantLabel" runat="server"></h3>
<div class="dependentInformation">
<asp:PlaceHolder ID="phDependentInformation" runat="server"></asp:PlaceHolder>
</div>
</asp:Panel>
<!-- code behind -->
public partial class userInfo : System.Web.UI.UserControl
{
public string identity;
public string applicantTitle
{
set { ApplicantLabel.InnerText = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
public void Bind()
{
WebControl textBox = new TextBox
{
Text = identity,
ID = "textbox"
};
phDependentInformation.Controls.Add(textBox);
}
}
<html>
<head runat="server">
<title>Test user control binding</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:userInfo runat="server" ID="SpouseBasicInfo" Visible="false" />
<asp:Repeater runat="server" ID="RptDependents" OnItemCreated="RptDependents_ItemCreated">
<ItemTemplate>
<uc1:userInfo runat="server" ID="DependentBasicInfo" />
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton runat="server" ID="submit" OnClick="OnClickSubmit"><span>Submit</span></asp:LinkButton>
</div>
</form>
</body>
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SpouseBasicInfo.identity = "spouse";
SpouseBasicInfo.Bind();
SpouseBasicInfo.Visible = true;
List<String> list = new List<string>();
list.Add("Dependent A");
list.Add("Dependent B");
RptDependents.DataSource = list;
RptDependents.DataBind();
}
}
protected void OnClickSubmit(object sender, EventArgs e)
{
if (!Page.IsValid)
{
return;
}
var textbox = SpouseBasicInfo.FindControl("textbox") as TextBox;
string spouseName = textbox.Text;
}
protected void RptDependents_ItemCreated(object sender, RepeaterItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
{
var dependentInfo = e.Item.DataItem as String;
var dependentBasicInfo = e.Item.FindControl("DependentBasicInfo") as userInfo;
if (dependentBasicInfo == null) return;
dependentBasicInfo.applicantTitle = "Dependent " + (e.Item.ItemIndex + 1);
dependentBasicInfo.identity = dependentInfo;
dependentBasicInfo.Bind();
}
break;
}
}
}
</html>
Can you please post your code so we can get a look at it? Also, you say the runtime control becomes null after post back. Is the text property of the control set after the page is rendered? if so you may be able to use a hidden asp label on the page that can hold the text property. When the page is posted back the hidden label still holds the last value held for the text property of said control.
"User control (spouseBasicInfo). Why? Also the user control create a runtime control (assuming a TextBox). I found there is no way to retrieve the runtime control's Text property after clicking the submit as the control becomes null after PostBack. How to retrieve the property easily? Could any one help me? Thanks."
I haven't been working with asp.net for a long time so I don't think I can answer all the questions you are asking. But, if you are creating a text box at runtime and using the placeholder to deliver the object to the screen then yes, the textbox control will be null after post back. This is because it is not an asp.control like a textbox or label that is not runtime created. You can retrieve the value previously held in the text box by creating a label on screen that is hidden. Place your value in the hidden label and the runtime created text box. After post back the hidden label will still hold the value previous to post back and you can retrieve as you would normally retrieve a value held in a control. I hope this helps you get a step closer to solving your issue. Sorry I can't be of more help. Good luck.
I'm trying to access a hiddenfield value from my masterpage that is set in my child aspx page, but cannot access it the masterpage codebehind page_load event.
Child aspx page:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<telerik:RadStyleSheetManager ID="RadStyleSheetManager1" runat="server">
</telerik:RadStyleSheetManager>
<div class="center_content">
<div style="text-align: left">
<h2>
</h2>
</div>
<div style="text-align: left">
<uc1:Chart ID="Chart1" runat="server" />
</div>
</div>
<asp:HiddenField ID="hid1" runat="server" Value="Satellite Availability % Report" />
Master page:
<asp:Label runat="server" ID="Label1" Style="text-align: right; font-size: xx-large; color: #808080"></asp:Label>
Master page code behind: This is where I want to set the text value of the report from the child page.
protected void Page_Load(object sender, EventArgs e)
{
HiddenField hid1 = (HiddenField)MainContent.FindControl("MainContent_hid1");
if (hid1 != null)
{
Label1.Text = hid1.Value;
} }
<input type="hidden" name="ctl00$MainContent$hdnRptTitle" id="MainContent_hdnRptTitle" value="Satellite Availability % Report" />
There is no intellisense for the hdnRptTitle variable.
How can I get this to work? It seems simple enough, but don't know why it not working...
You can add the below code in your MasterPage:
HiddenField hid1 = (HiddenField)MainContent.FindControl("hid1");
if (hid1 != null)
{
Label1.Text = hid1.Value;
}
EDIT: Make sure your Label on the MasterPage is outside your ContentPlaceHolder, as I made this mistake when I first tested.
The above code should work as provided, with your control names, I'm not sure why you are using:
.FindControl("MainContent_hid1");
instead of
.FindControl("hid1");
You can use like this.
There can be multiple conterntPlaceHolder on your master page.
use the id which contains your hidden field in this case I assume that it is ContentPlaceHolder1
HiddenField hid1 = (HiddenField)ContentPlaceHolder1.FindControl("hdnRptTitle");
if (hid1 != null)
{
Label1.Text = hid1.Value;
}
There is a similar post on so
How to access content page controls from master page in asp.net
You can reference a master page and get the control like this:
VB.Net:
Dim te As HiddenField
Dim val As String
te = Me.Page.Master.FindControl("hdnRptTitle")
val = te.Value
c#:
HiddenField te = default(HiddenField);
string val = null;
te = this.Page.Master.FindControl("hdnRptTitle");
val = te.Value;
Why do you think that you can access a control in a content-page of a master-page? A MasterPage is used for multiple pages, why do you want to hardlink it with a specific page, it won't work anymore without it. If the HiddenField is essential for the operation of the master you should declare it there.
For every child page, there is a different rpt title which needs to
show up on the master page. How can I accomplish this?
Then the content page can access it's master to set the text but not vice-versa.
You could provide a public property in the master, e.g.:
public string ReportTitle
{
get { return this.LblReportTitle.Text; }
set { this.LblReportTitle.Text = value; }
}
and in the ContentPage, for example in it's Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
// assuming the type of your master is SiteMaster
var master = this.Master as SiteMaster;
if (master != null)
master.ReportTitle = hdnRptTitle.Value;
}
This approach is still linking the master with one (or multiple) of it's childs, but it would still "work" if the content-page would use a different master-type. You'd also be informed with a compiler error if somebody remove or change the property.
However, where the content stores the report-type or where the master displays it is an implementation detail and can be changed in future without breaking anything.
I have a FormView and I need to access some Divs and other controls that are inside it. My apsx code looks similar to this:
<asp:FormView ID="Edit_FV" runat="server" DataKeyNames="IDproceso" DefaultMode="Edit" DataSourceID="SqlDS_Procesos">
<EditItemTemplate>
<div id="second_info" runat="server">
<div id="second_info_left" runat="server">
<div id="alcance" class="report_field" runat="server">
<p class="container-title">
Alcance:</p>
<asp:TextBox ID="TextBox14" runat="server" TextMode="multiline" Width="400px" Height="120px" Text='<%# Bind("alcance") %>' />
</div>
</div>
<div id="second_info_right" runat="server">
<div class="valores-container" id="tipo_ahorro" runat="server">
<asp:CheckBox ID="ahorro_state" runat="server" Checked='<%# Bind("tipo_ahorro") %>' />
</div>
</div>
</EditItemTemplate>
</asp:FormView>
Now, say I want to access the CheckBox with id = ahorro_state, I tried with Edit_FV.FindControl("ahorro_state") and got a Null reference. I also tried with Edit_FV.FindControl("MainContent_Edit_FV_ahorro_state") because this is how the ID actually gets named in the final HTML document, but I got a Null reference too. The same happened when I tried accessing any of the divs (with IDs second_info,tipo_ahorro, etc..). I feel I'm doing a dumb mistake but I looked around a bit and haven't found and answer.
Any ideas how to solve this?
EDIT: Added Code where I'm calling FindControl.
I tried both calling DataBind() from the Page_Load():
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
if (Edit_FV.CurrentMode == FormViewMode.Edit)
{
Control c = Edit_FV.FindControl("ahorro_state");//c is null here.
}
}
And also tried setting the OnDataBound attribute of Edit_FV: OnDataBound="onBound"
protected void onBound(object sender, EventArgs e)
{
if (Edit_FV.CurrentMode == FormViewMode.Edit)
{
ControlCollection a = Edit_FV.Controls;
Control c = Edit_FV.FindControl("ahorro_state");//c is null here
}
}
Although the default mode is set "Edit", the form view won't switch to that mode until the control is DataBound. Try calling DataBind() first, then use FindControl using the ID of your element (not the ClientID, as you tried in your second example).
See FormView.FindControl(): object reference error for examples of where to put your FindControl logic.
EDIT:
There is also the possibility that your data source is not returning any data. This will result in the EditItemTemplate being empty which might explain your null reference errors. Try checking for a Edit_FV.DataItemCount > 0 before switching into Edit mode.
I have had similar problems with 'FindControl'. I found a piece of code that has helped me a) Find controls recursively, and b) the debug statement has been very help to see why I am not finding the control in question. To help me find the controls I have to give them ID values when I am looking for them if they don't have one by default:
public static class General_ControlExtensions
{
//From: http://www.devtoolshed.com/content/find-control-templatefield-programmatically
/// <summary>
/// recursively finds a child control of the specified parent.
/// USAGE:
/// Control controlToFind = DetailsView1.fn_ReturnControl_givenControlID("txtName");
/// </summary>
/// <param name="rootControl"></param>
/// <param name="ID"></param>
/// <returns></returns>
public static Control fn_ReturnControl_givenControlID(this Control rootControl, string ID)
{
if (rootControl.ID == ID)
{
return rootControl;
}
foreach (Control control in rootControl.Controls)
{
Debug.WriteLine("FindByID - child.id: " + control.ID);
Control foundControl = fn_ReturnControl_givenControlID(control, ID);
if (foundControl != null)
{
return foundControl;
}
}
return null;
}
Here is an example of its usage:
using System.Diagnostics; // for debug
TextBox txt_LastName = (TextBox)fv_NewHire_DetailsForm.fn_ReturnControl_givenControlID("INSERT_txt_LastName");
In addition, I have found it helpful for this type of problem to preface the controls in the 'insertitemtemplate' with 'INSERT_", and controls in the 'edititemtemplate' with 'EDIT_" to quickly tell them apart in the debug output.