Welcome to MSDN Blogs Sign in | Join | Help

1. Consider a Microsoft Office SharePoint Server 2007 site that will be used as a “Document Approval System”. Certain users will be “Editors” and they will be able to upload documents for approval. Another set of users will be “Approvers”. These users can either approve or reject the uploaded documents. The security requirement is that “Editors” should not be able to approve the documents and the “Approvers” should not be able to edit or delete the documents.

2. Create a document library where the documents will be uploaded.

clip_image002

In this document library, create an Out-of-the-box MOSS 2007 Approval Workflow. In the “Select a task list to use with this workflow”, select “New task list”.

clip_image004

3. In the text box for “Approvers”, add the windows group that will contain all the “Approver” users. Also so that an editor cannot change this “Approver” group at the time the workflow is being created, uncheck the “Allow changes to the participant list when this workflow is started” checkbox.

clip_image006

4. As you can see a new task list is created for this workflow.

clip_image008

5. Give Contribute permissions on the site to the windows group that will contain the “Editors”.

clip_image010

This group can now add, edit and delete items from lists.

6. Now login as an “Editor” and upload a document. clip_image012

Start the workflow on the uploaded document.

clip_image014

As you can see the approvers text box is disabled.

clip_image016

Once the workflow is started, a task is created in the task list specific to this workflow.

clip_image018

7. Let us see what happens if the “Editor” tries to approve the document herself.

clip_image020

We are trying to approve a workflow logged in as an editor.

clip_image022

The “Editor” will get an error message and the following will be added to the workflow history.

clip_image024

8. Now login as the “Administrator” and create a new permission level for the “Approver”. Give this permission level, edit items, view items, open items, view versions and view application pages permissions.

clip_image026

9. Create a new Share Point group for workflow approvers. Give it read permissions on the site.

clip_image028

clip_image030

Give the same group edit permissions on the workflow task list (that was specifically created for the approval workflow) using the “WorkflowApprovalPerm” permission just created.

clip_image032

clip_image034

The Share Point group “Workflow Approvers” now has the following effective permissions on the site. Effectively it has read-only permissions on the entire site, but “edit” permissions on the task list specific to the approval workflow.

clip_image036

10. Add the windows group containing all the approvers to this “Workflow Approvers” Share Point group.

clip_image038

11. Now login as an “Approver”. Go to the document library. See that the approver can neither edit nor delete the uploaded documents.

clip_image040

12. Go to the task created for approval. Try to approve it.

clip_image042

As you can see the “Approver” is able to approve the document.

clip_image044

Summary:-

This “How To” shows that it is possible using the out-of-the-box MOSS 2007 approval workflow to create a document approval system where

1. The “Editors” can only upload documents to be approved but cannot approve the documents themselves.

2. The “Approvers” can only approve or reject the documents but cannot edit or delete them.

Quite a few web applications encrypt query string values. This is generally done as an added measure to prevent unauthorized access. Since the end user cannot chose a value and then encrypt it, changing parameters becomes difficult. But encryption is not a panacea. See if you can spot this bug.

encrypt1

The code behind file looks like this:-

encrypt2

Implementation for the Encrypt and Decrypt methods is not shown. They are using the DES algorithm. There is no flaw in the usage or key management.

The end user can upload files and the screen look like this:-

encrypt3

On clicking Upload, the file gets uploaded and a message is shown. Note the query string values. The HTML source is also shown.

encrypt4

Do you think the code or design is flawed in any way? Can this be exploited?

Modern symmetric block encryption algorithms need to satisfy a number of properties to be considered strong. One such property is the property of “Confusion”.

What it means is that if an attacker is conducting an exhaustive key search, and if the key being tested is incorrect only in a few bits, the decrypted text should give no such indication. If the decrypted text does give such an indication, then the attacker can stop the brute force process, and simply change the incorrect bits in the key and get the actual key. This will take much less time relative to a full brute force attack.

To understand this better, I will demo it using the CrypTool, which is a great tool to learn about cryptography.

1. This will encrypt the text shown in the background using the Simple Substitution Cipher and the key “ONCEUPATIMXBDFGHJKLQRSVWYZ”.

crypt1

2. Text in the background has been encrypted. Using the tool, I will now perform an automatic analysis of the cipher text to try to get the key. Note: This could have been a brute force attack too.

crypt2

3. Although the correct key has not been found, since the decrypted text resembles text in English to a great extent, I may be “close” to the the actual key.

crypt3

 

4. I will now stop the brute force process and using manual analysis , one by one substitute only those characters in the key that seem to produce incorrect plaintext, thereby getting the actual key.

crypt4

 

Modern encryption algorithms like DES and AES have the Confusion property. Therefore if English text has been encrypted using DES or AES and during the brute force process, the key being tested differs from the actual key by only one bit, still the decrypted text does not resemble English text at all. 

In my previous “Catch the Security Flaw” post I wrote about a flawed CAPTCHA implementation. In this post I discuss what are the flaws in that implementation and how to prevent them. Before I go into the exact flaws, let us agree upon a standard notation to describe the flow of data.

C stands for Client. This is the end user. S stands for Server which is the web server in this case.

In the implementation of the flawed CAPTCHA, the data flow is:-

1) C ----> S; GET somepage.aspx

2) S ----> C; Somedata || CAPTCHA Picture || hash (CAPTCHA value)

3) C ----> S; Somedata’ || hash (CAPTCHA value) || CAPTCHA value

In the flawed implementation, hash (CAPTCHA value) is being maintained on the client side as a hidden field. CAPTCHA value is supposed to be entered by the end user in the text box.

If in the 3rd step, Server gets the ”right” CAPTCHA value, it takes the action. To check if the value is “right”, the server simply hashes the CAPTCHA value sent by the client and then compares it with the hash (CAPTCHA value) also sent by the client.

To discuss the flaws, we will look only at the 3rd step. The attacker, to run an automated script, will continually call step 3.

Attack 1:- The client can take any value, say A. Then hash it to get hash (A). It can then continually call step 3 as:-

3) C ----> S; Somedata’ || hash (A) || A

This value A is not the same as in the picture in step 2. It doesn't have to be. The server does not maintain state. Hence it doesn't know that this value A is not the same as the one it had sent in the picture in step 2.

Countermeasure of Attack 1:-

So to prevent this attack, instead of hashing the value, let us encrypt it. The flow now becomes:-

1) C ----> S; GET somepage.aspx

2) S ----> C; Somedata || CAPTCHA Picture || Encrypt (CAPTCHA value, Key)

3) C ----> S; Somedata’ || Encrypt (CAPTCHA value, Key) || CAPTCHA value

Key is the encryption key used to encrypt the CAPTCHA value. This key is known only to the server. Now if the Client takes any value, say A. It does not have the Key to encrypt it to create Encrypt (A, Key). Hence it cannot choose any A and then call step 3. Great!

Attack 2:-

Even if the above countermeasure is put in place, the Client can still call step 3 continually. The Client can once manually see the CAPTCHA picture. Say the value in it is B. It can then call step 3 continually with the same value.

3) C ----> S; Somedata’ || Encrypt (B, Key) || B

Client doesn't know how to calculate Encrypt (B, Key). It does not need to. The Server is not storing any state. Hence the server does not know if this value has been used before.

Therefore, never forget this principle for a CAPTHCA implementation:-

“The Server MUST maintain state in a secure CAPTCHA implementation”

Countermeasure for Attack 2:-

1) C ----> S; GET somepage.aspx

2) S ----> C; Somedata || CAPTCHA Picture =>Server maintains CAPTHCA value

3) C ----> S; Somedata’ || CAPTCHA value  =>Server verifies CAPTCHA value

In step 2, the Server creates a random CAPTCHA value and stores it on the server side. It links this value with a particular Client, say using a session ID. In step 3, the Server verifies if the value sent by the Client is the same as in its state. It then must nullify the CAPTCHA value for that client.

 

Reference:-

An ASP.NET Framework for Human Interactive Proofs

Consider a fictional web site that lets you create new accounts (as shown below).

 

This site implements CAPTCHA to prevent a malicious user from creating large number of false accounts by running an automated script.

The following code is used to implement the CAPTCHA. What do you think is the flaw here?

