<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GPederzini</id>
		<title>OWASP - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GPederzini"/>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php/Special:Contributions/GPederzini"/>
		<updated>2026-05-02T03:33:05Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.2</generator>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=35162</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=35162"/>
				<updated>2008-08-01T18:35:18Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* .NET Preventing LDAP Injection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;^[a-zA-Z_0-9 @.]+$&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;^[a-zA-Z_0-9 @.]+$&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb;&lt;br /&gt;
               User Id=user; Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, &lt;br /&gt;
                   Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
                   UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
                   KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;br /&gt;
* http://blogs.vertigosoftware.com/snyholm/archive/2005/12/16/1746.aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=35000</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=35000"/>
				<updated>2008-07-30T21:51:04Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Authorization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Policy. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
If an account is locked (for example due of an attempt to brute force that exceed the &amp;quot;Account lockout threshold&amp;quot; or simply for an error), a new password must be created by the administrator. So a good choice is to ALTER the login with a MUST_CHANGE new password, to force the user to modify it during the first login. The script is like that:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER LOGIN [userName1] WITH PASSWORD=N'12345678' UNLOCK MUST_CHANGE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
&lt;br /&gt;
As it's previously defined, in SQL Server 2005 there are 2 types of authentication: Windows Mode or Mixed Mode. In both case the login only authenticates against the server. Every login could belong to one or more &amp;quot;server roles&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* sysadmin  &lt;br /&gt;
* dbcreator &lt;br /&gt;
* diskadmin &lt;br /&gt;
* processadmin &lt;br /&gt;
* securityadmin &lt;br /&gt;
* bulkadmin &lt;br /&gt;
* serveradmin &lt;br /&gt;
* setupadmin &lt;br /&gt;
* public&lt;br /&gt;
&lt;br /&gt;
The full-rights role is &amp;quot;sysadmin&amp;quot; and for a predefined setting three groups and one sql login have this role (assuming the machine is called WIN2K3 and the sql installation SQL2005INSTANCE):&lt;br /&gt;
&lt;br /&gt;
* Windows group BUILTIN\Administrators&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005MSSQLUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Engine Service Account)&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005SQLAgentUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Agent Service Account)&lt;br /&gt;
* Sql Login &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So if the services Sql Server Engine and Sql Server Agent run under a specific account (as it's mentioned above), it's possible to DROP the group BUILTIN\Administrators to reduce the administration's surface, but first check if there is a &amp;quot;sysadmin account&amp;quot; of which the password is known (&amp;quot;sa&amp;quot; or better renamed &amp;quot;sa&amp;quot; for example). Otherwise create it. After that drop the BUILTIN\Administrators (rembember that it's a reversible operation).&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 DROP LOGIN [BUILTIN\Administrators]&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
The same approach is possible also with the others two groups, but it's necessary to create two more logins with sysadmin right. So it's preferred to mantain the two groups, using them only for the respective service account.&lt;br /&gt;
&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34999</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34999"/>
				<updated>2008-07-30T21:45:41Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Authorization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Policy. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
If an account is locked (for example due of an attempt to brute force that exceed the &amp;quot;Account lockout threshold&amp;quot; or simply for an error), a new password must be created by the administrator. So a good choice is to ALTER the login with a MUST_CHANGE new password, to force the user to modify it during the first login. The script is like that:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER LOGIN [userName1] WITH PASSWORD=N'12345678' UNLOCK MUST_CHANGE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
&lt;br /&gt;
As it's previously defined, in SQL Server 2005 there are 2 types of authentication: Windows Mode or Mixed Mode. In both case the login only authenticates against the server. Every login could belong to one or more &amp;quot;server roles&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* sysadmin  &lt;br /&gt;
* dbcreator &lt;br /&gt;
* diskadmin &lt;br /&gt;
* processadmin &lt;br /&gt;
* securityadmin &lt;br /&gt;
* bulkadmin &lt;br /&gt;
* serveradmin &lt;br /&gt;
* setupadmin &lt;br /&gt;
* public&lt;br /&gt;
&lt;br /&gt;
The full-rights role is &amp;quot;sysadmin&amp;quot; and for a predefined setting three groups and one sql login have this role (assuming the machine is called WIN2K3 and the sql installation SQL2005INSTANCE):&lt;br /&gt;
&lt;br /&gt;
* Windows group BUILTIN\Administrators&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005MSSQLUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Engine Service Account)&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005SQLAgentUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Agent Service Account)&lt;br /&gt;
* Sql Login &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So if the services Sql Server Engine and Sql Server Agent run under a specific account (as it's mentioned above), it's possible to DROP the group BUILTIN\Administrators to reduce the administration's surface, but first check if there is a &amp;quot;sysadmin account&amp;quot; of which the password is known (&amp;quot;sa&amp;quot; or better renamed &amp;quot;sa&amp;quot; for example). Otherwise create it. After that drop the BUILTIN\Administrators (rembember that it's a reversible operation).&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 DROP LOGIN [BUILTIN\Administrators]&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34998</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34998"/>
				<updated>2008-07-30T21:44:50Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Authorization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Policy. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
If an account is locked (for example due of an attempt to brute force that exceed the &amp;quot;Account lockout threshold&amp;quot; or simply for an error), a new password must be created by the administrator. So a good choice is to ALTER the login with a MUST_CHANGE new password, to force the user to modify it during the first login. The script is like that:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER LOGIN [userName1] WITH PASSWORD=N'12345678' UNLOCK MUST_CHANGE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
&lt;br /&gt;
As it's previously defined, in SQL Server 2005 there are 2 types of authentication: Windows Authentication or Mixed Mode. In both case the login only authenticates against the server. Every login could belong to one or more &amp;quot;server roles&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* sysadmin  &lt;br /&gt;
* dbcreator &lt;br /&gt;
* diskadmin &lt;br /&gt;
* processadmin &lt;br /&gt;
* securityadmin &lt;br /&gt;
* bulkadmin &lt;br /&gt;
* serveradmin &lt;br /&gt;
* setupadmin &lt;br /&gt;
* public&lt;br /&gt;
&lt;br /&gt;
The full-rights role is &amp;quot;sysadmin&amp;quot; and for a predefined setting three groups and one sql login have this role (assuming the machine is called WIN2K3 and the sql installation SQL2005INSTANCE):&lt;br /&gt;
&lt;br /&gt;
* Windows group BUILTIN\Administrators&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005MSSQLUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Engine Service Account)&lt;br /&gt;
* Windows group WIN2K3\SQLServer2005SQLAgentUser$WIN2K3$SQL2005INSTANCE  (the group of the Sql Server Agent Service Account)&lt;br /&gt;
* Sql Login &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So if the services Sql Server Engine and Sql Server Agent run under a specific account (as it's mentioned above), it's possible to DROP the group BUILTIN\Administrators to reduce the administration's surface, but first check if there is a &amp;quot;sysadmin account&amp;quot; of which the password is known (&amp;quot;sa&amp;quot; or better renamed &amp;quot;sa&amp;quot; for example). Otherwise create it. After that drop the BUILTIN\Administrators (rembember that it's a reversible operation).&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 DROP LOGIN [BUILTIN\Administrators]&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34712</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34712"/>
				<updated>2008-07-25T07:44:50Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Password Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Policy. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
If an account is locked (for example due of an attempt to brute force that exceed the &amp;quot;Account lockout threshold&amp;quot; or simply for an error), a new password must be created by the administrator. So a good choice is to ALTER the login with a MUST_CHANGE new password, to force the user to modify it during the first login. The script is like that:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER LOGIN [userName1] WITH PASSWORD=N'12345678' UNLOCK MUST_CHANGE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34704</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34704"/>
				<updated>2008-07-24T22:58:48Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Password Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Settings. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
If an account is locked (for example due of an attempt to brute force that exceed the &amp;quot;Account lockout threshold&amp;quot; or simply for an error), a new password must be created by the administrator. So a good choice is to ALTER the login with a MUST_CHANGE new password, to force the user to modify it during the first login. The script is like that:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER LOGIN [userName1] WITH PASSWORD=N'12345678' UNLOCK MUST_CHANGE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34703</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34703"/>
				<updated>2008-07-24T22:09:43Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Password Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Settings. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-99999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34702</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34702"/>
				<updated>2008-07-24T22:04:10Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Password Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Settings. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
* Account lockout duration: (indicates the number of minutes in which the account is locked. The range is [1-99999]. A 0 value indicates that the account will be blocked until the administrator unlocks it)&lt;br /&gt;
* Account lockout threshold (indicates the max number of failed attempts after that the login is blocked. The range is [1-999]. A 0 value indicates that the account won't be never blocked)&lt;br /&gt;
* Reset account lockout counter after (indicates the number of minutes that must elapse before the number of attempts return to zero. The range is [1-99999].)&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34701</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=34701"/>
				<updated>2008-07-24T21:44:01Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Password Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
When it's time to create a new Login on Sql Server, it's very important to use some evalation criteria. A possible script to do that is:&lt;br /&gt;
&lt;br /&gt;
 USE [master]&lt;br /&gt;
 GO&lt;br /&gt;
 CREATE LOGIN [userName1] WITH PASSWORD=N'password1' &lt;br /&gt;
 MUST_CHANGE, DEFAULT_DATABASE=[master], CHECK_EXPIRATION=ON, CHECK_POLICY=ON&lt;br /&gt;
&lt;br /&gt;
The relevant things are:&lt;br /&gt;
&lt;br /&gt;
* MUST_CHANGE --&amp;gt; after the first login, the user must change the planned password (in this case &amp;quot;password1&amp;quot;). Applied to SQL Logins&lt;br /&gt;
* CHECK_EXPIRATION=ON --&amp;gt; the password must accomplish the expiration policy. Applied to SQL Logins&lt;br /&gt;
* CHECK_POLICY=ON --&amp;gt; the password must accomplish the Windows policy. Applied to SQL Logins&lt;br /&gt;
&lt;br /&gt;
When SQL Server 2005 runs on Windows Server 2003 or higher, it can benefit on Windows password policies. These are configured on Control Panel -&amp;gt; Administrative Tools -&amp;gt; Local Security Settings. &lt;br /&gt;
On &amp;quot;Account Policies&amp;quot; there are &lt;br /&gt;
&lt;br /&gt;
* Password Policy&lt;br /&gt;
* Account Lockout Policy&lt;br /&gt;
&lt;br /&gt;
On the first option, it's important to set:&lt;br /&gt;
* Enforce password history (number of password stored for each account, to avoid repeating every time the same password.  The range is [0-24])&lt;br /&gt;
* Maximum password age (max number of days in which the password is valid. The range is [1-998]. A 0 value indicates no expiration)&lt;br /&gt;
* Minimum password age (min number of days in which the password could not be changed The range is [1-998]. A 0 value indicates that the password could be changed in every moment)&lt;br /&gt;
* Minimum password length (minimum number of characters. The range is [1-14]. A 0 value indicates no password needed)&lt;br /&gt;
* Password must meet complexity requirements (no two consecutive character of account name, minimum 6 character belonging at least at three of the categories [A-Z], [a-z], [0-9], or characters like !, %, #, $ ecc...)&lt;br /&gt;
&lt;br /&gt;
On the second option, it's important to set:&lt;br /&gt;
&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33752</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33752"/>
				<updated>2008-07-09T07:48:45Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb;&lt;br /&gt;
               User Id=user; Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, &lt;br /&gt;
                   Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
                   UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
                   KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;br /&gt;
* http://blogs.vertigosoftware.com/snyholm/archive/2005/12/16/1746.aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33747</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33747"/>
				<updated>2008-07-09T07:18:39Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb;&lt;br /&gt;
               User Id=user; Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, &lt;br /&gt;
                   Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
                   UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
                   KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33746</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33746"/>
				<updated>2008-07-09T07:17:00Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb;&lt;br /&gt;
               User Id=user; Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33707</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33707"/>
				<updated>2008-07-08T21:35:59Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33706</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33706"/>
				<updated>2008-07-08T21:35:43Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;br /&gt;
* http://blogs.vertigosoftware.com/snyholm/archive/2005/12/16/1746.aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33705</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33705"/>
				<updated>2008-07-08T21:29:21Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/dtkwfdky(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33703</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33703"/>
				<updated>2008-07-08T21:18:59Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section is comparable to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;NameProvider1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application that must access to this section do automatically the decryption, due the read permission for the key container granted to the running user.&lt;br /&gt;
In any case it's always possible to decrypt the section with:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pdf connectionStrings C:\Project\BackendSecProj&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33702</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33702"/>
				<updated>2008-07-08T21:06:23Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
First thing it's necessary to create a key container, for the public key encryption; open the SDK command prompt of the Framework and digit:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis.exe -pc keycontainer1 &lt;br /&gt;
&lt;br /&gt;
in this manner a file with public and private key is stored at the path &lt;br /&gt;
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys&lt;br /&gt;
with a unique code. It's possible to recognize the creation's datetime. It's important to know that this file is protected by the NTFS ACL, so only the creator and the SYSTEM account can manipulate it.&lt;br /&gt;
So if the web application run with another account (for example MACHINENAME\ASPNET user), it's necessary to grant the read permission  for the key container with the command:&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pa keycontainer1 MACHINENAME\ASPNET&lt;br /&gt;
&lt;br /&gt;
On the other hand add these lines in the Web.Config:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration xmlns=&amp;quot;http://schemas.microsoft.com/.NetConfiguration/v2.0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;configProtectedData&amp;gt;&lt;br /&gt;
      &amp;lt;providers&amp;gt;        &lt;br /&gt;
        &amp;lt;add name=&amp;quot;NameProvider1&amp;quot;&lt;br /&gt;
             type=&amp;quot;System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,Culture=neutral,&lt;br /&gt;
             PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL&amp;quot;&lt;br /&gt;
             UseMachineContainer=&amp;quot;true&amp;quot;&lt;br /&gt;
             KeyContainerName=&amp;quot;keycontainer1&amp;quot;&lt;br /&gt;
          /&amp;gt;       &lt;br /&gt;
      &amp;lt;/providers&amp;gt;&lt;br /&gt;
    &amp;lt;/configProtectedData&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which there are references of the name of the provider (NameProvider1) that is based on RSA and key container (keycontainer1) used by the provider.&lt;br /&gt;
Now it's possible to encrypt the &amp;quot;connectionStrings&amp;quot; section using the physical path of the directory storing the web.config (and the the web application):&lt;br /&gt;
&lt;br /&gt;
 aspnet_regiis -pef connectionStrings C:\Project\BackendSecProj -prov NameProvider1&lt;br /&gt;
&lt;br /&gt;
The result is that the connectionStrings section has a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;connectionStrings configProtectionProvider=&amp;quot;MyProv&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;EncryptedData Type=&amp;quot;http://www.w3.org/2001/04/xmlenc#Element&amp;quot;&lt;br /&gt;
   xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;EncryptedKey xmlns=&amp;quot;http://www.w3.org/2001/04/xmlenc#&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;EncryptionMethod Algorithm=&amp;quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;KeyInfo xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;KeyName&amp;gt;Rsa Key&amp;lt;/KeyName&amp;gt;&lt;br /&gt;
     &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
     &amp;lt;CipherData&amp;gt;&lt;br /&gt;
      &amp;lt;CipherValue&amp;gt;XV8DCEfUymYphQaL5GTqCQGhrNoED+/rIKNXS3l44exGiQWx2FH0Rq.....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
     &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;/EncryptedKey&amp;gt;&lt;br /&gt;
   &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
   &amp;lt;CipherData&amp;gt;&lt;br /&gt;
    &amp;lt;CipherValue&amp;gt;2jTQIKfzHOaXcyOYd3kA6Pdvy1v3269fr0OzEsK9DRnxgi9iH8umA....&amp;lt;/CipherValue&amp;gt;&lt;br /&gt;
   &amp;lt;/CipherData&amp;gt;&lt;br /&gt;
  &amp;lt;/EncryptedData&amp;gt;&lt;br /&gt;
 &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33695</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33695"/>
				<updated>2008-07-08T19:53:56Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
So it's confortable to use the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; with RSA provider.&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33531</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33531"/>
				<updated>2008-07-06T16:29:53Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot; (located in %SystemRoot%\Microsoft.NET\Framework\versionNumber folder)&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33506</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33506"/>
				<updated>2008-07-06T11:06:41Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. Additionally it uses an encryption mode based on the login of the user, storing the information in the registry, so no key creation needed. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33464</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33464"/>
				<updated>2008-07-05T16:36:29Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided in three modes:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
* Custom Provider&lt;br /&gt;
&lt;br /&gt;
DPAPI is the simplest manner. It uses a machine (or user) level key storage, so it's possible to share the secret with all the applications of the machine or not. But if the application is deployed in a Web farm, the better is RSA protected configuration provider due to the ease with which RSA keys can be exported.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33463</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33463"/>
				<updated>2008-07-05T16:03:14Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to the virtual directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In both cases the encryption is potentially provided by two elements:&lt;br /&gt;
&lt;br /&gt;
* Windows Data Protection API Provider (DPAPI)&lt;br /&gt;
* RSA Protected Configuration Provider&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33461</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33461"/>
				<updated>2008-07-05T15:47:35Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a .NET Web Application tipically the parameters to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's possible to notice:&lt;br /&gt;
&lt;br /&gt;
* Name of the server machine&lt;br /&gt;
* Name of the instance of SQL Server&lt;br /&gt;
* Name of the database&lt;br /&gt;
* Username&lt;br /&gt;
* Password&lt;br /&gt;
&lt;br /&gt;
Gaining the access to the virtual directory of the web application, these informations are freely accessible. &lt;br /&gt;
The solution to mantain the confidentiality is always one: encryption.&lt;br /&gt;
Because encryption is not costless, it's not a good choice to encrypt the Web.config in its totality. It's better to select only the sensitive informations, that often are stored in the &amp;quot;configuration&amp;quot; sections of the file.&lt;br /&gt;
In .NET there are two mode to encrypt configuration section:&lt;br /&gt;
&lt;br /&gt;
* Coding with some classes of the Framework&lt;br /&gt;
* Using the command line tool &amp;quot;aspnet_regiis.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33458</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33458"/>
				<updated>2008-07-05T14:00:01Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a Web Application tipically the parameter configuration to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;  &lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;Connection_SQLServer2005&amp;quot; connectionString=&amp;quot;Data Source=WIN2K3\SQLInstance; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33457</id>
		<title>OWASP Backend Security Project .NET Security Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_.NET_Security_Programming&amp;diff=33457"/>
				<updated>2008-07-05T13:57:41Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Web.config Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
In this section are explained the best solution to avoid two of the most dangerous vulnerabilities of web applications, the sql injection and ldap injection on .NET programming &lt;br /&gt;
&lt;br /&gt;
It will be analized the interactions between a web application written in C# in ASP.NET technology, .NET Framework 2.0 and two kinds of data provider: a SQL Server 2005 data provider and an OpenLdap Server data provider.&lt;br /&gt;
&lt;br /&gt;
For the first interaction imagine a database called “ExampleDB” in which there are some tables. One of these tables is “Users”. From a &lt;br /&gt;
web application is possible to query the database to extract information about the users through their name. &lt;br /&gt;
&lt;br /&gt;
For the second interaction imagine an Ldap server called “ExampleLDAP”.&lt;br /&gt;
&lt;br /&gt;
The project is simple and is made by some .aspx page with a textbox in which is possible to insert the name of the user and the program will return the information, reading from ExampleDB (or ExampleLDAP).&lt;br /&gt;
It's not important to specify how it's possible to create an aspx page So the focus is on the code that we have to write to interact with the server data provider.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing SQL Injection ==&lt;br /&gt;
&lt;br /&gt;
Two approaches are likely: inline query or stored procedure.&lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Case 1: Inline query ===&lt;br /&gt;
&lt;br /&gt;
Inline queries are the queries in which is possible to compose a sql statement through string concatenation. By clicking on the first button, the execution of the OnClick event is generated, doing the following:&lt;br /&gt;
&lt;br /&gt;
  protected void btnQueryInline_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open(); &lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; &lt;br /&gt;
                                             + txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection); &lt;br /&gt;
            cmd.CommandType = CommandType.Text;&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper();&lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
&lt;br /&gt;
This section of code provides the sqlConnection, reading the connectionString from the Web.Config file. This is an important task for the application because it represents the entry point to the database, the credentials of the user that can authenticate on the ExampleDB. &lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
        sqlConnection.Open(); &lt;br /&gt;
        SqlCommand cmd = new SqlCommand(&amp;quot;select Name,Surname,Code from  dbo.Users where Name LIKE '%&amp;quot; + &lt;br /&gt;
                                        txtQueryInline.Text + &amp;quot;%'&amp;quot;, sqlConnection);			                              &lt;br /&gt;
        cmd.CommandType = CommandType.Text; &lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class, in which is written the sql code, concatenating with the text to search. The type of the SqlCommand is “Text”, so it's clear that the sql code is provided directly. This code is prone to sql injection, because we can manipulate the statement, injecting in the textbox, for example, the string: &lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
where sql statement is any sql code (it is possible to drop tables, add users, reconfigure the xp_cmdshell, etc.) &lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
The third section is useful to represent the result set of the query. It uses the ADO.NET “Dataset”, and an intermediate class called SqlDataAdapter, that adapts the sql data in a form that can be used by the Dataset Object.&lt;br /&gt;
&lt;br /&gt;
It is possible to improve this query, using the second form of interaction that make use of a stored procedure&lt;br /&gt;
&lt;br /&gt;
=== Case 2: Parametrized query + Stored Procedure vulnerable ===&lt;br /&gt;
&lt;br /&gt;
By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStoredVuln_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStoredVuln.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if (sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
       DECLARE @StrSQL varchar(max)&lt;br /&gt;
       SET @StrSQL = 	&lt;br /&gt;
                'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
                FROM dbo.Users U &lt;br /&gt;
                WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This kind of stored procedure are not rare. In this case is possible to compose the statement in many ways using parameters, function and so on.&lt;br /&gt;
&lt;br /&gt;
Altough it is a parametrized query with a stored procedure, as the code shows, it is possible to inject the same string&lt;br /&gt;
&lt;br /&gt;
'' '; sql statement -- ''&lt;br /&gt;
&lt;br /&gt;
to inject a sql statement. Using the SQL Server function REPLACE, it is possible to “patch” the problem without rewrite the store procedure, replacing all the single quote with a couple of single quote.&lt;br /&gt;
&lt;br /&gt;
 ALTER PROCEDURE [dbo].[USP_SearchUserByNameVuln]&lt;br /&gt;
      @Name varchar(50)&lt;br /&gt;
 AS&lt;br /&gt;
 BEGIN&lt;br /&gt;
      SET NOCOUNT ON;				&lt;br /&gt;
      DECLARE @StrSQL varchar(max)&lt;br /&gt;
      SET @Name = REPLACE(@Name,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;,&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;)&lt;br /&gt;
      SET @StrSQL = 	&lt;br /&gt;
            'SELECT U.Name,U.Surname,U.Code&lt;br /&gt;
            FROM dbo.Users U &lt;br /&gt;
            WHERE U.Name LIKE ' + &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%'+  @Name+  '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
       EXEC (@StrSql)	&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
This second case explains the fact that the use of parametrized query with stored procedure not always resolve the security flaws caused by sql injection.&lt;br /&gt;
&lt;br /&gt;
=== Case 3: Parametrized query + Stored Procedure not vulnerable ===&lt;br /&gt;
&lt;br /&gt;
It is possible to modify the way to execute the same query, using parametrized query in conjunction with stored procedures. By clicking on the second button, the execution of the OnClick event is generated, doing the following: &lt;br /&gt;
&lt;br /&gt;
 protected void btnQueryStored_OnCLick(object sender, EventArgs e)&lt;br /&gt;
 {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        try&lt;br /&gt;
        {                       &lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
        }&lt;br /&gt;
        catch (SqlException ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
        finally&lt;br /&gt;
        {&lt;br /&gt;
            if(sqlConnection != null)&lt;br /&gt;
                sqlConnection.Close(); //close the connection               &lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
''' First Section: '''&lt;br /&gt;
&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString(); &lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString);&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
''' Second Section: '''&lt;br /&gt;
&lt;br /&gt;
            sqlConnection.Open();&lt;br /&gt;
            SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByNameNotVuln&amp;quot;, sqlConnection);  &lt;br /&gt;
            cmd.CommandType = CommandType.StoredProcedure; &lt;br /&gt;
            SqlParameter pName = new SqlParameter(&amp;quot;@Name&amp;quot;, SqlDbType.VarChar, 50);&lt;br /&gt;
            pName.Value = txtQueryStored.Text;&lt;br /&gt;
            cmd.Parameters.Add(pName);&lt;br /&gt;
&lt;br /&gt;
In this section is used the SqlCommand class as above, but, the type of the SqlCommand is “StoredProcedure” , so the sql code is not provided directly, but there is a procedure inside the database that makes the job. This procedure is called USP_SearchUserByNameNotVuln and accept a Varchar(50) parameter called @Name. &lt;br /&gt;
The code of the stored is simply: &lt;br /&gt;
&lt;br /&gt;
 CREATE PROCEDURE [dbo].[USP_SearchUserByNameNotVuln]&lt;br /&gt;
       @Name varchar(50)&lt;br /&gt;
 AS &lt;br /&gt;
 BEGIN &lt;br /&gt;
       SET NOCOUNT ON;				&lt;br /&gt;
 SELECT&lt;br /&gt;
       U.Name,&lt;br /&gt;
       U.Surname,&lt;br /&gt;
       U.Code&lt;br /&gt;
 FROM &lt;br /&gt;
       dbo.Users U &lt;br /&gt;
 WHERE&lt;br /&gt;
       U.Name LIKE &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;%' + @Name + '%&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
Three steps for each parameter passed to the stored procedure are needed to use the SqlParameter class:&lt;br /&gt;
&lt;br /&gt;
* Instantiate the parameter with the right name and type used in the stored procedure&lt;br /&gt;
* Assign the value (in this case the value given by the user in the textbox)&lt;br /&gt;
* Add the parameter to the SqlCommand &lt;br /&gt;
&lt;br /&gt;
When the sql command is executed, the parameters will be replaced with values specified by the SqlParameter object.&lt;br /&gt;
&lt;br /&gt;
In conclusion, this kind of query is not prone to sql injection, because it is not possibile to build ad hoc sql statements, due to the correct use of Stored Procedure and the SqlParameter class.&lt;br /&gt;
&lt;br /&gt;
''' Third Section: '''&lt;br /&gt;
&lt;br /&gt;
            DataSet ds = new DataSet();&lt;br /&gt;
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
            sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
            gridresult.DataSource = ds;&lt;br /&gt;
            gridresult.DataBind();&lt;br /&gt;
&lt;br /&gt;
This section is the same of the example above.&lt;br /&gt;
&lt;br /&gt;
=== Input validation ===&lt;br /&gt;
&lt;br /&gt;
Another point that is important to consider is the validation of the input. For example in a context in which a user has to insert (or select) some data in (or from) the database let’s think about the worst case, that is a user that can digit anything and submit anything to the server. To avoid this the only choiche is to validate the user's input. Two strategies are possible:&lt;br /&gt;
&lt;br /&gt;
1.	White list&lt;br /&gt;
&lt;br /&gt;
2.	Black list&lt;br /&gt;
&lt;br /&gt;
The first solution answers at the condition: &amp;quot;deny all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
The second solution answers at the condition: &amp;quot;allow all, except what is explicitly signed in the list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The best solution for the security of the application is try to implement a validation of the input based on the first case. This comes more simply with numeric input, range input or strings that follow a specific pattern (for example an e-mail or a date). It becomes more difficult for strings with a not specific pattern (for example strings inserted in a search engine) in which often only a solution based on a black list is reasonably possible. &lt;br /&gt;
&lt;br /&gt;
In a Web Application, there are two kinds of input validation:&lt;br /&gt;
&lt;br /&gt;
1.	client validations&lt;br /&gt;
&lt;br /&gt;
2.	server validations&lt;br /&gt;
&lt;br /&gt;
There are a couple of reasons to use both types of validation summarized in the following points: &lt;br /&gt;
&lt;br /&gt;
* client validations increase performance (the application doesn't postback to the server) but cause a false sense of security (the validation can be bypassed intercepting and manipulating the client request).&lt;br /&gt;
* server validations make worse performance but increase the security, because the validation is made by the server.&lt;br /&gt;
&lt;br /&gt;
In ASP.NET to realize these concepts there are the server web control Validators: &lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator&lt;br /&gt;
* CompareValidator&lt;br /&gt;
* RangeValidator&lt;br /&gt;
* RegularExpressionValidator&lt;br /&gt;
* CustomValidator&lt;br /&gt;
&lt;br /&gt;
Technically these objects realize both type of validations: that is if the client support Javascript, the Validator uses first the client validation, and after that the page is validated on then server side too. If the client doesn't support Javascript, the validation is made only on the server side. In this manner the application validate the input in a progressive mode and the design of the application doesn't follow a '' &amp;quot;Minimum-Denominator-Multiplier&amp;quot; ''.&lt;br /&gt;
&lt;br /&gt;
To explain the concept in code, it's possible to analyze the CustomValidator, that is the higher generalization because it's possible to use a personalized validation logic.&lt;br /&gt;
&lt;br /&gt;
=== CustomValidator ===&lt;br /&gt;
&lt;br /&gt;
We can think symply to a textbox with a button, like the example above, in which it gives the way to search all the suppliers with a specific code (a string of 16 char) For security reasons it is imagined that a specific user can only see the suppliers that have a code in which the first 4 character are &amp;quot;PFHG&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Any other string that doesn't match this pattern has to be exclude from the search (white list approach) &lt;br /&gt;
&lt;br /&gt;
[[Image:owasp_bsp_net_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
The XML part of the page is like that:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;asp:Label ID=&amp;quot;lblQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Digit the first four numbers&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;
 &amp;lt;asp:TextBox ID=&amp;quot;txtQuerySearch&amp;quot; Width=&amp;quot;5em&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;
 &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;RequiredFieldValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Required Code&amp;quot; &lt;br /&gt;
 ControlToValidate=&amp;quot;txtQuerySearch&amp;quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;&lt;br /&gt;
 &amp;lt;asp:CustomValidator ID=&amp;quot;CustomValidatorQuerySearch&amp;quot; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;Wrong code&amp;quot;&lt;br /&gt;
             ControlToValidate=&amp;quot;txtQuerySearch&amp;quot; OnServerValidate=&amp;quot;ValidateCode&amp;quot;&amp;gt;&amp;lt;/asp:CustomValidator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control Label and Button are intuitive web controls.&lt;br /&gt;
It's clear to see that two Validator have been applied to the textbox whose ID is '' &amp;quot;txtQuerySearch&amp;quot; ''. &lt;br /&gt;
The Validators are:&lt;br /&gt;
&lt;br /&gt;
* RequiredFieldValidator: we don't accept an empty textbox when we submit our request to the server&lt;br /&gt;
* CustomValidator: we would implement some custom logic to our textbox&lt;br /&gt;
&lt;br /&gt;
In fact the CustomValidator tag has a particular event called &amp;quot;OnServerValidate&amp;quot; that we can hook to a custom callback function, whose code is executed on the server side.&lt;br /&gt;
For this example it's like that: &lt;br /&gt;
&lt;br /&gt;
 protected void ValidateCode(object source, ServerValidateEventArgs args)&lt;br /&gt;
    {&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            string textToValidate = args.Value;&lt;br /&gt;
            if (textToValidate.Equals(&amp;quot;PFHG&amp;quot;))&lt;br /&gt;
                args.IsValid = true;&lt;br /&gt;
            else&lt;br /&gt;
                args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            args.IsValid = false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The function handles the argument &amp;quot;arg&amp;quot; that brings the text inserted by the user. &lt;br /&gt;
If this text match with our pattern, the argument is valid and the server executes the code associated to the button, querying the database in the same manner seen above; however the code is now conditioned by the statement &amp;quot;if(Page.IsValid)&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
 protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        DbHelper dbHelper = new DbHelper(); &lt;br /&gt;
        string connectionString = dbHelper.returnConnectionString();&lt;br /&gt;
        SqlConnection sqlConnection = new SqlConnection(connectionString); &lt;br /&gt;
        if (Page.IsValid)&lt;br /&gt;
        {&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                sqlConnection.Open();&lt;br /&gt;
                SqlCommand cmd = new SqlCommand(&amp;quot;USP_SearchUserByCode&amp;quot;, sqlConnection); &lt;br /&gt;
                cmd.CommandType = CommandType.StoredProcedure;              &lt;br /&gt;
                SqlParameter pCode = new SqlParameter(&amp;quot;@Code&amp;quot;, SqlDbType.VarChar, 4);&lt;br /&gt;
                pCode.Value = txtQuerySearch.Text;&lt;br /&gt;
                cmd.Parameters.Add(pCode);&lt;br /&gt;
                DataSet ds = new DataSet();&lt;br /&gt;
                SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);&lt;br /&gt;
                sqlDataAdapter.Fill(ds, &amp;quot;ResultTable&amp;quot;);&lt;br /&gt;
                gridresult.DataSource = ds;&lt;br /&gt;
                gridresult.DataBind();&lt;br /&gt;
            }&lt;br /&gt;
            catch (SqlException ex)&lt;br /&gt;
            {&lt;br /&gt;
                throw ex;&lt;br /&gt;
            }&lt;br /&gt;
            finally&lt;br /&gt;
            {&lt;br /&gt;
                if (sqlConnection != null)&lt;br /&gt;
                    sqlConnection.Close(); //close the connection   &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
This is only an example but the use of the Validators can be very important in all the contexts in which the protection of a database from malicious input is needed.&lt;br /&gt;
&lt;br /&gt;
== .NET Preventing LDAP Injection ==&lt;br /&gt;
&lt;br /&gt;
It’s not important here to explain how LDAP works. The focus is explain how it’s possible to avoid the injection of special character, that are responsible of a unpredictable behaviour of the LDAP server.&lt;br /&gt;
LDAP search are often made with a distinguished name (DN) and a filter. So if the user input is not properly validated, the user can manipulate the input to craft a malicious filter, to obtain more informations from the server.&lt;br /&gt;
LDAP search are made with string, so the best solution to analyze a string searching particular characters is a Regular Expression.&lt;br /&gt;
In this example there is the code associated to a event ButtonClick, and two TextBox called &amp;quot;txtUid&amp;quot; and &amp;quot;txtSn&amp;quot; are used to give input to the system&lt;br /&gt;
&lt;br /&gt;
    protected void btnQuerySearch_OnCLick(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
''' First Section '''&lt;br /&gt;
&lt;br /&gt;
        string regExString = &amp;quot;[a-zA-Z_0-9 @.]+&amp;quot;;&lt;br /&gt;
        RegexStringValidator regEx = new RegexStringValidator(regExString);&lt;br /&gt;
&lt;br /&gt;
The first section uses a Regular Expression, using the class “RegExStringValidator”, very useful to analyze a string. &lt;br /&gt;
The string can contain only alphanumeric characters, @, blank or dot. &lt;br /&gt;
Others characters different from the indicated subset are not allowed, according to the white list approach.&lt;br /&gt;
 &lt;br /&gt;
''' Second Section '''&lt;br /&gt;
&lt;br /&gt;
        if (regEx.CanValidate(txtUid.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtUid.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong uid&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        if (regEx.CanValidate(txtSn.Text.GetType()))&lt;br /&gt;
            try&lt;br /&gt;
            {&lt;br /&gt;
                regEx.Validate(txtSn.Text);&lt;br /&gt;
            }&lt;br /&gt;
            catch (ArgumentException argExec)&lt;br /&gt;
            {&lt;br /&gt;
                // Validation failed.&lt;br /&gt;
                Response.Write(&amp;quot;wrong sn&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
In this section there is the code to check if the strings inserted in the textbox “txtUid” and “txtSn” match the rule of the RegExp or not. There is a try-catch block and the object method &amp;quot;Validate&amp;quot; is used to make the job. If the validation passes, the catch block is not processed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Third Section '''&lt;br /&gt;
&lt;br /&gt;
        LdapConnection connection = new LdapConnection (&amp;quot;192.168.1.36&amp;quot;);&lt;br /&gt;
        connection.AuthType = AuthType.Anonymous;&lt;br /&gt;
        string DN = &amp;quot;uid=john,ou=people,dc=example,dc=com&amp;quot;;&lt;br /&gt;
        LdapSessionOptions options = connection.SessionOptions;&lt;br /&gt;
        options.ProtocolVersion = 3;&lt;br /&gt;
&lt;br /&gt;
The third section is the place for the connection to the server. &lt;br /&gt;
&lt;br /&gt;
''' Fourth Section '''&lt;br /&gt;
&lt;br /&gt;
        try&lt;br /&gt;
        {&lt;br /&gt;
            Response.Write(&amp;quot;\r\nPerforming a simple search ...&amp;quot;);&lt;br /&gt;
            // create a search filter to find all objects&lt;br /&gt;
            string ldapSearchFilter = &amp;quot;(&amp;amp;(uid=&amp;quot; + txtUid.Text + &amp;quot;)(sn=&amp;quot; + txtSn.Text + &amp;quot;))&amp;quot;;&lt;br /&gt;
            DirectoryRequest searchRequest = new SearchRequest&lt;br /&gt;
                                            (DN,&lt;br /&gt;
                                              ldapSearchFilter,&lt;br /&gt;
                                              System.DirectoryServices.Protocols.SearchScope.Base,&lt;br /&gt;
                                              null);&lt;br /&gt;
            //cast the returned directory response as a SearchResponse object&lt;br /&gt;
            DirectoryResponse response;&lt;br /&gt;
            response = (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            SearchResponse searchResponse =&lt;br /&gt;
                        (SearchResponse)connection.SendRequest(searchRequest);&lt;br /&gt;
            Response.Write(&amp;quot;\r\nSearch Response Entries &amp;quot; + searchResponse.Entries.Count);&lt;br /&gt;
            // enumerate the entries in the search response&lt;br /&gt;
            foreach (SearchResultEntry entry in searchResponse.Entries)&lt;br /&gt;
            {&lt;br /&gt;
                Response.Write(&amp;quot;indexof , DN &amp;quot; + searchResponse.Entries.IndexOf(entry) + entry.DistinguishedName);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        catch (Exception ex)&lt;br /&gt;
        {&lt;br /&gt;
            throw ex;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Finally it's made the request and the server make the response, giving the number of entries that found&lt;br /&gt;
&lt;br /&gt;
== Web.config Encryption ==&lt;br /&gt;
&lt;br /&gt;
Web.config (and others file with .config extension) could contain sensitive informations that should be protected. For a Web Application tipically the parameter configuration to acces to a database are stored in plain text, in a form like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;configuration&amp;gt;&lt;br /&gt;
  &amp;lt;appSettings&amp;gt;&lt;br /&gt;
    &amp;lt;add key=&amp;quot;webRefFromSql.ProvaSql1&amp;quot; value=&amp;quot;http://win2k3/ProvaSQL/ProvaSQL1&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/appSettings&amp;gt;&lt;br /&gt;
  &amp;lt;connectionStrings&amp;gt;&lt;br /&gt;
    &amp;lt;add name=&amp;quot;SQLServer2005Express&amp;quot; connectionString=&amp;quot;Data Source=localhost\SQLEXPRESS; Initial Catalog=Exampledb; User Id=user;    &lt;br /&gt;
              Password=clgir3s2s;&amp;quot; providerName=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/connectionStrings&amp;gt;&lt;br /&gt;
  &amp;lt;system.web&amp;gt;    &lt;br /&gt;
    &amp;lt;compilation debug=&amp;quot;true&amp;quot;&amp;gt;            &lt;br /&gt;
    &amp;lt;/compilation&amp;gt;    &lt;br /&gt;
    &amp;lt;authentication mode=&amp;quot;Windows&amp;quot;/&amp;gt;    &lt;br /&gt;
  &amp;lt;/system.web&amp;gt;&lt;br /&gt;
 &amp;lt;/configuration&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/default.aspx&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/6759sth4.aspx&lt;br /&gt;
* http://directoryprogramming.net/&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/system.configuration.regexstringvalidator.aspx&lt;br /&gt;
* http://www.ietf.org/rfc/rfc2254.txt&lt;br /&gt;
* http://msdn.microsoft.com/en-us/library/az24scfc(VS.80).aspx&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32920</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32920"/>
				<updated>2008-06-30T21:23:03Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings. Otherwise revoke the permission with:&lt;br /&gt;
&lt;br /&gt;
 REVOKE ALTER SETTINGS TO userToConnect&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32919</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32919"/>
				<updated>2008-06-30T21:19:23Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
If there are one o more results, look at the first column. The possibilities for the &amp;quot;role_principal_id&amp;quot; are:&lt;br /&gt;
* 3=sysadmin&lt;br /&gt;
* 4=securityadmin&lt;br /&gt;
* 5=serveradmin &lt;br /&gt;
* 6=setupadmin&lt;br /&gt;
* 7=processadmin&lt;br /&gt;
* 8=diskadmin&lt;br /&gt;
* 9=dbcreator&lt;br /&gt;
* 10=bulkadmin&lt;br /&gt;
&lt;br /&gt;
So if the 'userToConnect' doesn't have in the results number 3 or 5, doesn't belong to those roles. However it's not sufficient. Another check must be done. So launch&lt;br /&gt;
&lt;br /&gt;
 SELECT x.permission_name FROM sys.server_permissions x&lt;br /&gt;
 INNER JOIN sys.server_principals y&lt;br /&gt;
 ON x.grantee_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect' &lt;br /&gt;
&lt;br /&gt;
If the results don't have the permission ALTER SETTINGS, the &amp;quot;userToConnect&amp;quot; can't modify the server settings.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32917</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32917"/>
				<updated>2008-06-30T20:36:14Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that, after installation, have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
To look that, there are some system stored procedure used to view roles and permission for a LOGIN. Imagine for example that a web application connect to a database with a SQL Login called 'userToConnect'.&lt;br /&gt;
To see if this user belong to sysadmin or serveradmin roles, it's possible to digit:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM sys.server_role_members x&lt;br /&gt;
 INNER JOIN  sys.server_principals y&lt;br /&gt;
 ON x.member_principal_id = y.principal_id&lt;br /&gt;
 WHERE y.name = 'userToConnect'&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32914</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32914"/>
				<updated>2008-06-30T18:47:19Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
In SQL Server there are two roles that have ALTER SETTINGS permission:&lt;br /&gt;
* sysadmin&lt;br /&gt;
* serveradmin&lt;br /&gt;
So it's necessary that the LOGIN used to connect to a database for an application doesn't belong to these roles, and at the same time doesn't have the ALTER SETTINGS permission.&lt;br /&gt;
In this manner, there will be not possible to re-enable, for example, xp_cmdshell.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32913</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32913"/>
				<updated>2008-06-30T18:42:01Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To disable this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',0&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32773</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32773"/>
				<updated>2008-06-29T15:51:02Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think in an &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32771</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32771"/>
				<updated>2008-06-29T15:50:35Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administratives tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
and automatically the xp_cmdshell would be enabled.&lt;br /&gt;
The solutions technically could be:&lt;br /&gt;
* Dropping the sp_configure&lt;br /&gt;
* Configuring in a right manner the LOGIN inside the Sql Server&lt;br /&gt;
&lt;br /&gt;
The first solution is not good, because dropping system stored procedure could cause anomalies when it's time to patching the server with the last updates/upgrades.&lt;br /&gt;
So it's better to think ina a &amp;quot;administrative manner&amp;quot;&lt;br /&gt;
For example, sp_configure with zero or one parameter could be executed by everyone. But sp_configure with two parameters (necessary to re-enable xp_cmdshell) could be executed by users that have ALTER SETTINGS permission.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32748</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32748"/>
				<updated>2008-06-29T15:18:58Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administrative tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So even if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell), if the application is vulnerable, a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32724</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32724"/>
				<updated>2008-06-29T14:12:25Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administrative tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So it's not so good if the server is well configurated avoiding every dangerous stored procedure (such as xp_cmdshell) and a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32714</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32714"/>
				<updated>2008-06-29T13:19:41Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administrative tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure''' in conjunction with '''RECONFIGURE''' command to modify the server's configuration.&lt;br /&gt;
So it's not so good if the server is configurated avoiding every dangerous stored procedure (such as xp_cmdshell) and a sql injection can cause the execution of the script:&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32706</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32706"/>
				<updated>2008-06-29T13:12:16Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* System Stored Procedure (xp_cmdshell) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure ===&lt;br /&gt;
&lt;br /&gt;
Sql Server provides a lot of system stored procedures, to accomplish administrative tasks.&lt;br /&gt;
Surface Configuration Area for features for example is a graphical interface that uses, as it's showed, the stored procedure '''sp_configure'''.&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32678</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32678"/>
				<updated>2008-06-29T12:21:19Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the extended stored procedure &amp;quot;xp_cmdshell&amp;quot;. By definition &amp;quot;executes a command string as an operating-system command shell and returns any output as rows of text&amp;quot;.&lt;br /&gt;
Enabling xp_cmdshell is potentially very dangerous, because it allows a complete interaction with the operating system, so it's possible to give every command. It's better to do administratives tasks not using SQL Server, so mantain disable xp_cmdshell.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'xp_cmdshell',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32675</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32675"/>
				<updated>2008-06-29T12:12:16Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email using MAPI protocol. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable stored procedures to generate HTML report from the data results. It's deprecated because there are others components (like Reporting Services) to present data in a browser.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Web Assistant Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32669</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32669"/>
				<updated>2008-06-29T11:58:00Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
SQL Mail is a feature for legacy applications, supported for backward compatibility, to send and receive email. This is replaced by Database Mail Feature.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'SQL Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32659</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32659"/>
				<updated>2008-06-29T11:10:19Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''SQL Mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Web Assistant stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''xp_cmdshell''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32658</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32658"/>
				<updated>2008-06-29T11:07:05Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint for SOAP, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints is created)&lt;br /&gt;
&lt;br /&gt;
Service Broker is a technology in which two or more entities accomplish a task, sending and receiving messages, in a asynchronous mode. As XML Web Services, to use this feature, a Service Broker endpoint must be created.&lt;br /&gt;
A Service Broker endpoint listens on a specific TCP port numberm (tipically 4022, but could be configured during the endpoint's creation).&lt;br /&gt;
The authentication against Service Broker could be BASIC, DIGEST, NTLM, KERBEROS, INTEGRATED.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create a TCP endpoint for SERVICE_BROKER, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32654</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32654"/>
				<updated>2008-06-29T09:55:29Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no SOAP endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature allows access properties and methods of an ActiveX object within SQL Server. If it's necessary to obtain informations inside a DLL that is not available inside SQL Server, it's possible to use some stored procedure to do the work, enabling this feature, but it's better to access the object with the right language, not with T-SQL.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ole Automation Procedures',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Service Broker''' (default no Service Broker endpoints are created)&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32650</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32650"/>
				<updated>2008-06-29T09:28:04Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
'''OLE Automation stored procedures''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32646</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32646"/>
				<updated>2008-06-29T08:21:32Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default no endpoints are created)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32645</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32645"/>
				<updated>2008-06-29T08:20:43Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint, and then start or stop the service, with the Surface Area Reduction tool.&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32604</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32604"/>
				<updated>2008-06-28T15:23:22Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
To use this feature, first thing is to create an HTTP endpoint, and then enable the endpoint&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32603</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32603"/>
				<updated>2008-06-28T15:03:01Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
To use this feature, firs create an HTTP endpoint, and then enable the endpoint&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32602</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32602"/>
				<updated>2008-06-28T14:37:13Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Native XML Web services''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature basically gives the possibility to use SQL Server as a Web Services provider. It's possible to create HTTP Endpoints in Sql Server, associated for example to a result of stored procedure.&lt;br /&gt;
A SOAP client could consume a service simply invoking the correct url provided by Sql Server, without others layers (tipically an IIS web server in wich the web services are hosted).&lt;br /&gt;
Enabling this feature and create HTTP endpoints goes in the direction to increase the surface of attack. Every client could produce SOAP request, because SOAP grounds on its working to XML and HTTP, two standards.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32601</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32601"/>
				<updated>2008-06-28T14:07:08Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlInstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Database mail''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
The database mail feature enables the possibility to use the Sql Server Instance to send email. If it's a powerful solution to give some advices to a sysadmin, from a security point of view it's a good practice to use the instance with the only aims that needed.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Database Mail XPs',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32600</id>
		<title>OWASP Backend Security Project SQLServer Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Backend_Security_Project_SQLServer_Hardening&amp;diff=32600"/>
				<updated>2008-06-28T13:42:05Z</updated>
		
		<summary type="html">&lt;p&gt;GPederzini: /* Surface Area Reduction (features) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
In this section there are some best practices concerning the security of SQL Server 2005. The operating system under SQL Server is Windows Server 2003.&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
&lt;br /&gt;
== Installation of the Engine ==&lt;br /&gt;
The prerequisites for the installation are:&lt;br /&gt;
* .NET Framework 2.0&lt;br /&gt;
* Microsoft SQL Native Client&lt;br /&gt;
* Microsoft SQL Server 2005 Setup Support Files.&lt;br /&gt;
&lt;br /&gt;
The installation consist of a large amount of services that are shortly descripted:&lt;br /&gt;
* SQL Server Database Services (install SQL Server database engine and tools for managing relational and XML data, replication and full text search)&lt;br /&gt;
* Analysis Services (install analysis services and tools used to support online analytical procession OLAP and data mining. Install also Integration Services)&lt;br /&gt;
* Notification Services (installs notification services a platform for developing and deploying applications that send personalized, timely notifications to a variety of devices or applications)&lt;br /&gt;
* Integration Services (install a set of tools and programmable objects for creating and managing packages that extract, transofrm and load data, as well perform task)&lt;br /&gt;
* Client Components (install management tools, development tools and legacy components)&lt;br /&gt;
* Documentation, samples and sample databases (installs books online documentation, sample databases and sample applications for all sql 2005 components)&lt;br /&gt;
During the installation the thing to remind is that from a security point of view, only what is strictly needed must be installed. To install a tipycal minimal configuration, the SQL Server Database Services and some Client Components (Connectivity components and  Management Tools) can be installed.&lt;br /&gt;
=== Services ===&lt;br /&gt;
In SQL Server every service can run under a particular Windows account. The choices for the service's accounts are:&lt;br /&gt;
&lt;br /&gt;
* Local user that is not a Windows administrator &lt;br /&gt;
* Domain user that is not a Windows administrator&lt;br /&gt;
* Local Service account&lt;br /&gt;
* Network Service account&lt;br /&gt;
* Local System account&lt;br /&gt;
* Local user that is a Windows administrator&lt;br /&gt;
* Domain user that is a Windows administrator&lt;br /&gt;
&lt;br /&gt;
There is not only a solution to configure the service's account, but there are two rules to follow that enforce to behave in certain way:&lt;br /&gt;
* minimum privileges&lt;br /&gt;
* account isolation&lt;br /&gt;
Follow this, probably an administrator account (local or domain) has much more privileges than needed, indipendently of the service.&lt;br /&gt;
The Local System account has to many privileges and it's not indicated for a service's account&lt;br /&gt;
On the other hand Local Service and Network Service have not much privileges, but they are used for more Windows services, so there is no account isolation.&lt;br /&gt;
&lt;br /&gt;
So the more secure solution for the Sql Server Service's Account is to use Local User or Domain User not Administrators. &lt;br /&gt;
For example imagine that are installed the trhee main services:&lt;br /&gt;
* Sql Server&lt;br /&gt;
* Sql Server Agent&lt;br /&gt;
* Sql Server Browser&lt;br /&gt;
The task is to create three Windows Local User Account, belonging to User Group, protected with password, and assign them to the services.&lt;br /&gt;
In this manner there are exactly two concepts: minimum privileges and account isolation.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Mode ===&lt;br /&gt;
Sql Server provides two kinds of authentication: SQL Server Authentication and Windows Authentication. During the installation is possible to enable both (Mixed Mode) or only the Windows Authentication (Windows Mode)&lt;br /&gt;
&lt;br /&gt;
If there is an homogeneous Windows environment, the more secure solution is to enable the Windows mode Authentication, because the administration of the logins is made in the Windows Server and the credentials are not passed through the network, because Windows Authentication uses NTLM or Kerberos Protocols.&lt;br /&gt;
If there is an heterogeneous environment, for example no domain controller or there are some legacy applications that have to connect to Sql Server, only the Mixed Mode solution is possible. In this second case the administration of the logins is made inside SQL Server and the credentials are necessarily passed through the network.&lt;br /&gt;
&lt;br /&gt;
Is important to say that in a Windows Mode Authentication, the &amp;quot;sa&amp;quot; user (system administrator) is not enabled. In a mixed mode is enabled. &lt;br /&gt;
So in an environment with Mixed Mode Authentication, to avoid the attacks against &amp;quot;sa&amp;quot; user, is better to:&lt;br /&gt;
* rename &amp;quot;sa&amp;quot; with another name&lt;br /&gt;
* use a strong password for the renamed &amp;quot;sa&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Processes ===&lt;br /&gt;
Every services that is installed in Sql Server could be administrated through the tool &amp;quot;Sql Server Configuration Manager&amp;quot; that is possible to install, enabling the client component of Sql Server.&lt;br /&gt;
With this tool is possible to realize the two best practices for the account's services, assigning to every service a specific account protected with password, that authenticates against Windows.&lt;br /&gt;
Every service could be started or stopped in a manual or automatic manner, like other Windows Services.&lt;br /&gt;
&lt;br /&gt;
== Configuration tools provided ==&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (services and connections) ===&lt;br /&gt;
The Surface Area Reduction is a powerful tool provided with Sql Server 2005 to configure:&lt;br /&gt;
* Services &amp;amp; Connections&lt;br /&gt;
&lt;br /&gt;
'''Services'''&lt;br /&gt;
&lt;br /&gt;
Every Service installed could be rapidly managed. It's posssible in every moment to:&lt;br /&gt;
* Manage the status of the service with the possibilities: Start/Stop &amp;amp; Pause/Resume&lt;br /&gt;
* Manage the action of the operating system on startup for that service: Automatic, Manual, Disabled.&lt;br /&gt;
&lt;br /&gt;
The concept is to configure automatic start only for those services that are immediately needed, disabling or manually starting others services that are not necessary.&lt;br /&gt;
&lt;br /&gt;
'''Connections'''&lt;br /&gt;
&lt;br /&gt;
For every instance of SQL Server is possible to allow:&lt;br /&gt;
* Only local connection to the server&lt;br /&gt;
* Local and remote connections to the server&lt;br /&gt;
In a distributed environment probably it's necessary to allow both the connection's type, but it's easy to understand that allowing remote connections expose the server more easily.&lt;br /&gt;
So for the remote connections Sql Server could allow two kind of protocols:&lt;br /&gt;
* TCP/IP&lt;br /&gt;
* Named Piped&lt;br /&gt;
For the normal use the better thing is to configure only TCP/IP, because Named Pipes need more open port to work.&lt;br /&gt;
Additionally there are others two kinds of connections to the server:&lt;br /&gt;
* VIA&lt;br /&gt;
* Shared Memory&lt;br /&gt;
VIA (Virtual Interface Adapter protocol ) works with VIA hardware. Shared Memory is a protocol that is possible to use only by local connections. &lt;br /&gt;
Using the Sql Server Configuration Manager the best solution is enable TCP/IP for remote connections and Shared Memory for the local connections.&lt;br /&gt;
&lt;br /&gt;
=== Surface Area Reduction (features) ===&lt;br /&gt;
This is a series of interfaces for enabling or disabling many Database Engine, Analysis Services, and Reporting Services features. The most important are the features of the Database Engine: &lt;br /&gt;
&lt;br /&gt;
* Ad hoc distributed queries&lt;br /&gt;
* Common language runtime (CLR) integration	&lt;br /&gt;
* Dedicated administrator connection (DAC)	&lt;br /&gt;
* Database Mail	&lt;br /&gt;
* Native XML Web services	&lt;br /&gt;
* OLE Automation stored procedures&lt;br /&gt;
* Service Broker&lt;br /&gt;
* SQL Mail&lt;br /&gt;
* Web Assistant stored procedures&lt;br /&gt;
* xp_cmdshell&lt;br /&gt;
&lt;br /&gt;
'''Ad hoc distributed queries''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enable the OPENROWSET and OPENDATASOURCE calls, to connect to an OLE DB data source. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'Ad Hoc Distributed Queries',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
It's recommended to disable this feature, because in a case of Sql Injection, an attacker could use OPENROWSET to connect to a database.&lt;br /&gt;
&lt;br /&gt;
'''Common language runtime (CLR) integration''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature give the possibility to write stored procedures, triggers, user defined functions using a .NET Framework language. So if the server is not used with this aim, or if all the databases object are written with T-SQL, there's no reason to enable this. To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'clr enabled',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
'''Dedicated administrator connection (DAC)''' (default is disabled)&lt;br /&gt;
&lt;br /&gt;
This feature enables the possibility to execute diagnostics queries and troubleshoot problems when there are some problems to connect with standard mode to the server.&lt;br /&gt;
The uses are tipically:&lt;br /&gt;
&lt;br /&gt;
* Querying some dynamic management views of SQL Server to obtain informations about the &amp;quot;status health&amp;quot;&lt;br /&gt;
* Basic DBCC commands (for example DBCC SHRINKDATABASE to cut the log file)&lt;br /&gt;
* Kill the PID of processes&lt;br /&gt;
&lt;br /&gt;
But for example is possible to do other works, like add logins with sysadmin privileges or other administrator's tasks&lt;br /&gt;
This is an emergency type of connection, that SQL Server can permit every time, reserving an amount of resources during startup. It permits only a user a time, so if there is an user connected via DAC, no others users can connect. It's possible to use it with SQLCMD or Sql Server Management Studio, through the sintax:&lt;br /&gt;
&lt;br /&gt;
 Admin:&amp;lt;namepc&amp;gt;\&amp;lt;nameSqlIstance&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So DAC is only another type of connection, and in every time the credentials must be given to the server, but if it's not necessary, disable it.&lt;br /&gt;
To use this feature launch:&lt;br /&gt;
&lt;br /&gt;
 EXEC sp_configure 'remote admin connections',1&lt;br /&gt;
 GO&lt;br /&gt;
 RECONFIGURE&lt;br /&gt;
 GO&lt;br /&gt;
&lt;br /&gt;
=== Sql Server Configuration Manager (endpoints and protocols) ===&lt;br /&gt;
=== Sql Server Administrators ===&lt;br /&gt;
=== System Stored Procedure (xp_cmdshell) ===&lt;br /&gt;
&lt;br /&gt;
== Database Administration ==&lt;br /&gt;
&lt;br /&gt;
=== Password Policies ===&lt;br /&gt;
=== Authorization ===&lt;br /&gt;
=== Roles and Schemas ===&lt;br /&gt;
=== Metadata Views ===&lt;br /&gt;
=== Linked Servers ===&lt;br /&gt;
=== Execution Context ===&lt;br /&gt;
&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&lt;br /&gt;
=== Symmetric ===&lt;br /&gt;
=== Asymmetric ===&lt;br /&gt;
=== Asymmetric with certificate ===&lt;br /&gt;
&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>GPederzini</name></author>	</entry>

	</feed>