Using security-related attributes

Described is a technology including an evaluation methodology by which a set of privileged code such as a platform's API method may be marked as being security critical and/or safe for being called by untrusted code. The set of code is evaluated to determine whether the code is security critical code, and if so, it is identified as security critical. Such code is further evaluated to determine whether the code is safe with respect to being called by untrusted code, and if so, is marked as safe. To determine whether the code is safe, a determination is made as to whether the first set of code leaks criticality, including by evaluating one or more code paths corresponding to one or more callers of the first set of code, and by evaluating one or more code paths corresponding to one or more callees of the first set of code.

BACKGROUND

In contemporary computing, computer application programs and other code may be downloaded and installed from the Internet. This leads to potential problems in that untrusted sources such as the Internet often provide code that is intentionally malicious or otherwise capable of harming or providing unauthorized access to important data. However, because there are many situations in which computer users benefit from the ability to download code and execute code without prompting, completely preventing downloading is not a practical solution to this problem.

One solution to this problem is referred to as sandboxing, a generic security term that applies to any environment that reduces the privileges under which an application runs. It is particularly valuable to sandbox applications downloaded from the Internet, as they tend to come from unknown or untrusted sources.

Some environments, such as one based on Microsoft Corporation's Windows® Presentation Foundation and .NET technologies, attempt to solve the problems of running untrusted code via a sandbox-model that limits what the untrusted code has permission to do. For example, the underlying platform can require that its callers have specific permissions, and while code can request the permissions it needs for the execution, the runtime will only grant permission based on policy that evaluates how much the code is trusted. Such permissions include things like the ability to access files and databases, connect to the Internet, interact with the user via a user interface, call into unmanaged code, and so forth. One policy-based solution is to prompt the user when code requests such permissions, however this solution is not very desirable because a typical user is often not equipped to make a correct security decision when prompted.

As can be readily appreciated, writing secure code for platforms that enable applications to be downloaded and installed from the Internet without prompting is an extremely difficult problem. This is because the platform itself needs to have elevated privileges to properly operate. Security flaws can exist if any part of the platform code is written such that it inadvertently exposes an internal way to run untrusted code with elevated permissions/privileges, (that is, allow the untrusted code to do something beyond what would otherwise be allowed via its reduced permission set), because this would allow the untrusted code to perform unsafe operations. By way of example, the platform code needs to be able to call unmanaged code for operating system services, such as to render text on a window, while untrusted code is not allowed to do so; however if the platform code is inadvertently written such that the untrusted code can call unmanaged code via a call to a internal method of the platform code, a security flaw exists.

One solution that increases the likelihood that platform code is securely written is to allow the developer to mark (e.g., using metadata) any part of the platform code that requires elevated permissions to run, or mark code that controls whether elevated permissions can be run. In general, the metadata indicates that the marked set of platform code is “critical” code that performs a dangerous operation. Security teams and static code analysis tools (e.g., FxCop is one such code analysis tool that checks .NET managed code assemblies) then recognize the metadata, whereby platform features can be developed so that the likelihood of platform code running with elevated privileges being exposed to untrusted code is dramatically reduced.

However, while highly valuable, the marking of such code and data as critical results in a complex code-review process that burdens a security team with many critical methods that need to be code reviewed.

SUMMARY

Briefly, various aspects of the subject matter described herein are directed towards a technology by which a set of privileged code such as a platform's API method may be marked as being security critical and/or safe for being called by untrusted code; (which, for example may include code that the user has not explicitly trusted to run and have access to the user's machine, e.g., a random site on the internet that does not require a prompt. Trusted code comprises code that the user has explicitly, e.g., through a prompt for that specific application, or publisher, or the like, given permission to run/install on the machine). The set of code is evaluated to determine whether the code is security critical code, and if so, it is identified as security critical. Such code is further evaluated to determine whether the code is safe with respect to being called by untrusted code, and if so, is marked as safe. For example, method code may be considered safe when its inputs may be considered safe, when its returned values are not unsafe values (e.g., are non-critical data), and when the API is otherwise safe (e.g., does not perform operations known to be unsafe).

To determine whether the code is safe with respect to being called by untrusted code, a determination is made as to whether that code leaks criticality, including by evaluating one or more code paths corresponding to one or more callers of the first set of code, and by evaluating one or more code paths corresponding to one or more callees of the first set of code. For example, criticality may be leaked by passing or otherwise providing access to critical data to a callee of the method, when that callee in turn stores or leaks critical data, without safely brokering access to the critical data.

DETAILED DESCRIPTION

Exemplary Operating Environment

Using Security-Related Attributes

In general, a codebase such as platform code can be partitioned into a critical “core” that reduces the burden of security auditing, and increase the probability that a platform is secure. The technology described herein is generally directed towards a technology by which a set of code (e.g., a given method/API) and its code paths (e.g., other methods that call the set of code or other methods that the set of code calls) may be evaluated to determine whether the code is critical, and if so, whether the set of code can be treated as safe with respect to allowing its being called by untrusted code. For example, code corresponding to an application programming interface (API) may be deemed by an evaluation methodology (possibly using an analysis/auditing tool) to be transparent, whereby the code need not be heavily audited and can be called by an untrusted caller. In general, the only interfaces called by untrusted code are those marked public; however other code that is trusted but unaudited also may be called. Such unaudited code should be considered by developers as being untrusted, and thus as used herein, untrusted code also refers to unaudited code.

Alternatively, a method is deemed critical when it elevates (privileges) and/or performs certain operations such as those that return, store or provide access to critical data, in which event the code may be tagged (with metadata) as needing to be heavily audited. A method is also deemed critical at times when it makes decisions about a behavioral difference from a security standpoint. In general, the metadata indicates that the marked set of platform code is “critical” code that performs a dangerous operation or calls into something that performs a dangerous operation and is not marked TreatAsSafe.

This is done to ensure that any changes to this code are also audited. Although critical, there is still a possibility that such a method may be treated as safe, including safe for being called by an untrusted caller, if the method does not have unsafe (or validates) inputs (e.g., dealing with critical parameters), does not work with unsafe values (e.g., return or store critical data), and is otherwise safe. In other words, a critical method may be safe in the event that its criticality does not “leak out or up” to transparent code and/or untrusted callers. One way criticality can be leaked is by providing access to data that required an elevation of permissions to obtain.

In general, the technology described herein is primarily described with reference to an example Windows® Presentation Foundation managed code environment, including code access security, a .NET framework, and a common language runtime that provide a secure execution environment for untrusted or partially trusted code, (such as Web Browser Applications, e.g., having a .xbap extension). This technology also extends to XPSDocuments and .XAML files. As will be understood, however, such technology may be implemented in other sandbox-type environments, and thus may be used various ways that provide benefits and advantages in computing in general.

FIG. 2shows an example code evaluation methodology202(e.g., a manual analysis and/or a software-based analysis tool or tools) evaluating some method204such as an API of the platform code to ensure that any critical code is marked as such, and also to mark code as to whether it may be treated as safe for being called by untrusted code. The results206may be reviewed by a security team and/or one or more developers (possibly using further analysis tools) to eliminate any security flaws in the method204. In a typical scenario, the initial safe/unsafe categorization is done by a combination of tools, developer review, and is based upon a set of guidelines.

FIG. 3shows the compiled method304in operation with untrusted code310. Whether or not the method can be called by the untrusted code310(as indicated by the dashed line) depends on what the method304does, as evaluated in the previous analysis ofFIG. 2. In the event the method304is not safe, the untrusted code310will not be able to use the functionality of the method304, that is, a sandbox is set up that prevents its usage. Note that it is feasible to perform runtime checks for untrusted or transparent code calling critical, non-marked as safe methods, e.g., by maintaining attributes or the like with the compiled method code304that indicates when code, data and/or methods are critical. In general, code is critical when it performs an operation that is an elevation, calls a critical method, and/or stores data obtained under an elevation. Note that a platform may be built on top of an existing platform, which needs to be evaluated when determining the initial criticality of an operation.

As mentioned above, it is possible that critical code may be called by untrusted code as long as the critical code has certain characteristics by which the critical code may be deemed safe. Among these characteristics is that the overall functionality of the critical code is itself safe. Another characteristic is that any caller (untrusted or otherwise) can safely call the critical method, e.g., so that the called method's criticality cannot leak out to such callers. Still another characteristic is that the critical code does not call any other code (any “callee”) to which the calling code passes critical data and to which it in turn leaks out that data to untrusted/non-critical callers. If these characteristics are not present, the method cannot be deemed safe.

FIG. 4provides a visual representation of these characteristics, where some method404that is critical (elevates) is evaluated for whether it can be tagged as safe (e.g., with a TreatAsSafe security attribute). For example, the method404may be critical when an operation is performed that is outside the set of things allowed in the predefined sandbox, e.g., a call to unmanaged code on a CAS platform (where in a CAS, or Code Access Security model, a program runs with full trust (a full set of rights and privileges) or with partial trust (some lesser subset of rights and privileges).

Other methods that are represented inFIG. 4include callers A()-J() that form code paths that need to be reviewed, including direct callers I() and J(), that may need to be evaluated to determine whether any one of them causes a criticality violation that would prevent the method404from being marked as safe, and callees X() and Y() that also need to be evaluated along with any code paths to which they belong.

In general and as described below, the method404has its own code evaluated for criticality and for whether it can be treated as safe for being called by untrusted callers. If so, then the method404may be marked as safe (e.g., tagged with a TreatAsSafe attribute). To determine this, the code path(s) of the method404are reviewed, e.g., those of callers I() and J(). This is generally referred to as reviewing up, where the upward direction is arbitrarily defined as inFIG. 4such that callers are “above” callees; reviewing up determines the criticality of the callers and helps determine a new treat as safe boundary if the current method cannot be one. Similarly, the downward code path(s) to the callees of the method404are reviewed; reviewing down determines the criticality of the callees to ensure that no critical data is leaked out.

While evaluating its callers and callees, if a trust boundary is reached in that a caller or callee is already marked as TreatAsSafe, then that code path is considered safe and need not be evaluated further. For example, inFIG. 4, the E() method is marked TreatAsSafe (TAS), and thus a trust boundary is reached on this path, whereby methods A() and B() (and any other higher methods that call them) need not be evaluated, as that particular code path is known safe. Note that some methods that are marked TreatAsSafe are because they will throw a security exception if the appropriate permissions are not available. This is also a viable TreatAsSafeBoundary.

In addition, the code developer may mark a certain function/method as specifically not being enabled in a sandbox environment, e.g., via a demand attribute or a link demand or an explicit demand in the code, as represented inFIG. 4by the method C(). In such a situation, there is no reason to evaluate that path since this calling path will otherwise not be allowed, and thus its callers need not be evaluated. This function can essentially be considered treat as safe from the perspective of the method404.

FIG. 5Ashows an example of a method504that cannot be marked treat as safe, because it stores (e.g., in some variable) critical data, shown as the shaded box marked C1, and/or has at least one caller to which it leaks critical data C2. Note that other ways of leaking criticality are feasible, but are not represented inFIG. 5A.

FIG. 5Bshows another example method505that cannot be treated as safe because it passes critical data C4to a callee Z() that leaks the data to an unsafe method W(), (wherein W() stores critical data in such a way that it is leaked to untrusted code). Note that other ways of leaking criticality are feasible, but are not represented inFIG. 5B.

Turning to an explanation of the operation of such technology in one example implementation,FIG. 6shows the reviewing of code following the initial security exception that that is thrown when some code attempts to do something that it does not have the required permission to do. For example, in a Windows® Presentation Foundation environment, when such a situation occurs, the demand fails and the .NET Framework runtime throws a SecurityException.

To locate such potential security flaws, a developer of a platform method may intentionally request some action be taken through the method that a requesting (sandboxed) program does not have permission to do, such as to write something to the file system, and thus cause a security exception. In general, this will start the analysis logic ofFIG. 6. Note that in addition to attempted file system reads or writes by some code, other examples of actions that will cause a security exception may include attempted reads or writes to a system registry, or attempts to call native operating system (e.g., Win32) functions.

Step602ofFIG. 6represents reviewing the method, including reviewing it to determine (as represented via step606) whether the code corresponds to an added elevation. Note that step604represents determining via a helper class whether the piece of code being evaluated may be refactored into smaller pieces, (e.g., functions), such as to break dangerous operations into smaller isolated functions, and determine whether those functions are able to contain the criticality and return safe data, whereby those smaller pieces may be marked treat as safe. However, for purposes of this example, this step604may be considered optional or already performed with respect to the code being evaluated.

In the event that there is no elevation being performed, step606branches to step608where the method (API in this example) can be considered not part of this sandbox. This situation may be documented, e.g., in a sandbox specification.

If the method elevates, step606branches to step610where the API is considered part of the sandbox, and is marked with a security critical (e.g., SecurityCritical attribute) tag at step610. The method is then further evaluated to determine whether it is safe, that is, whether it contains its criticality (is safe) or leaks any of its criticality (is not safe) to other methods.

Step612evaluates the method, including whether its inputs (e.g., params, class fields, and so forth) may be considered safe, whether its returned values are non-critical, and whether the API is otherwise safe. If so, step612branches to step614, where the method is marked as safe, e.g., via a TreatAsSafe tag. Note that the evaluation process may continue to evaluate its callees, as represented viaFIG. 8.

If not safe atFIG. 612because it may leak its criticality, the process branches to step702ofFIG. 7to evaluate the criticality of this method's callers. Essentially this branch corresponds to the “reviewing up” part of the evaluation, wherein each upward code path (the method's callers and any caller's callers and so forth) may be exploded into it various callers, with each caller recursively evaluated for safety.

FIG. 7represents the reviewing up process of the callers' code paths, in which each method in the code path is evaluated as to whether it is safe or leaks criticality.FIG. 8represents the reviewing down process of the callees' code paths, in which each method in the code path is evaluated as to whether it is safe or leaks criticality. Note that there is no particular order for selecting a caller or callee to evaluate, as long as each is evaluated. Also,FIGS. 7 and 8show only general example steps, and as mentioned above additional steps may exist for efficiency, e.g., a developer may put a demand on a method that ends the need to evaluate further in a given code path if that method is not going to be enabled for a sandbox, and a method already marked treat as safe need not be further exploded into its code paths.

In general, step702represents determining each of the primary method-under-test (API's) direct callers, with step704representing the test that ends this reviewing up process when all callers have been examined. Step706selects an unexamined caller as a currently selected caller, and adds the security critical tag to the currently selected caller, (as this caller is calling a security critical method (as previously determined at step606ofFIG. 6).

Steps708,710,712and714perform an analysis on the caller similar to that described with reference toFIG. 6, and indeed can recursively reuse at least part of the evaluation process described with reference toFIG. 6. Note that step714recursively reuses the code ofFIG. 7so that each of the currently selected caller's callers are likewise examined. In this manner, each code path is evaluated in a reviewing up process, that is, each caller and its callers are examined and tagged as appropriate (unless a code path is stopped via a caller having a demand or treat as safe tag already present). In the event that the callers can not be marked as treat as safe, the API is not available in this sandbox.

FIG. 8represents the reviewing down process of the callees, whether that callee is called by the API under test, by a direct or indirect caller of that API, or by another callee. Again, a general purpose ofFIG. 8is to determine whether criticality is leaked to any callee, to any caller of each callee, or to any callee of that callee. More particularly, this part of the process examines whether any critical data passed to a currently-selected callee is stored, e.g., in a variable, or leaked, that is passed to another method or methods.

To this end,FIG. 8evaluates for each callee (step802) whether that callee receives or accesses critical data (step804), and if so, whether the critical data is stored or leaked by the callee (step806). Note that critical data is tagged as such by the developer, and thus is readily identifiable. In the event that the critical data is not stored or leaked, step808is performed to confirm that this callee's usage of the critical data is indeed innocuous, which may include identifying the callee code for further audit.

Returning to step806, if the critical data is stored or leaked, step810is instead executed, which represents encapsulating the data (e.g., in a security critical data container as described in U.S. patent application Ser. No. 11/051,808, filed Feb. 4, 2005, assigned to the assignee of the present invention and hereby incorporated by reference), and refactoring. Step812represents confirming safe usage, e.g., via an audit, and step814adds a security critical tag to this current callee being evaluated.

Step816evaluates the API may be marked with the TreatAsSafe tag, and if not, the process explodes this callee's callers and evaluates them using the process described above with respect toFIG. 7. In any event, this callee's callees are also evaluated, e.g., recursively via the code ofFIG. 8, as represented via step818.

In this manner, a decision process as to when to mark a set of code (e.g., a method) as SecurityCritical and/or SecurityTreatAsSafe is realized. The process thus helps in developing secure code, including by identifying potential or actual security flaws.