public partial class _Default : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!IsPostBack)

        {

            int randomValue = GetRandomCaptchaValue();

            imgCaptcha.ImageUrl = GenerateImage(randomValue);

            // hdnCaptchaValue is a hidden variable.

            // <asp:HiddenField ID="hdnCaptchaValue" runat="server" />

hdnCaptchaValue.Value = GenerateHash(randomValue.ToString());

        }

 }

 

protected void btnSubmit_Click(object sender, EventArgs e)

    {

        if (GenerateHash(txtImageValue.Text).CompareTo(hdnCaptchaValue.Value) == 0)

        {

            // Code to create the account

 

        }

        else

        {

            lblCaptcha.Text = "The value entered is not correct.";

        }

    }

 

public static string GenerateHash(string text)

    {

        string hash = string.Empty;

        System.Text.UnicodeEncoding uEncode = new System.Text.UnicodeEncoding();

           

        System.Security.Cryptography.SHA512Managed sha = new System.Security.Cryptography.SHA512Managed();

        Byte[] hashBuffer = sha.ComputeHash(uEncode.GetBytes(text));

        return  Convert.ToBase64String(hashBuffer);

     }

 

private int GetRandomCaptchaValue()

    {

        Random random = new System.Random();

        return random.Next(100001, 999999);

    }

/// <summary>

    /// This method generates an image using Bitmap class and then saves it in webroot.

    /// It returns the URL of the image.

    /// </summary>

    /// <param name="captchaValue">URL of the image</param>

    /// <returns></returns>

    private string GenerateImage(int captchaValue)…

   

       

 

 

It is time to discuss the flawed code that I posted a couple of weeks back. The comments posted were good and in essence summarize the flaw.

The circled part is an example of an embedded code block. The query string parameter “id” will be inserted inside the <% %> block, creating HTML at the client that looks something like this:-

<!--<input type="text" value="123" />--> for a query string value id=123.

 This can lead to Cross Site Scripting (XSS).   

 

The countermeasure is simple. Treat user controlled input which is put inside an embedded code block with caution, even if there are comments around the HTML element. If you do not need the element, remove the embedded code block. If you need it, validate the input and encode the output.

Setting ValidateRequest to true (which is by default) would have prevented this bug from getting exploited. But would ValidateRequest prevent this from being exploited?

I will be from time to time, putting up flawed code as an open question on this blog. Those who can catch the flaw please do post about it in the comments section (preferably with the repro steps). After a few days, I will post the flaw and its countermeasure.

Here is the first one:-

I have seen quite a few web applications that rely on disabling controls for authorization. Consider this code:-

The scenario may be that the page has to be displayed in a read-only manner for certain roles, or after submission of some details but prior to approval (in a workflow). This reason depends on the business requirement. In this dummy app, the page looks like this:-

This authorization can easily be bypassed. Without using any special tool, an attacker can just enter script this way in the address bar and hit enter:-

Now the attacker enters some text and hits the submit button, completely bypassing the authorization control:-

Countermeasure:-

Check the condition in the event handler before taking action.

About a month back, ACE Engineering released "XSSDetect", a stripped down version of the "Code Analysis Tool for .NET code bases (CAT.NET)".

A Cross site scripting (XSS) vulnerability exists in a web application whenever user controlled input, without proper validation or encoding is echoed back to the browser.

To find XSS (and other injection flaws) in an application, you need to enumerate all user input. User inputs can be through query string, form fields, cookies etc. Then you need to do a manual data flow analysis for each user input by reading through the code and by using the web site. The goal is to find all instances of user input that, without validation or encoding, are being echoed back to the browser. This may be if the input is assigned to a label control, or is used in a "Response.Write" statement etc. Without doubt this is a tedious process.

XSSDetect automates this process of finding XSS bugs. It has predefined sources of user input and then does a data flow analysis. If the input ends up in a predefined list of sinks that are vulnerable, it flags it as a XSS bug.

I wanted to give an idea of the sort of issues XSSDetect finds. For this, I ran the tool on a demo site that the ACE Security Team uses for its Secure Application Development/ Testing Training course.

1. Once you install XSSDetect, it is visible as a snap-in in the Visual Studio IDE.

2. After loading the solution in Visual Studio and clicking on the green "GO" button, XSSDetect's analysis window shows the list of potential issues that it has found in the application.

3. Clicking on the issue, takes you to the source code where the issue exists.

In this particular case, user controlled input, without validation is being assigned to a label control.

4.

Here the RegisterStartUpScript method is being used to add script. The script contains user controlled input which is again not validated or encoded.


5.

In this vulnerability, user controlled input is being directly assigned to an image "src" property through an embedded code block.

XSSDetect only finds non-persistent XSS. This is because it is a stripped down version of the CAT.NET tool. The CAT.NET tool, other than finding persistent XSS, also finds various other vulnerabilities like SQL injection, Redirection to user controlled site, exception details being shown to user, file canonicalization bugs, LDAP injection etc and has many more features including integration with MSBUILD and FxCop.

You can download XSSDetect from here.

This is nothing new, but I just wanted to document it on my blog. Block ciphers encrypt data in blocks of bits. These blocks are generally 64 or 128 bits long. In the ECB (or Electronic Code Book) mode, each block is encrypted independently of the other blocks. As a result if two blocks are same, the same cipher text results. This enables the attacker to figure out all instances of a plaintext if that plaintext-cipher text pair is known and the cipher text is repeating. An attack based on the frequency analysis of the blocks is also possible. Frequently repeating cipher text blocks mean frequently repeating plain text blocks.

I will show the effects of another simple attack. In this case consider that the plain text is "Give Jo one two one two dollars". Note that I have purposely divided the message into blocks of 8 characters (or 64 bits in ASCII). "Give Jo " is the first block, "one two " is the next and so on.

Now I will use the DESCryptoServiceProvider class to encrypt this plaintext using ECB mode. The code used to encrypt is available here. The only difference is that I have changed the mode to ECB, and the block size to 64 bits for this demo to work.

After encrypting the plain text, the cipher text received is:-

First of all note the repeated block because of ECB. "one two one two" (from the plain text) consists of two blocks of 64 bits each. These blocks give identical cipher text blocks because of ECB.

Now consider if an attacker removes one of these blocks. This is the cipher text after removing one of the repeating blocks.

If I decrypt this cipher text, using the same code (and key) I get:-

Notice that the decryption was possible and successful, but the plain text is now different from the original plain text. Jo now gets lot less dollars ;)

Ofcourse these are the reasons why ECB mode is not preferred.

In its own words, "ClubHACK is one of its kind hacker's convention in India which serves as a meeting place for hackers, security professionals, law enforcement agencies and all other security enthusiasts."

At ClubHACK, I will talk about some interesting and subtle security flaws found while assessing business applications, which principles were not followed that resulted in the flaws and why, no matter how good a developer you are, you should always follow the basic principles of software security.

The concept of perfect secrecy is that given the cipher text, and any resources and amount of time, the adversary has no way of getting to the plain text. Having the cipher text makes no difference and provides absolutely no additional information. The adversary can try a brute force approach, by trying each and every key, one by one, but this will still require the adversary to guess the plaintext. A cipher that enables this is an unbreakable cipher.

The contemporary symmetric encryption algorithms like AES and Triple-DES are not unbreakable ciphers in this sense. If you know that the plain text is a sentence in English, you have the cipher text, and you brute force, it may take you a long time, but eventually you will get only a few (probably only one) sentence in English as the plain text. This would beyond doubt be the plain text that you were looking for.

There is only one unbreakable cipher, which provides perfect secrecy as defined above. This is the One-time pad. In a One-time pad, the key size is equal to the size of the data to be encrypted. A key is used only once to encrypt data. This one-time key is random. When Alice wants to send an encrypted message (a sentence in English) to Bob, Alice generates a random sequence of bits, equal in length to the message and XOR’s this key and the message. To decrypt, Bob then XOR’s the cipher text with this One-time random key and the plain text is retrieved.

If Eve gets hold of the cipher text in transit, she may decide to get the plain text by brute forcing. If the message is n-bits, Eve can one by one, try all n-bit sequences as the key. But this will create every sentence in English of that length. In other words, given any sentence in English (constructed from n-bits), there will be a key that will transform the given cipher text to that sentence. Hence even knowing the cipher text requires Eve to guess the plaintext and provides absolutely no additional information.

The reason One-time pad is rarely used is because it requires the key to be transferred securely before the cipher text is transmitted, and since the key length is equal to the message length, key distribution becomes a problem.

Consider the following architecture for an intranet application. A thick client installed on the user’s machine connects to a web service which in turn connects to the database. The web service authenticates the caller using windows authentication. It connects to the SQL Server using a fixed identity.

 

 

The vulnerability occurs if authorization controls are built into the thick client only and not in the web service. The user can easily bypass these authorization controls by directly accessing the web service. This means that any domain user in intranet can call web methods in the web service which may result in loss of integrity and confidentiality of the data.

 

Example of vulnerable code in the thick client

 

// Thick client code

// Create instance of web proxy class

Service service = new Service();

service.Credentials = CredentialCache.DefaultCredentials;

// Check if user is admin in the application

if (service.IsAdmin())

{

    // If yes, approve the request

    service.ApproveRequest(100);

}

else

{

    // User is not authorized...

}

 

A malicious user can bypass the thick client and call the ApproveRequest web method directly, since it doesn’t authorize.

                A proper design would ensure that authorization takes place in each of the web methods in the web service based on the windows identity of the user. The thick client only represents the user interface and may implement authorization controls only for aesthetic and/ or performance purposes.

 

This is an example of how the web service should authorize the caller

 

    // Web service code

    [WebMethod]

    public void ApproveRequest(int RequestId)

    {

        // Check if the calling user is in admin role

        if (User.IsInRole("Admin"))

        {

            // If yes, approve the request

            new Request(RequestId).ApproveRequest();

        }

        else

        {

            // User is not authorized...

        }

     }

 

In the year 1995, there were eight options for the “type” attribute of the “input” element. These were “CHECKBOX”, “RADIO”, “HIDDEN”, “TEXT”, “PASSWORD”, “IMAGE”, “RESET” AND “SUBMIT”. The “FILE” option was added later on to the HTML DTD (Document type definition) to allow for users to upload files to the web server. Internet Explorer 3.02 and 4.0 released in 1997 had support for this option. Before web browsers started supporting this option, custom applications had to be built only to support the feature of uploading files.

When the “<input type=file/>” element (file upload element) is used to upload files from the client to the web server, the name of the file that gets uploaded is in the “value” attribute of this element. Internally, the browser opens the file (specified in the “value” attribute), reads it, and sends its contents as a POST request.

Can you think of a possible security flaw here? What if the creator of the website could set the “value” attribute of this element, hide the element and submit the form immediately after loading? A file from the user’s machine would be uploaded to the server without the user’s knowledge. Consider this

<html>

    <body onload="window.document.forms.form1.submit();">

        <form name="form1" method="post" action="upload.aspx" id="form1" enctype="multipart/form-data">

            <input type="file" value=”c:\Users\UserName(NeedToKnow)\AppData\Local\Microsoft\Outlook\outlook.ost” style=”visibility:hidden”/>

        </form>

    </body>

</html>

 

As it turns out, the value attribute is read-only. It can’t be set by JavaScript or by a default value. Only the browser can set the “value” attribute, either after showing the file select dialogue or as the user enters text in the file upload element’s text area. As a result, the user is well aware of which file is being sent to the server.

This is also the reason that it is difficult to change the style of the file upload element. You cannot create a custom textbox and a custom browse button, use them to get the user to select a file, and set the file name in the “value” attribute of the file upload element.

 

References:-

[1]http://www.ietf.org/rfc/rfc1867.txt

[2]http://www.microsoft.com/technet/security/bulletin/MS00-093.mspx

 

I assess software security for a living, but I almost missed this one.

<connectionStrings>

    <add name="Conn" connectionString="server=server1; database=database1; Integrated Security=True" Encrypt="True"/>

</connectionStrings> 

 

This connection string was being used in an application that stored confidential data in the database. The data should have been encrypted on the network (from the web server to the database server). I know that for an application to choose encryption for specific SQL connections, it has to set “Encrypt=True” in the connection string and this one was doing it… Or was it?

On closer inspection, “Encrypt=True” is outside the connection string! The data wouldn’t have been encrypted. This is how it should have been.               

<connectionStrings>

    <add name="Conn" connectionString="server=server1; database=database1; Integrated Security=true; Encrypt=True" />

</connectionStrings> 

 

More Posts Next page »
 
Page view tracker