Wednesday, October 24, 2007

10 Warning Signs of Project Failure

This is a great article that outlines the 10 signs that a project is going to fail which written by Allen Bernard.

What are the signs you agree with? I think that Undefined or poorly defined project requirements and lack of or poorly developed budget forecast are the real problems.

Technorati Tags:

Astoria DataSource Extender

PhaniRajuYN posted a very interesting post about Astoria DataSource Extender. (You can read my Getting Started With Astoria post to get more details about Astoria). The main issue is that it's a "Database in the cloud", which means that your database is hosted on the Web.

PhaniRajuYN Extender helps one retrieve data and post data to a database on Astoria using JavaScript.
The Extender encapsulates its own Server-Side handler so that  you don't have to write a Server-Side proxy to avoid Making Cross-Domain Requests from the Client browser.

You can read the post and download the source and sample from here.

Saturday, October 20, 2007

How to prevent SQL injections

Many applications include code that looks like:

   1:  string sqlStmt = "SELECT * FROM USERS WHERE UserName= '" + un + "' AND Password='" + pwd + "'";

Admit it...it's ugly, but you constructed SQL statements like this one.


The variables un,pwd are provided by the user. The problem with this SQL string is that the attacker can piggyback SQL statements in one of them.


What if the attacker enters this:


un = maor, pwd = 123456' OR 1=1. The following malicious statement is built:


   1:  string sqlStmt = "SELECT * FROM USERS WHERE UserName= 'maor' AND Password='123456' OR 1=1";

The statement will return all columns for all rows...Bad!


And what if the attacker enters this:


un=maor , pwd = 123456' DROP TABLE Users. The following malicious statement is built:


   1:  string sqlStmt = "SELECT * FROM USERS WHERE UserName= 'maor' AND Password='123456' DROP TABLE Users";

This builds SQL statement that queries for a user and then drops the users table.


What can you do prevent these attacks?


1. Quoting the input


Quoting the input is not a remedy, but its often proposed to solve the problem.


if we use the statement of:


   1:  string pwd;
   2:  pwd = pwd.Replace("'","''");

The code replaces single quotes with 2 single quotes in the input. The single quote is escaped and its render to invalid SQL statement. However its not perfect. If the statement has a integer field the attacker can use it to attack.


2. Use stored procedures


Many of us probably believe that the application is immune to SQL injection if we use stored procedures. WRONG!


When we enter the 123456' OR 1=1 to a parameter the sp will fail cause we cannot perform join across a stored procedure call. However, performing data manipulation is valid.


   1:  exec sp_getUser 'maor','123456' INSERT INTO Users Values('123','123')

This command will fetch data about the user and then insert a new row into the users table! What we can do? secure the stored procedure. How?



  1. Use quotename function for object names. It's built in T-SQL function that adds delimiters to object names to help nullify invalid characters.
  2. Use sp_executesql to execute sql statements built dynamically, instead of just concatenating a string. This makes sure no malformed parameters are passed along to the database server.

3. Never connect as sysadmin


If you see that your web application connects to the database as sysadmin account - its a BUG. Most of the web applications don't need the capabilities of a sysadmin to run; If there is a bug in the SQL statements and the application connects as sysadmin account, the attacker can: delete any database or table in the server; delete any table data; change data; alter tables; deletes log; and more... The potential damage is unlimited.


4. Build secure SQL statements


Instead of dynamically building a string, as shown in the bad examples above, use parameters. Anything placed into a parameter will be treated as field data, not part of the SQL statement, which makes your application much more secure.


Using parameterized queries is a three step process:


  1. Construct the SqlCommand command string with parameters.
  2. Declare a SqlParameter object, assigning values as appropriate.
  3. Assign the SqlParameter object to the SqlCommand object's Parameters property.

   1:  // 1. declare command object with parameter
   2:  SqlCommand cmd = new SqlCommand(
   3:      "SELECT * FROM USERS WHERE UserName= @UN AND Password= @PWD", conn);
   4:   
   5:  // 2. define parameters used in command object
   6:  SqlParameter param1 = new SqlParameter();
   7:  param1.ParameterName = "@UN";
   8:  param1.Value = userName;
   9:   
  10:  SqlParameter param2 = new SqlParameter();
  11:  param2.ParameterName = "@PWD";
  12:  param2.Value = password;
  13:   
  14:   
  15:  // 3. add new parameter to command object
  16:  cmd.Parameters.Add(param1);
  17:  cmd.Parameters.Add(param2);


