Sunday, March 25, 2012

Memory used by IIS worker processes

OK, how to find out which worker process in your server is using how much memory?
1. List all the current running Worker Processes.
  • Go to Start-->Run-->cmd
  • This will launch the Command Prompt.
  • In the Command Prompt, change the directory to Windows\System32\inetsrv
  • Run the command appcmd list wp

This will list all of your worker process along with their individual Process IDs.
2. Next launch the Task Manager.
  • In the Task Manager, Go to the Performance tab.
  • Click on the Resource Monitor button.
  • When the Resource Monitor is launched, expand the tab for Memory.
  • From the memory you can order the processes(listed as Image) alphabetically and see which w3wp process is related to which Process ID and what is the memory used by individual worker processes.



Saturday, March 17, 2012

Top 20 measures to secure your ASP.Net Web Application

Inspired by this man's one of the wittiest blog posts and his endless obsession with lists, here is my list of top twenty TO-DO's to secure your ASP.Net applications and sites over the internet:
1. Use SSL when transmitting account information, passwords, user identities over the wire. If you develop things such as a user log in page, registration page or edit profile page etc. keep in mind that people out there would be ready to sniff your traffic for identity information and steal it. SSL is one of the better ways to protect to secure the communication channel and prevent your users' identities from being stolen.
4. Use CAPTCHA validation for anonymous users when they enter data. Great way to stop many types of DOS(Denial of Service) Attacks from happening.
5. Respect thy Firewall. Do not host applications in servers which can be accessed from the internet without connecting through a secure communication channel.
6. Use ASP .Net membership, role managers etc and make sure that sections of your application which should stay protected from undesired access, stays so.
12. If you are storing any sensitive information in the view states using hidden-fields, then encrypt them as well. Use my favorite AES Encryption.
13. If you want to create an extremely secure application, for example a web application which contains company budgets, legal and M&A data, data for the board of directors and what not, you can create a dual mode of authentication(on top of using SSL). E.g. you can configure the application to run on standard Windows authentication with membership and role management happening through Active Directory or some other profile store. Additionally you can have your own custom authentication module developed as a custom HTTP module. The module will have function which will trigger every time a request is made to the server. It will check for an encrypted Cookie that you will create and store in the user's browser for the session in question. If the cookie is not found, redirect the user to a custom log-in page. In the log-in page the user must enter a different set of user IDs and password which must be matched against your custom database. When a match will be found, create the cookie and redirect the user to the URL requested earlier.
15. Avoid creating persistent cookies as much as possible.
16. A brief note on password policies. Please remember, a password policy for strong passwords is helpful for the users to create a password which meets your standards for a strong password. At the same time, it is also helpful for hackers to design a much more intelligent brute force dictionary attack. (I like using the password strength indicator provided by Ajax Control Toolkit to help users determine their password strengths without giving away too much on my password policy )
17.Use validation controls to make sure that the user data entries are not messed up. This means that you should(read must) stop end users from entering text in the field which asks them enter their phone numbers. 
18. Kerberos is difficult than NTLM, but there is a bigger pay-off.
19.Use impersonations and delegations properly.
20. Work on exception handling and errors must be handled. Test, test and test to make sure the end user cannot crash your system unintentionally(or intentionally for that matter) and you have taken measures that your code exits such scenarios gracefully.


For the complete list and more detailed white papers, you can visit this link.

Please understand that the above list will not make your web-site impenetrable. Theoretically all computer systems and networks can be cracked given sufficient time and resources. The motive of a malicious user will not always be about stealing data from you. The motive could be as simple as disrupting the service you provide. The combination of the above steps will decrease the probability of your system getting cracked or disrupted and the pay-off for trying to do so lesser and lesser for the hacker/cracker taking a shot at it.
The topic also does not speak of anything about network security etc.(An area which requires a great deal of detailed expertise, which unfortunately I do not possess) and deals with the aspects related to ASP .Net web site security only. 
The key thing is, if your data can be stolen, probably it will be stolen. If your systems can be cracked, probably they will be cracked! So it is better to be proactive than reactive.

Thursday, March 15, 2012

Restrict access for anonymous users


If you are building a SharePoint website on the internet, you might be having the following architecture. 

You will probably have created a web application and configured it to run on Windows Authentication.Then you can extend the same web application from the Central Administration and the extended web application can run on Forms authentication over the internet.
Extending a web application will create a new site in the IIS by SharePoint and this site and the site created to run with Windows Authentication will be sharing the same content database.
For most content based web sites over the internet, Anonymous Authentication may be configured for the site.
But configuring anonymous access creates one significant problem in case of SharePoint sites. The areas of the site sometimes get exposed over the internet which you might want to keep under wraps.
There could be other scenarios where you might want your registered users to have more rights than Restricted Read. But at the same time you want to maintain a tight leash so that your website is less vulnerable even from users who have registered and logged in as they are external users and may not be a part of your organization. If they have malicious intentions, I guess it will be better to be prepared than to be sorry later.
Mostly you would like to restrict the following pages completely from external users who are access the site over the internet:
View All Items Page : /_layouts/viewlsts.aspx
The different views in lists and libraries : <Document Library Name>/Forms/Allitems.aspx etc.
There could be a host of other pages as well. But it will be crucial for the content managers/information workers to access this page from the intranet zone of the website.
The good news is there is a very simple way to solve this problem. One thing to keep in mind is all SharePoint sites are in reality ASP .Net sites. Hence you can modify the web.config file to do your bidding. In this case, what you can do is modify the web.config file for the extended web application running on the forms authentication or anonymous authentication on the internet. Modify the following section on the web.config file:

<!--Added for Access Control-->
    <location path="_layouts/mobile/mbllogin.aspx">
        <system.web>
            <authorization>
                <allow users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="Pages/Forms">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="Css/Forms">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="PublishingImages/Forms">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="Documents/Forms">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="Lists">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="_layouts/1033">
        <system.web>
            <authorization>
                <allow users="?" />
                <allow users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="_layouts/<your custom directory>">
        <system.web>
            <authorization>
                <allow users="?" />
                <allow users="*" />
            </authorization>
        </system.web>
    </location>   
    <location path="_layouts/images">
        <system.web>
            <authorization>
                <allow users="*" />
            </authorization>
        </system.web>
    </location>
    <location path="_layouts">
        <system.web>
            <authorization>
                <deny users="?" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <!--End for Access Control-->

 The good thing is you can do a lot of mix and match and allow access to certain areas for anonymous users and even registered users logging in and then completely restricting access to other areas. As you can see above this particular setting provides access to:
1. All files and folders under Pages library, style sheets library, images library, but denies access to the Forms folders hence the user cannot actually open various views in the document library and fiddle around.
2.You restrict access to all assets under _layouts directory, but open images under _layouts so that logos, banners icons etc. can be displayed. Similarly you can open 1033 directory and any custom directory that you might have deployed which can contain JavaScript files, resources etc.


Thursday, March 8, 2012

Getting Distinct Records using LINQ

