Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

ClickOnce Security Overview


ClickOnce Runtime Protections

ClickOnce and the .NET runtime provide runtime protections for the client as well. ClickOnce relies on the Code Access Security (CAS) infrastructure of the .NET Framework for enforcing those runtime protections, but ClickOnce security is configured and managed a little differently than for non-ClickOnce deployed applications.

ClickOnce security is applied at the application level, instead of at the individual assembly level as it is in a normal .NET application. Your entire ClickOnce application (the application executable and all assemblies that it loads) are treated as a single unit for the purposes of deployment, versioning, and security. When an application is deployed through ClickOnce, the application manifest specifies what security permissions the application needs to run. These permissions are based on CAS.

As the application is launched by ClickOnce, the runtime first evaluates what URL or UNC path was used to deploy the application to the client machine (the path to the deployment manifest on the deployment server). This path is treated as the launch path. Based on this path, the runtime associates your application with one of the built-in location-based code groups (My Computer, LocalIntranet, Internet, Trusted Sites, or Restricted Sites zones). The runtime determines what set of permissions should be granted to your application based on the zone that it was launched from and compares that to the set of permissions requested by the application.

If the requested permissions in the application manifest are less than or equal to the set that would be granted based on the launch zone, then no elevation of permissions needs to occur and the application can simply launch and run. If the application attempts to perform an operation that exceeds the granted permissions, then a SecurityException will be thrown.

To see this in action, do the following.

  1. Create a new Windows Application project in Visual Studio, and name the project RuntimeProtectionApp.
  2. From the toolbox, add a button to the form.
  3. Double-click on the button to add a Click event handler for the button.
  4. Add the following code to the event handler:

    private void button1_Click(object sender, EventArgs e)
    {
        StreamWriter writer = new StreamWriter("AttemptedHack.evil");
        writer.WriteLine("If I can do this, what else could I do??");
        writer.Close();
    }

  5. Add a using statement for the System.IO namespace to the top of the file:

    using System.IO;

  6. Open the project properties editor (choose Project > RuntimeProtectionApp Properties).
  7. On the Security tab, check the checkbox labeled Enable ClickOnce Security Settings, and click the radio button labeled This is a partial trust application (see Figure 6.1).

    [Click image to view at full size]
    Figure 6.1: ClickOnce Security Settings

  • Publish the application by choosing Build > Publish RuntimeProtectionApp.
  • When the Publish wizard appears, click the Next button.
  • In the second step of the Publish wizard, select the option to make the application available online only (see Figure 6.2) and then click Finish.

    Figure 6.2: Selecting Install Mode in the Publish Wizard

  • Click the Run button in the publish.htm test page when it appears in the browser. This launches the application.
  • Press the button that you added to the form in step 2, causing the application to try to write a text file to the current working directory (which in this case is the C:\Windows\Microsoft.NET\Framework\v2.0.50727 folder, since the application is marked for partial trust).
  • A SecurityException will be thrown for the FileIOPermission type, because the default LocalIntranet zone security permissions do not include that permission. The permission is demanded by the StreamWriter class when you construct an instance of the StreamWriter. Since the application does not catch the exception, the dialog shown in Figure 6.3 will display.
  • Click the Quit button to exit the application.

    In this example, the application requested permissions that did not exceed the permissions granted by the launch zone. This is because you selected partial trust and the default zone for partial trust is the Local Intranet zone. When you installed the application by clicking on the Run button in the publish.htm test page, the address used was http://<your-machine-name>/RuntimeProtectionApp/RuntimeProtectionApp.application. The runtime evaluates this address to the Local Intranet zone (based on the server address portion of the URL: http://<your-machine-name>/) and compares the requested permissions in the application manifest to the permissions for that zone. Since they match, no additional prompting is needed based on security and the application launches.

    However, just because the application only requests a certain set of permissions based on its manifest does not mean that there is not code in that application that might try to do some operation that exceeds the granted set of permissions. In this example, the application contains code that tries to perform a file write to the local directory. That operation triggers a check for FileIOPermission for the file that is being written. Since the Local Intranet zone does not include that permission, a SecurityException is thrown at that point.

    Figure 6.3: Unhandled Exception Dialog
  • These protections are designed to ensure that your application does not inadvertently do something on the user's machine that it was not designed to do. This could result from bugs in your code, debug code that was left behind unintentionally, or it could happen if your application manages to load some other assembly that does something more than you expect it to. For example, suppose you design a smart client application that acts as a data entry client for a distributed application. Based on your design, that application should only present a rich interactive user interface for the user to view, enter, and manipulate data that gets passed to your middle-tier application server through Web services.

    Suppose you choose to use some third-party UI component to speed your development. Unknown to you, the code inside that component collects any values that are entered through its controls and transfers that data to some unknown location via a Web request for intelligence gathering. If you deployed this application with full trust, the component would be able to do just that and you may never even know it is happening behind the scenes. However, if you deployed your application with partial trust and restricted the WebPermission options to only allow calls to your middle-tier servers, then a security exception would be thrown when that nefarious component tried to do its evil deeds. By restricting the permission set, you would be protecting the user from that hidden data transfer.

    Using a restricted set of permissions through partial trust is an excellent way to prevent your application from doing anything it was not designed to do. Unfortunately, for a lot of meaningful things that you might want to do in your application, such as doing on-demand updates through ClickOnce or making remote calls through Windows Communication Foundation, you will be required to set your application for full trust due to the more advanced things the Framework does for you under the covers to provide those capabilities. You can still lock down permissions for specific sections of your code, however.

    If the application manifest requests permissions that exceed the launch zone permissions, such as full trust, then those permissions need to be granted to the application somehow so it can launch. This can be done either through user prompting (the default) or automatically based on trusted publishers.


    Related Reading


    More Insights






    Currently we allow the following HTML tags in comments:

    Single tags

    These tags can be used alone and don't need an ending tag.

    <br> Defines a single line break

    <hr> Defines a horizontal line

    Matching tags

    These require an ending tag - e.g. <i>italic text</i>

    <a> Defines an anchor

    <b> Defines bold text

    <big> Defines big text

    <blockquote> Defines a long quotation

    <caption> Defines a table caption

    <cite> Defines a citation

    <code> Defines computer code text

    <em> Defines emphasized text

    <fieldset> Defines a border around elements in a form

    <h1> This is heading 1

    <h2> This is heading 2

    <h3> This is heading 3

    <h4> This is heading 4

    <h5> This is heading 5

    <h6> This is heading 6

    <i> Defines italic text

    <p> Defines a paragraph

    <pre> Defines preformatted text

    <q> Defines a short quotation

    <samp> Defines sample computer code text

    <small> Defines small text

    <span> Defines a section in a document

    <s> Defines strikethrough text

    <strike> Defines strikethrough text

    <strong> Defines strong text

    <sub> Defines subscripted text

    <sup> Defines superscripted text

    <u> Defines underlined text

    Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

     
    Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
     

    .NET Recent Articles

    Upcoming Events



    Most Recent Premium Content