Summary



  • Don't trust the user's input.
  • Be strict about what represent valid input and reject everything else. RegEx are your friend!!!
  • Use parameterized queries not string concatenation.
  • Connect to the database server by using a least-privilege account, not the sysadmin account.

Code secure!!!!


Technorati Tags: , , ,

Wednesday, October 17, 2007

.NET Framework Multi Targeting in Visual Studio 2008

One of the great features in Visual Studio 2008 is the ".NET Framework Multi Targeting".  This allows you to build applications targeting any of these frameworks using Visual Studio 2008:

  • .NET Framework 2.0 - released with Visual Studio 2005
  • .NET Framework 3.0 - released with Windows Vista
  • .NET Framework 3.5 - will release with Visual Studio Orcas

After I built a project targeted .NET framework 2.0 I encountered problem on a machine with .NET framework 2.0 installed.

It turns out that when installing Visual Studio 2008, it also install .NET framework 2.0 SP1. Hence, this means that when you target .NET 2.0 in Visual Studio 2008, you are really targeting .NET 2.0 SP1.

To run applications which built with Visual Studio 2008 and targeted to .NET framework 2.0, be aware that you need NET framework 2.0 SP1 on the application's host.

Saturday, October 13, 2007

Gmail's Storage Increases to 6 GB

gmailI read at Google Operating System blog that Gmail will increase the free storage gradually in the next days. On October 23, you'll get 4321 MB of storage, then the growth will slow down until January 4, when you'll have 6283 MB of storage.

That's really great.

Read more here.

Technorati Tags: ,

Linq to XML - Adding,Updating and Deleting data

The previous post about Linq to XML introduced how to query XML data using LINQ. LINQ allows us to not only query XML in a truly unique way, but also create XML documents in a very expressive manner. This post will talk about other operations on the XML: adding, updating and deleting data.

First, lets create a sample XML document:

   1:  XElement book = new XElement("Books", new XElement("Book",
   2:      new XAttribute("publisher", "O'Reilly Media, Inc."),
   3:          new XAttribute("price", "40$"),
   4:          new XElement("title", "Learning WCF: A Hands-on Guide"),
   5:          new XElement("authors", new XElement("author", "Michele Bustamante"))));
   6:   
   7:  book.Save("Books.xml");

Adding data to the XML document


Adding XML to the existing XML document is very simple, we need only construct our XML using a mixture of XElement and XAttribute types (there are other ways also...) and then add them to the document.


The following adds a new book:


   1:  XElement doc = XElement.Load("Books.xml");
   2:  XElement newBook = new XElement("Book",
   3:      new XAttribute("publisher", "Microsoft Press"),
   4:      new XAttribute("price", "45$"),
   5:      new XElement("title", "Introducing Microsoft LINQ"),
   6:      new XElement("authors", new XElement("author", "Paolo Pialorsi"), 
   7:          new XElement("author", "Marco Russo")));
   8:   
   9:  doc.Add(newBook);
  10:  doc.Save("Books.xml");

We must save the xml with the save method, because in LINQ to XML, no changes are made to the loaded XML document until that document is saved.


The XML document now is:


   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <Books>
   3:    <Book publisher="O'Reilly Media, Inc." price="40$">
   4:      <title>Learning WCF: A Hands-on Guide</title>
   5:      <authors>
   6:        <author>Michele Bustamante</author>
   7:      </authors>
   8:    </Book>
   9:    <Book publisher="Microsoft Press" price="45$">
  10:      <title>Introducing Microsoft LINQ</title>
  11:      <authors>
  12:        <author>Paolo Pialorsi</author>
  13:        <author>Marco Russo</author>
  14:      </authors>
  15:    </Book>
  16:  </Books>

Updating data


Updating XML data is also very simple; Just pick the element/attribute you wish to update and then set its new value.


   1:  XElement doc = XElement.Load("Books.xml");
   2:   
   3:  //obtain a single book
   4:  IEnumerable<XElement> singleBook = (from b in doc.Elements(
   5:                                        "Book")
   6:                                      where ((string)b.Element(
   7:                                      "title")).Equals("Introducing Microsoft LINQ")
   8:                                      select b);
   9:   
  10:  //update book, should only be 1
  11:  foreach (XElement xe in singleBook)
  12:  {
  13:      xe.SetAttributeValue("price", "39$");
  14:      
  15:      //use the ReplaceContent method to do the replacement for all attribures
  16:      //this will remove all other attributes and save only the price attribute
  17:      xe.ReplaceAttributes(new XAttribute("price", "32$"));
  18:  }
  19:   
  20:  doc.Save("Books.xml");

Deleting data


We simply have to get the object we want to delete and then delete it using the Remove() method.


   1:  XElement doc = XElement.Load("Books.xml");
   2:   
   3:  //obtain the first Book
   4:  IEnumerable<XElement> firstBook = (from b in doc.Elements(
   5:                                        "Book")
   6:                                        select b).Take(1);
   7:   
   8:  //delete book price
   9:  foreach (XElement xe in firstBook)
  10:  {
  11:      xe.Attribute("price").Remove();
  12:  }
  13:   
  14:  doc.Save("Books.xml");

Other way: we pass a lambda expression in as an argument to the Where extension method.

As you can see, Xlinq is really simple and great way to work with XML.


Enjoy!


Wednesday, October 10, 2007

Create custom task for MSBuild - Step by Step

This is the 2nd post in the msbuild posts series. The first post was an introduction to MSBuild and give you tasting of the basics.

In order to extend Team Foundation Build by plugging in your own logic and tasks, you must write a custom task and use it in your build script (the .proj file).

Custom MSBuild task must be implemented as a .NET class that implements the ITask interface, which is defined in the Microsoft.Build.Framework.dll assembly. You can implement your task in the following two ways:

  1. Derive your class directly from ITask and implement the methods on this interface. or
  2. Derive your class from the helper class, Task (an abstract base class that is a default implementation for BuildEngine and HostObject properties) which is defined in the Microsoft.Build.Utilities.dll assembly. Choosing this option makes it easier to log events from your task.

In both cases you must implement (ITask) or override (Task) it's Execute method. I override this mwthod with a very simple logic to just log a string value to the Build log as you see below.

Step 1 - Creating project

Create Class Library project with a class and a reference to Microsoft.Build.Utilities assembly. I'll derive the class from the Task abstract class and override the Execute method.

Step 2 - Writing the task

Execute function must return true if task has executed successfully otherwise it must return false. Now I will add my code to the Execute method - this is my logic which I want to be executed during the build process. I also add a property to the class (Message) and set an attribute to it [Required] (line 29) - this indicates that msbuild must pass a parameter to the task. The Log ( line 17,24) object I use is the LoggingHelper of the Build Utilities (defined at Microsoft.Build.Utilities.dll )

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using Microsoft.Build.Utilities;
   5:  using Microsoft.Build.Framework;
   6:   
   7:  namespace MSBuildTasks
   8:  {
   9:      public class MyTask:Task
  10:      {
  11:          private string message;
  12:   
  13:          public override bool Execute()
  14:          {
  15:              try
  16:              {
  17:                  Log.LogMessage(
  18:                      String.Format("This is the message from my task: {0}",
  19:                      message));
  20:                  return true;
  21:              }
  22:              catch
  23:              {
  24:                  Log.LogError("Error occured in my task!");
  25:                  return false;
  26:              }
  27:          }
  28:   
  29:          [Required]
  30:          public string Message
  31:          {
  32:              get { return message; }
  33:              set { message = value; }
  34:          } 
  35:   
  36:      }
  37:  }

Now compile the project.


Step 3 - Registering the task in MSBuild file


Now we need to import and register this custom task to the MSBuild file we want to extend (This is because MSBuild must know how to locate the assembly that contains the task class.) . We'll do it by editing the .proj file of the build and add a <UsingTask> element which is a direct child of root <Project> element.  This element has a TaskName attribute to get the name of the task class and an AssemblyFile attribute to get the name or address of the assembly where this class is implemented in.

<UsingTask 
TaskName="MSBuildTasks.MyTask" AssemblyFile="C:\Work\Projects\Samples\MSBuild\MSBuildTasks\bin\Debug\MSBuildTasks.dll"/>

Step 4 - Calling the task from MSBuild


Calling the task depends on the point in the build process where we want to call. We should choose the point in the process that we want to call the task and add the following under it:


   1:  <Target Name="MyTaskTarget">
   2:      <MyTask Message="Hi MSBuild" />
   3:    </Target>

Line 2 calls the task. The message here is the required parameter to pass to the task.


Step 5 - Running the MSBuild file


After all of that you should run the msbuild file.


This is my MSBuild file (.proj extension)

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="MSBuildTasks.MyTask"
AssemblyFile="C:\MSBuildTasks\MSBuildTasks.dll" />
<Target Name="MyTaskTarget">
<MyTask Message = "Hi MsBuild"/>
</Target>
</Project>

This is the output of the example.


msbuild


Enjoy!!


See you in the next post of the MSBuild series.




Technorati Tags: