Saturday, September 3, 2011

Validate uploaded image content in ASP.NET


A very few day ago i had to face the situation where hacker uploaded the malicious ASP script to the web server by changing its extension to .JPG through user interface which allow user to upload image file. Although developer team had put the validation on extension. But unfortunately extension of ASP script was .JPG and hence it is allowed extension. So hacker could upload that malicious script.

After this situation i thought just checking only extension for uploaded file is not the sufficient. We need to check content as well of the uploaded file.

So i decided to check header information in uploaded image file. If it found valid header information then only save uploaded file otherwise discard uploaded file. After Digging couple of hour onhttp://www.wotsit.org(I am fan of www.wotsit.org for more than 5 years), found following Header Information about different image file format.

Image File Header Information Table
File Format
Offset
Length
Value
JPG / JPEG
0
4
0xFF, 0xD8, 0xFF, 0xE0
PNG
0
4
0x89, 0x50, 0x4E, 0x47
TIF / TIFF
0
4
0x49, 0x49, 0x2A, 0x00
GIF
0
4
0x47, 0x49, 0x46, 0x38
BMP
0
2
0x42, 0x4D
ICO
0
4
0x00, 0x00, 0x01, 0x00

Instead of checking only header, we could also check whole file content against its file format. But checking only header could serve our purpose and it is also speedy process than checking whole file content so i am not checking whole file content.

Following code snippet validate header of known image types (JPG, PNG, TIFF, GIF, BMP, ICO) Please do let me know if i have missed any image types.

NOTE: In code snippet fuImage refer to ASP.NET file upload control

01protected void btnUpload_Click(object sender, EventArgs e)
02{
03    // DICTIONARY OF ALL IMAGE FILE HEADER
04    Dictionary<stringbyte[]> imageHeader = new Dictionary<stringbyte[]>();
05    imageHeader.Add("JPG"new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 });
06    imageHeader.Add("JPEG"new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 });
07    imageHeader.Add("PNG"new byte[] { 0x89, 0x50, 0x4E, 0x47 });
08    imageHeader.Add("TIF"new byte[] { 0x49, 0x49, 0x2A, 0x00 });
09    imageHeader.Add("TIFF"new byte[] { 0x49, 0x49, 0x2A, 0x00 });
10    imageHeader.Add("GIF"new byte[] { 0x47, 0x49, 0x46, 0x38 });
11    imageHeader.Add("BMP"new byte[] { 0x42, 0x4D });
12    imageHeader.Add("ICO"new byte[] { 0x00, 0x00, 0x01, 0x00 });
13 
14    byte[] header;
15    if (fuImage.HasFile)
16    {
17        // GET FILE EXTENSION
18        string fileExt;
19        fileExt = fuImage.FileName.Substring(fuImage.FileName.LastIndexOf('.') + 1).ToUpper();
20 
21        // CUSTOM VALIDATION GOES HERE BASED ON FILE EXTENSION IF ANY
22         
23        byte[] tmp = imageHeader[fileExt];
24        header = new byte[tmp.Length];
25 
26        // GET HEADER INFORMATION OF UPLOADED FILE
27        fuImage.FileContent.Read(header, 0, header.Length);
28 
29        if (CompareArray(tmp, header))
30        {
31            lblMessage.Text = "Valid ." + fileExt + " file.";
32            // VALID HEADER INFORMATION
33            // CODE TO PROCESS FILE
34        }
35        else
36        {
37            lblMessage.Text = "Invalid ." + fileExt + " file.";
38            // INVALID HEADER INFORMATION
39        }
40    }
41    else
42    {
43        lblMessage.Text = "Please select image file.";
44    }
45}
46 
47private bool CompareArray(byte[] a1, byte[] a2)
48{
49    if (a1.Length != a2.Length)
50        return false;
51 
52    for (int i = 0; i < a1.Length; i++)
53    {
54        if (a1[i] != a2[i])
55            return false;
56    }
57 
58    return true;
59}
Any input on above is greatly appreciated...

Source: http://www.dotnetexpertguide.com/2011/05/validate-uploaded-image-content-in.html
dotnet Expert Guide

@Blog.Author(Nandip Makwana)

Saturday, August 13, 2011

Sending Call back from client side to Server Side without postback by using AJAX(ClientCallBacks)

We can make a call from client side to server side without postback
occurance by using "AJAX".
To achieve "Call back" concept in ASP.NET web page. we need to perform
the following steps:
Serverside:
=======
1. Need to Implement "System.Web.UI.ICallbackEventHandler" for your web page.
2. Need to Implement "RaiseCallBackEvent" method for the
"ICallBackEventHandler" interface. This method is called by the
clientside. You can use it to receive parameter values from the
client.
3.Need to Implement "GetCallBackResult" method for
"ICallBackEventHandler" interface. This function will returns the
result of any serverside process to clientside. The results are sent
as a string back to the client code.