LINQ provides us with a handy way of obtaining Distinct records from a collection of objects. The collection of objects has to be a generic collection and could be anything from a records returned by an LINQ to SQL or  objects returned by a WCF service or your very own collection of objects. The Distinct Operator faithfully queries a sequence and gets the distinct items matching a specific criteria. (That's a no-brainer!) 
The method is overloaded. By default, if you invoke the distinct method on an enumeration or collection, you do not need to pass any function parameters. If you are invoking the distinct method on an enumeration returned by say querying a SQL table, the distinct will by default act on the primary key. If you want to find out the specific records with distinct values for a particular column, you need to use an IEqualityComparer or Type T. 
Enough talk....let's try some code!
For the example, I'm going to use the NorthWind products table. We can see from the diagram below that there is a relationship between the Products and Categories in the NorthWind database.

What I will do is use the repository that I have created here and get the list of Products from the Products table. First I will perform a Distinct() on the records returned and see what happens.


            //objProductsRep is my concrete repository of the abstract
            //data repository which I have created for the NorthWind database
            ProductRepository objProductsRep = new ProductRepository();

            //gv_Products is the gridview which I am using in the aspx file
            //to display the data.
            gv_Products.DataSource = objProductsRep.GetAllProducts()
                .Distinct()
                .ToList<Product>();
            gv_Products.DataBind();


This generates a GridView as shown below:

So this brings us to the important and all consuming question of how do we get Distinct values for say, the Categories; i.e. how many distinct Categories of Products are there? (Believe me, sometimes it is important to know such things; stock markets collapse and people go bankrupt for the lack of such knowledge)
But let us not digress and get back to the topic at hand. Below is the code of class which uses the IEqualityComparer to filter only the Distinct CategoryIDs.



    /// <summary>
    /// This class extends the IEqualityComparer to compare two products and find out
    /// if their categories are unique. This is like comparing apples and oranges(no pun
    /// intended!) and finding out if they both belong to the category fruits. The  
    /// IEqualityComparer is of type Product
    /// </summary>

    public class ProductsComparer : IEqualityComparer<Product>
    {
        /// <summary>
        /// This is the method which does the comparison
        /// </summary>
        /// <param name="P1">The first product to compare</param>
        /// <param name="P2">The second product to compare</param>
        /// <returns>Return true if there is a match for the categories
        /// else false</returns>
        public bool Equals(Product P1, Product P2)
        {
            if (P1.CategoryID == P2.CategoryID)
                return true;
            return false;
        }
        /// <summary>
        /// This method helps the comparison by producing the hashkey
        /// of the category ID column. It is understood if the CategoryID
        /// is same then the products belong to the same category
        /// </summary>
        /// <param name="P">The product</param>
        /// <returns>the integer hashcode</returns>
        public int GetHashCode(Product P)
        {
            if (Object.ReferenceEquals(P, null)) return 0;

            int hashProductID = P.CategoryID == null ? 0 : P.CategoryID.GetHashCode();

            return hashProductID;
        }
    }


Now we invoke the same Distinct method(well, actually the overloaded version of it) on the collection of Products returned by the Product Repository, but this time pass an object of ProductsComparer class as a function parameter.

            //objProductsRep is my concrete repository of the abstract
            //data repository which I have created for the NorthWind database
            ProductRepository objProductsRep = new ProductRepository();

            //gv_Products is the gridview which I am using in the aspx file
            //to display the data. I have ordered the results by Category ID
            //in an attempt to make it a little more pleasing to the eye
             gv_Products.DataSource = objProductsRep.GetAllProducts()
                .Distinct(new ProductsComparer())
                .OrderBy(P => P.CategoryID)
                .ToList<Product>();
             gv_Products.DataBind();



And the result is the following GridView:

References


Wednesday, March 7, 2012

Repository Pattern with LINQ to SQL

As a continuation of my earlier post, this post aims to implement Repository Pattern using LINQ to SQL. I am using the same NorthWind Database, but this time using dbml. I have created a Linq to SQL class file called NorthWind.dbml. From the Server Explorer in Visual Studio, I have dragged and dropped the Product Table and the Category table to the designer surface of the dbml file.

Below is the implementation of a generic Repository Pattern and a concrete implementation for it, using LINQ to SQL.


//*********************************************************************************//
//***********************Generic Repository Pattern********************************//
//*********************************************************************************//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Expressions;


namespace Application.Linq
{
    public class DataRepository<T> : IDataRepository<T>, IDataRepository where T : class
    {
        readonly NorthWindDataContext _dataContext;
        public DataRepository()
        {
            _dataContext = new NorthWindDataContext();
        }
        public virtual T GetById(int ID)
        {

            var itemParameter = Expression.Parameter(typeof(T), "item");
            var members = _dataContext.GetTable<T>().Context.Mapping.GetMetaType(typeof(T)).DataMembers;
            string pk = members.Where(m => m.IsPrimaryKey == true).First().Name;
            var whereExpression = Expression.Lambda<Func<T, bool>>
                (
                Expression.Equal(
                    Expression.Property(
                        itemParameter,
                       pk
                        ),
                    Expression.Constant(ID)
                    ),
                new[] { itemParameter }
                );
            try
            {
                return GetAll().Where(whereExpression).Single();
            }
            catch
            {
                return null;
            }

        }

        public virtual IQueryable<T> GetBySpecificKey(string KeyName, string KeyVal)
        {

            var itemParameter = Expression.Parameter(typeof(T), "item");
            var whereExpression = Expression.Lambda<Func<T, bool>>
                (
                Expression.Equal(
                    Expression.Property(
                        itemParameter,
                       KeyName
                        ),
                    Expression.Constant(KeyVal)
                    ),
                new[] { itemParameter }
                );
            try
            {
                return GetAll().Where(whereExpression).AsQueryable();
            }
            catch
            {
                return null;
            }

        }

        public virtual IQueryable<T> GetAll()
        {
            return _dataContext.GetTable<T>();
        }
        public virtual void Insert(T entity)
        {

            _dataContext.GetTable<T>().InsertOnSubmit(entity);
            _dataContext.SubmitChanges();

        }
        public virtual void Delete(T entity)
        {
            _dataContext.GetTable<T>().DeleteOnSubmit(entity);
            _dataContext.SubmitChanges();
        }
       
        IQueryable IDataRepository.GetAll()
        {
            return GetAll();
        }
        void IDataRepository.Insert(object entity)
        {
            Insert((T)entity);
        }
       
        void IDataRepository.Delete(object entity)
        {
            Delete((T)entity);
        }      
        object IDataRepository.GetById(int ID)
        {
            return GetById(ID);
        }
        IQueryable IDataRepository.GetBySpecificKey(string KeyName, string KeyVal)
        {
            return GetBySpecificKey(KeyName, KeyVal);
        }
    }
    public interface IDataRepository<T> where T : class
    {
        T GetById(int ID);
        IQueryable<T> GetAll();
        void Insert(T entity);       
        void Delete(T entity);
        IQueryable<T> GetBySpecificKey(string KeyName, string KeyVal);
    }
    public interface IDataRepository
    {
        object GetById(int ID);
        IQueryable GetAll();
        void Insert(object entity);       
        void Delete(object entity);       
        IQueryable GetBySpecificKey(string KeyName, string KeyVal);
    }
}
//*********************************************************************************//
//*************************************END*****************************************//
//*********************************************************************************//
 Now the time for concrete implementation of the pattern for the Products table:
*Note: The code below should ideally go to the Business Logic Layer. I am using Data Annotations here as I had hooked the Product Repository with an ObjectDataSource and plugged it to a simple GridView control to test the implementation.

//*********************************************************************************//
//*******************Concrete implementation for the pattern***********************//
//*********************************************************************************//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Application.Linq
{
    /// <summary>
    /// Concrete implementation of the repoistory for the Product table
    /// </summary>
    [System.ComponentModel.DataObject]
    public class ProductRepository
    {
        /// <summary>
        /// The product repository is instantiated
        /// </summary>
        readonly IDataRepository<Product> objProductRepository = new DataRepository<Product>();

        /// <summary>
        /// Get all products
        /// </summary>
        /// <returns>Returns a list of all products</returns>
        [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
        public List<Product> GetAllProducts()
        {
            return objProductRepository.GetAll().ToList<Product>();
        }
      
        /// <summary>
        /// Delete a product
        /// </summary>
        /// <param name="p">The product entity to be deleted</param>
        [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Delete, true)]
        public void DeleteProduct(Product p)
        {
            objProductRepository.Delete(p);
        }

        /// <summary>
        /// Gets a product by ID, assuming the Product ID is unique
        /// </summary>
        /// <param name="ProductID">The value for the primary key ProductID</param>
        /// <returns>The product associated with the integer ID</returns>
        [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
        public Product GetProductByID(int ProductID)
        {
            try
            {
                return objProductRepository.GetById(ProductID);
            }
            catch
            {
                return null;
            }
        }
    }
}

//*********************************************************************************//
//*************************************END*****************************************//
//*********************************************************************************//

Using the concrete implementation with a GridView: