Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, February 23, 2021

ASP.NET/C#: OleDb example, reading from DB


public void example()
{

    string sql = string.Concat("SELECT f1, f2 FROM table1",
                                               " WHERE id=?");


    using (OleDbConnection connection = new OleDbConnection(AppSettings.getConnectionString()))
    {
        // The insertSQL string contains a SQL statement that
        // inserts a new row in the source table.
        OleDbCommand command = new OleDbCommand(sql, connection);
 

        command.Parameters.AddWithValue("@id", 10);

        // Open the connection and execute the command.
        try
        {
            connection.Open();

            OleDbDataReader reader = command.ExecuteReader();

            while (reader.Read())

            {

                string str1 = reader.GetString(0);

                string str2 = reader.GetString(1); 

                break;

            }
 
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        // The connection is automatically closed when the
        // code exits the using block.
    }
}

ASP.NET/C#: Link a config file to web.config for an extra app-Settings section


Multiple appSettings sections are not allowed in web.config. However, we can add config sections by using <configSections>.

In web.config, add <configSections> at the very beginning of <configuration> element.

<configuration>
    <configSections>
        <section name="appSettingsExtra" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </configSections>
    <
appSettingsExtra configSource="webextra.config">
    </
appSettingsExtra>
    ....
</configuration>


Create a new file webextra.config with the following content:

<appSettingsExtra>
     <add key="TheKey" value="TheValue"/>
</appSettingsExtra>


In the code, to read the parameter from webextra.config:

System.Collections.Specialized.NameValueCollection extraSettings = (System.Collections.Specialized.NameValueCollection)ConfigurationManager.GetSection("appSettingsExtra");
string value = extraSettings["TheKey"];



Tuesday, February 9, 2021

IIS Logs


To find out the IIS logs location of a site:

1. Open IIS Manager;

2. Click the Web Site;

3. Find the Logging icon and double click it;

4. Find the location of the logs in the Directory text box.

 

If you are using IIS Express of the Visual Studio, the logs location of  IIS Express is at %userprofile%\Documents\IISExpress\Logs


In C#, to add infomation to the IIS logs, use:

    Response.AppendToLog("your debug info");

or

    System.Web.HttpContext.Current.Response.AppendToLog("your debug info");

 


Tuesday, December 31, 2019

C# programming: Debug and trace


To generate a trace, use

System.Diagnostics.Trace.WriteLine("some trace");

This code works when TRACE is turned on during compiling. Add the compile option in web.config:

<compilation defaultLanguage="c#" debug="true" targetFramework="4.5">
  <compilers>
    <compiler language="c#" ... compilerOptions="/d:DEBUG;TRACE" />
  </compilers>
</compilation>

During the development, the trace can be found in the Visual Studio's console. If the application is deployed, the trace can be seen with the tool Debugview, which can be downloaded from:

https://docs.microsoft.com/en-us/sysinternals/downloads/debugview


Monday, December 30, 2019

OWASP Top Ten 2017 Examples and Fixes | C# Programming


1. Injection

The problem: SQL Injection

string sql = @"SELECT *  FROM Memos WHERE Id = " + idString;
using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
  cnn.Open();
  OleDbCommand cmd = new OleDbCommand(sql, cnn);
  OleDbDataReader reader = cmd.ExecuteReader();

  while (read.Read())
  {
    ...
  }
}

If idString comes from the user input, it can be manipulated to create unexpected SQL commands.

The fix is to use prepared statement:

string sql = @"SELECT *  FROM Memos WHERE Id = ?";
using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
  cnn.Open();
  OleDbCommand cmd = new OleDbCommand(sql, cnn);

  cmd.Parameters.AddWithValue("@Id", idString);
 
  OleDbDataReader reader = cmd.ExecuteReader();

  while (read.Read())
  {
    ...
  }
}



2. Broken Authentication

The problem: Session is kept after logout

public ActionResult LogOut()
{
  return RedirectToAction("LogOn");
}

The fix is to remove the user session from DB and server side:

public ActionResult LogOut()
{
  string userName = Session["UserName"].ToString();
  db.RemoveUserSession(userName);
  Session.Abandon();
  return RedirectToAction("LogOn");
}


3. Sensitive Data Exposure

The problem: Store password in plain text

var user = new User()
{
  Email = email,
  Login = login,
  Password = password,
  Name = name,
  Role = role
};

The fix is to store the hash so that the password won't be stolen from the memory:

var user = new User()
{
  Email = email,
  Login = login,
  Password = Argon2.Hash(password),
  Name = name,
  Role = role
};


4. XML External Entities (XXE)

var resolver = new XmlUrlResolver();

var settings = new XmlReaderSettings
{
  DtdProcessing = DtdProcessing.Parse,
  XmlResolver = resolver
};

XmlReader reader = XmlReader.Create("items.xml", settings);

The fix:

var resolver = new XmlUrlResolver();

var settings = new XmlReaderSettings
{
  DtdProcessing = DtdProcessing.Prohibit,
  XmlResolver = null
};

XmlReader reader = XmlReader.Create("items.xml", settings);


5. Broken Access Control

The problem: Unvalidated Redirects and Forwards

private ActionResult RedirectToLocal(string retureUrl)
{
  if (!string.IsNullOrEmpty(returnUrl))
  {
    return Redirect(returnUrl);
  }
  return RedirectToAction("Index");
}

The fix is to validate the URL first before redirect:

private ActionResult RedirectToLocal(string retureUrl)
{
  if (Url.IsLocalUrl(returnUrl))
  {
    return Redirect(returnUrl);
  }
  return RedirectToAction("Index");
}


6. Security Misconfiguration

The problem: Information Exposure of Error Details

Logger.LogError(ex.Message + ex.StackTrace);

The fix is to avoid logging stack trace unless it is in debugging:

if (Debugger.IsAttached)
  Logger.LogDebug(ex.Message + ex.StackTrace);

Logger.LogError(ex.Message);


7. Cross Site Scripting (XSS)

userModel.Information = reader["Information"].ToString();

The fix:

string information = reader["Information"].ToString();
string encodedInfo = AntiXssEncoder.HtmlEncode(information, false);
userModel.Information = encodedInfo.ToString();


8. Insecure Deserialization

using (var filestream = File.Open(filename, FileMode.Open))
{
  return DeserializeObject<T>(filestream, settings);
}

The fix is to use encryption/decryption during serialization/deserialization:

using (var filestream = File.Open(filename, FileMode.Open))
{
  using (var cs = new CryptoStream(filestream,
                        CreateRijndael(password).CreateDecryptor(),
                        CryptoStreamMode.Read))
  {
    return DeserializeObject<T>(cs, settings);
  }
}

private static Rijndael CreateRijndael(string password)
{
  var rijndael = Rijndael.Create();
  var pdb = new Rfc2898DeriveBytes(password, Pepper, 1000000);
  rijndael.Key = pdb.GetBytes(32);
  rijndael.IV = pdb.GetBytes(16);
  return rijndael;
}


9. Using Components with Known Vulnerabilities

Linking a file from an untrusted website:

<link href="http://a.company.com/some.styles.css" rel="stylesheet" />

The fix:

 <link href="https://a.trustworthy.website.com/some.styles.css"
       rel="stylesheet" 
       integrity="sha256-......." 
       crossorigin="anonymous" />









10. Insufficient Logging and Monitoring

Console.WriteLine(ex.Message);

The fix:

Logger.LogError(ex.Message);



Thursday, June 13, 2019

ASP.NET: Xml control loading a XML string in a safe way


In the .aspx file:

<asp:Xml id="xml1" runat="server" />


In the .aspx.cs file:

XmlSchema schema = new XmlSchema();
XmlSchemaElement elementRoot = new XmlSchemaElement();
schema.Items.Add(elementRoot);
elementRoot.Name = "root";

XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schema);
settings.ValidationType = ValidationType.Schema;
settings.DtdProcessing = DtdProcessing.Prohibit;   // to prevent XXE attack.
StringReader sr = new StringReader(xmlInString);
XmlReader reader = XmlReader.Create(sr, settings);

xml1.Document.XmlResolver = null;   // to prevent XXE attack.
xml1.Document.Load(reader);

Note: the schema generated has only the root element (as below). If xmlInString contains any type of children elements, it will be validated as good.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root"/>
</xs:schema>


Since Xml.Document is an obsolete property, for the above example, we should use another property DocumentContent. If Schema validation is not needed, we have a much simpler code:

xml1.DocumentContent = xmlInString;


Wednesday, June 12, 2019

ASP.NET: Cross site scripting attack and HtmlEncode


To prevent the Cross Site Scripting (XSS) attack, we should use System.Web.HttpUtility.HtmlEncode() to encode a string before sending it in a response if the string is from an untrusted source.

System.Web.HttpUtility.HtmlEncode will encode these characters:

   Character       Encoded
    <        &lt;
    >        &gt;
    "        &quot;
    &        &amp;
    '        &#39; (.Net 4.0 Only)

Thursday, April 25, 2019

Visual Studio: fix the References in a web site solution or .NET project


A solution can have references to multiple sub-projects. If you make some code changes on a sub-project but the changes do not seem to take effects on the project, the reference may have been broken.

To check the references in the solution, right click on the Web Site on the Solution Explorer. Select Property Pages on the menu.

In the Property Pages dialogue, select References from the listed items. Check on the lists of the references and make sure the Version of all the sub-projects have the values of Auto Update. If it is a specific version number, your changes of the sub-project will have not effect. To change it to Auto Update, use the Remove button to remove the sub-project from the list and then use the Add button to add it back.

You may also be able to add or remove the References from the Solution Explorer for projects. Just expand the project and look for the References item.

Tuesday, April 23, 2019

ASP.NET: logout user and invalidate the session


When logging out the user, we need to abandon the session on the server side and remove the session id from the client side. For example, in the Page_Load() method:

if (!IsPostBack) {
  // Invalidate the old session. A new session will be started.
  Session.Abandon();

  // Clear the session ID from the client side. 
  // Otherwise, the old session ID will be recycled by default.
  Response.Cookies["ASP.NET_SessionId"].Value = "";
}

Wednesday, April 17, 2019

ASP.NET: create an error page to display unhandled exceptions


Step 1: In Global.aspx, create the Application_Error() method to trap the error:

<script runat="server">
... ...
  void Application_Error(object sender, EventArgs e)
  {
    // Transfer the server error to the error page.
    Server.Transfer("~/ErrorPage.aspx");
  }
 ... ...
</script>

Step 2: Add the error message to ErrorPage.aspx:

<body>
... ...
<p><asp:Label ID="errorMessage" runat="server" /></p>
... ...
</body>

Step 3: In the code-behind of ErrorPage.aspx, i.e. ErrorPage.aspx.cs, add code in Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
  Exception ex = Server.GetLastError();
  if (ex != null && ex.GetType() == typeof(HttpUnhandledException))
    ex = ex.InnerException;

  if (ex != null)
    errorMessage.Text = ex.Message;

  Server.ClearError();
... ...
}

However, for security reasons, this version of ErrorPage.aspx should be used only in a development environment. In production, you don't want to display the exceptions to the end user because that might leak information of your system.

Wednesday, April 10, 2019

C#: Write to DB with OleDbCommand and positional Parameters


string sql = "UPDATE Members SET Age = ?, Email = ? WHERE Name = ?";

OleDbConnection conn = new OleDbConnection(connectionString);

int rowsAffected = 0;

try {
  conn.Open();

  OleDbCommand comm = new OleDbCommand(sql, conn);
 
  comm.CommandType = CommandType.Text;
 
  // when CommandType is set to Text, parameter names are not important,
  // but the position of the paramter matters. *
  comm.Parameters.AddWithValue("parm1", intAgeValue);
  comm.Parameters.AddWithValue("parm2", strEmailValue);
  comm.Parameters.AddWithValue("parm3", strNameValue);
 
  rowsAffected = comm.ExecuteNonQuery();
}
catch (Exception ex) {
  // handle ex
}
finally {
  conn.Close();
}



According to Microsoft, the OLE DB.NET Provider does not support named parameters for passing parameters to an SQL Statement when CommandType is set to Text. In this case, the question mark (?) placeholder must be used.  Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter. Ref: https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbcommand.commandtext?view=netframework-4.7.2#remarks
 
Get This <