Default.aspx:
=========
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function ClientCallbackFunction(args) {
LabelMessage.innerHTML=args;
}

</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList runat="server" ID="dllChoice"
onchange="MyServerCall(dllChoice.value)">
<asp:ListItem Text="09">
</asp:ListItem>
<asp:ListItem Text="01">
</asp:ListItem>
<asp:ListItem Text="02">
</asp:ListItem>
<asp:ListItem Text="03">
</asp:ListItem>
<asp:ListItem Text="04">
</asp:ListItem>
<asp:ListItem Text="05">
</asp:ListItem>

</asp:DropDownList>

<asp:Label runat="server" ID="LabelMessage" ></asp:Label>
</div>
</form>
</body>
</html>



Default.aspx.cs:
===========
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
public partial class _Default :
System.Web.UI.Page,System.Web.UI.ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
string callbackRef =
Page.ClientScript.GetCallbackEventReference(this, "args",
"ClientCallbackFunction", "");
string callbackscript = "function MyServerCall(args)" + "{" +
callbackRef + "; }";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"MyServerCall", callbackscript, true);

}
string _callBackEventArgs;
public void RaiseCallbackEvent(string eventArgument)
{
_callBackEventArgs = eventArgument;
}
public string GetCallbackResult()
{
return _callBackEventArgs;
}
}







Example2:
=======



<%@ Page Language="C#" AutoEventWireup="true"  %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Client Callbacks</title>
    <script runat="server">
        public void RaiseCallbackEvent(String eventArgument)
        {
            // Processes a callback event on the server using the event
            // argument from the client.
        }

        public string GetCallbackResult()
        {
            // Returns the results of a callback event to the client.
            string dateString = DateTime.Now.ToLongDateString();

            return dateString;
        }

        void Page_Load(object sender, EventArgs e)
        {
            ClientScriptManager cm = Page.ClientScript;
            String cbReference = cm.GetCallbackEventReference(this, "arg",
                "ReceiveServerData", "");
            String callbackScript = "function CallServer(arg, context) {" +
                cbReference + "; }";
            cm.RegisterClientScriptBlock(this.GetType(),
                "CallServer", callbackScript, true);
        }
    </script>
    <script type="text/javascript">
        function ReceiveServerData(arg, context) {
            Message.innerText = "Date from server: " + arg;
        }
    </script>
</head>
<body>
    <h2>Client Callbacks Without Postbacks</h2>
    <form id="form1" runat="server">
       <input type="button" value="Callback"
           onclick="CallServer('1', alert('Callback sent to Server'))" />
       <br />
       <span id="Message"></span>
   </form>
</body>
</html>

Reference: Callbacks Reference
Example3
--
Regards:
M.Rama Subba Reddy
Cell:+919080391242


























Friday, August 5, 2011

How to access Div tag in Asp.NET Themes and Skins

you can use <asp:panel, it will become <div> after rendering.
Try this
skinfile.skin  inside App_Themes/Theme1 folder

<asp:Panel runat="server" SkinId="panelSkinned" BackColor="Red" ></asp:Panel>
yourpage.aspx
<%@ Page Language="C#" AutoEventWireup="true" Theme="Theme1" ...
<asp:Panel ID="test" SkinID="panelSkinned" runat="server" >
hello hai........ :)
</asp:Panel>

html after rendering(yourpage.aspx) :
============================
<div id="test" style="background-color:Red;">
 
        hello hai........ :)
  </div>
Hope this may help

Tuesday, August 2, 2011

Using parent page properties in user control


http://weblogs.asp.net/gunnarpeipman/archive/2008/05/21/using-parent-page-properties-in-user-control.aspx


Using parent page properties in user control

There may be situations when we need to use parent page properties from user control. I know, this situations is a warning sign - there's something wrong with UI structure if user controls should know their parents. So, how to get correct reference to parent page so we can use also custom properties defined there?

Let's suppose we have property called MyId in parent page of our user control and we want to call this property from user control.

If we use this code in our user control


protected void MyMethod()
{
    Page myParent = this.Page;

...
    // here we need to call MyID property
}

we will get just a Page - the base class for all Pages. This is because reference of Page is kept in base class of user controls. Whenever you create a user control it gets also the Page property. But every page we create is custom page that inherits the Page class and we may define our own custom properties.

If we have page called MyPage and it has property MyID then how can we refer to this ID? Solution is simple: we have to use casting.

 

After casting parent page to correct type we are able to use it's properties.