FEATURE: WEB 2.0
Access Control in JavaScript Rodolfo Toledo and Éric Tanter, University of Chile
// A practical lightweight library based on aspect orientation provides expressive and extensible access control for JavaScript. //
THIRD-PARTY JAVASCRIPT code inclusion is a cornerstone of today’s Web 2.0 applications. Without it, rich, personalized start pages, such as on iGoogle and My Yahoo!, would be unthinkable. Facebook wouldn’t be as rich as it is without external applications. Even targeted advertising, such as Google AdSense, would be impossible. However, despite external code’s usefulness, including it poses a threat to the hosting page. JavaScript can modify the page’s layout and functionality to a potentially arbitrary degree. This raises several questions. What are the rights of external code? May it arbitrarily modify the host page layout or functionality? How can we restrict it
to only certain actions? Can we ensure it doesn’t degrade the user experience with the page? Other languages that also support dynamic loading of code, such as Java and C#, have a powerful access control architecture, letting developers expressively specify code’s rights. Although JavaScript’s most recent specification includes basic access control features,1 advanced control over access to sensitive resources requires external tools. These tools rely on a variety of approaches, including code analyses, code transformation, and runtime libraries. This article presents ZAC (short for Easy Access Control), a practical library for access control based on as-
76 I E E E S O F T W A R E | P U B L I S H E D B Y T H E I E E E C O M P U T E R S O C I E T Y
pect orientation. ZAC supports fi negrained access control in an extensible, expressive, and modular way.
Current Approaches The only way to control the rights of external code with the HTML standard is to use frames. Including a script in a frame gives full permissions to the script, but only over its enclosing frame. However, this option usually isn’t expressive enough, mainly because it’s too coarse-grained. For instance, it’s impossible to grant certain permissions to external code, such as showing alert dialogs, while forbidding others, such as accessing cookies. So, several proposals exist for controlling the actions scripts can perform in a webpage (see Table 1). ADsafe (www. adsafe.org) limits the JavaScript features external code can use, leaving only a “secure” subset of the language that can be statically checked to ensure it doesn’t perform potentially dangerous actions. FBJS (Facebook JavaScript; http:// developers.facebook.com/docs/fbjs) rewrites the code to replace references to standard objects with limited but equivalent objects, preventing any potentially dangerous action. Facebook uses FBJS for third-party applications. BrowserShield is more flexible and works in more scenarios. It transforms code to make it trigger notifications of its own activity during execution.2 An observer entity then decides whether to allow the code’s activity. Developers can specify new policies as functions, using JavaScript. Finally, Caja is a more principled approach to access control based on the object-capability model (http:// code.google.com/p/google-caja). In this model, external code can access (and therefore use) references to other objects 0 74 0 -74 5 9 / 11 / $ 2 6 . 0 0 © 2 0 11 I E E E
TABLE 1
JavaScript proposals for access control. Name
Enforcement
Based on
Extensible
Specification
Granularity
Adsafe
Static
Static analysis
No
None
Script
Facebook JavaScript
Static + dynamic
Object wrappers
No
None
Page
BrowserShield
Dynamic
Program monitoring
Yes
Blacklisting
Page
Caja
Static + dynamic
Object capabilities
Yes
Whitelisting
Script
ZAC
Dynamic
Dynamic aspect-oriented programming
Yes
Blacklisting
Object
only if the host page provides them. If no references are provided, the external code can still execute on the basis of its own (harmless) references. iGoogle and My Yahoo! use Caja. As Table 1 shows, ZAC combines interesting features. First, dynamic enforcement of policies enables execution of safe programs that use unsafe constructs. For example, programs that use eval only to deserialize JSON (JavaScript Object Notation; www.json.org) objects from strings, and not to execute arbitrary code, are safe. Because such programs use a potentially unsafe construct, systems such as ADsafe would reject them. Second, because ZAC policies are based on dynamic aspect-oriented programming (AOP), 3 they can reason about program execution in its entirety. For instance, you can defi ne a policy that prevents a script from never ending or taking too much time for acceptable Web interaction. Expressing such a policy in the object-capability model is impossible because the property depends not on object references but on the computation itself. Third, ZAC employs extensible access control specifications, which are crucial because different usage scenarios imply different requirements. Other proposals such as BrowserShield and Caja acknowledge this. Finally, object-level granularity is unique to ZAC. Letting different policies coexist for different scripts in a
ZAC.load(“http://www.evilsite.net/evil.js”, ZAC.newDefaultPolicy()); FIGURE 1. ZAC.load. This method loads a third-party script subject to the default access control policy.
webpage is fundamental. Going beyond the script level down to the object level also enables secure interaction among scripts. Objects from one script can use objects from other scripts, possibly with different policies; the correct policy will be unequivocally enforced. This isn’t the case with object capabilities, in which an untrusted object that obtains a reference to a sensitive resource can use it without limitations. The principle of ZAC is that foreign code can use every feature of JavaScript, including eval, and can access every reference to any object in the system. However, the access control policy assigned to the foreign code during loading forbids dangerous actions before they happen at runtime. In other words, ZAC employs blacklisting, which, despite being considered less safe than whitelisting, is actually used in real systems for access control. What’s more, it’s equivalent to the access control architectures of widely used languages such as Java and C#.4,5 (For more information, see the sidebar “Blacklisting vs. Whitelisting in Practice.”) Finally, ZAC also inherits the great expressive power of AspectScript,
the underlying general-purpose library for AOP.6
ZAC in Action ZAC is based on assigning access control policies when scripts are loaded. At runtime, ZAC enforces the policy for every action these scripts perform.
Loading Scripts A simple API makes enforcing access control policies easy. For example, to load a third-party script, a developer only needs to use the ZAC.load method (see Figure 1). After evil.js loads, its execution is automatically subject to the restrictions in the policy specified as the second argument. Policies in ZAC are sets of restrictions. Table 2 shows the restrictions in the policy returned by ZAC.newDefaultPolicy(), targeted to restrict access to common sensitive resources. For instance, the ZAC.R_ALERT forbids the use of alert dialogs. These dialogs normally provide valuable information to users but can also make a page (or even the whole browser) unusable by endlessly showing an alert dialog. Another example is ZAC.R_LOCATION, which forbids
S E P T E M B E R /O C T O B E R 2 0 11
| IEEE
S O F T W A R E 77
FEATURE: WEB 2.0
redirections of the page. This restriction prevents malicious scripts from sending the browser to potentially dangerous sites.
BLACKLISTING VS. WHITELISTING IN PRACTICE Whitelisting-based policies specify which resources system entities can access (for example, user X can use the printer). Blacklisting-based policies specify which resources system entities can’t access (for example, user Y can’t modify system files). In general, whitelisting is considered safer because access to resources can be granted gradually, minimizing the risk of inadvertently granting access to unneeded sensitive resources. This isn’t the case with blacklisting, in which it’s possible to forget to restrict access to a resource. Although whitelisting is superior from a conceptual viewpoint, blacklistingequivalent approaches are successfully used in practice. A compelling proof of this comes from the widespread use of Java and C#. Although their access control architectures appear to be based on whitelisting (because you declare permissions, not restrictions), in practice, they’re equivalent to blacklisting approaches. Permission checking in these architectures must be explicitly triggered at each relevant place in the code (using SecurityManager.checkPermission() in Java and . Demand() in C#). This means that forgetting to add the permission check associated with a sensitive resource in Java or C# is just like forgetting to restrict access to that resource in ZAC. (For more on ZAC, see the main article.) The dependency on explicit checks implies that the set of permissions is known in advance, so you can calculate the set of restrictions as the complement of the permissions. This makes the Java and C# architectures equivalent, in practice, to ZAC’s blacklisting architecture.
When loaded using ZAC.load, a script can’t bypass the specified access control policy, directly or indirectly. This means the script can’t perform any action forbidden by the policy and can’t lead other (possibly trusted) code to do it on its behalf. This is because ZAC supports stack-based access control,7 similarly to Java and C#. The semantics of stack-based access control says that each time a sensitive action is about to occur, the current stack of evaluation is inspected to determine whether all participating entities (in the case of JavaScript, objects and functions) may perform the action. If one entity isn’t allowed, ZAC aborts the action, typically by throwing an exception. To diminish the performance overhead, ZAC doesn’t inspect the stack every time a sensitive action occurs. In-
Direct invocation
Indirect invocation (using delegation)
Indirect invocation (using eval)
Scheduled invocation
alert(”I’m evil!”);
function info(msg){ alert(msg); } info(“I’m evil!”);
eval(”alert(\“I’m evil!”\”)”);
setTimeout(function(){ info(”I’m evil!”); }, 1000);
alert(..) R_ALERT
alert(..)
alert(..)
info(..)
eval()
evil.js R_ALERT
evil.js
evil.js R_ALERT Execution stack
(b) R_ALERT
1 second
setTimeout(..) evil.js R_ALERT
R_ALERT
Execution stack
Execution stack
Execution stack
(a)
Policy Enforcement
(c) Policy containing the ZAC.R_ALERT restriction
alert(..) info(..) anonymous function R_ALERT Execution stack
(d) Stack inspection order
FIGURE 2. Policy enforcement in ZAC. (a) Direct invocation. (b) Indirect invocation using delegation. (c) Indirect invocation using eval. (d) Scheduled invocation. All these attempts will fail with an exception raised by the access control policy. 78 I E E E S O F T W A R E | W W W. C O M P U T E R . O R G / S O F T W A R E
Defining Custom Policies Developers can modify ZAC policies by adding or removing restrictions (using the add and remove methods). This
TABLE 2
stead, it maintains the application’s security state at each necessary point. (For more information on ZAC performance overhead, see the related sidebar.) Figure 2 shows four attempts to call the alert function, all ending with an exception raised by the access control policy. The first is a direct call. The second uses delegation: the untrusted code invokes the (trusted) info function, which in turn tries to call alert. These attempts end with an exception because the stack contains an object whose policy doesn’t permit calls to alert. The third attempt is interesting because it uses eval. ZAC ensures that restrictions of the code that calls eval are inherited by the “eval-ed” code. So, this attempt also fails. The last attempt is more intricate. Although ZAC’s policies are specified at the level of scripts (loading them using load), they’re enforced at the level of individual objects. So, if an object is created during the execution of a script subject to a certain policy, that object’s execution will always be subject to that policy. Wherever the object goes, the policy follows it. Therefore, in the example, the policy is in the stack when the anonymous function calls info. This is why the fourth attempt also ends with an exception. Achieving such access control with any other proposal is impossible. For example, in capability-based access control, if the anonymous function manages to get a reference to the info function, there’s no way to prevent it from calling info to display an alert dialog. Once an object obtains a reference, it can use that reference at will, no matter which policy was originally assigned to it. This kind of security issue is equivalent to forgetting to enforce a particular restriction—in this case, R_ALERT.
Restrictions in ZAC’s default access control policy. Restrictions are accessed as properties of the ZAC global property. Restriction
Description
R_ALERT
Prevents alert calls
R_LOCATION
Prevents redirection of the browser
R_C_STYLES
Prevents calls to computedStyles()
R_INNER_HTML
Sanitizes strings assigned to the innerHTML property
R_COOKIES
Prevents access to cookies
R_GLOBAL
Prevents access to properties of the global object
R_EVAL
Prevents arbitrary use of eval (only JavaScript Object Notation deserialization)
R_FUN
Prevents instantiations of Function objects
R_STO_SI
Prevents calls to setTimeout and setInterval with a string argument
R_HTTP_REQ
Prevents instantiations of XMLHttpRequest objects
R_DEF_PROTOS
Prevents modification of prototypes of default objects
R_ARGS
Prevents access to other functions’ arguments property
R_WATCH
Prevents calls to watch and unwatch
R_UNENCR
Prevents calls to toSource and uneval
R_ZAC_POLICIES
Prevents access to ZAC policies
can prove useful in several scenarios. For instance, it seems natural to specify different policies for different foreign scripts, depending on the level of confidence the host page has in each of them. Another scenario is when a policy must be constructed programmatically (for example, according to user preferences). ZAC’s API lets programmers modify policies even after using them to load a script. These modifications will affect all the scripts already loaded using the policy. Besides default policies, developers can create fresh policies using ZAC.newPolicy(). The code in Figure 3 configures two policies to enforce different restrictions in two different scripts.
Extending ZAC Developers can extend ZAC policies by adding restrictions to protect other resources.
Defining Restrictions A restriction is a JavaScript object with two properties, both of which are functions. The rule property identifies the access to the resource; the action property specifies the action to take when the access occurs. For example, Figure 4 implements ZAC.R_ALERT. The function bound to rule identifies calls to alert by returning true when such calls occur. It uses the event parameter, which is a representation of the event occurring in the script. Table 3 lists
S E P T E M B E R /O C T O B E R 2 0 11
| IEEE
S O F T W A R E 79
ZAC PERFORMANCE OVERHEAD The performance overhead in ZAC has two main sources: event generation and the stack-inspection semantics for access control. Our previous research describes optimization techniques for event generation.1 To diminish access control’s performance overhead, ZAC doesn’t inspect the stack every time a sensitive action occurs. Instead, it uses a state-based approach that keeps the application’s security state up to date. This approach is similar to the optimization for control flow pointcuts commonly used when implementing aspect-oriented languages.2 In that situation, determining whether an action is in another action’s control flow is a matter of testing a variable while avoiding traversal of the stack. ZAC’s technique is also comparable to security-passing style, which passes an extra parameter representing the current security context to all functions.3 We could also integrate other implementation approaches, such as using continuation marks.4 This would eliminate depending on the stack to reason about access control (maintaining the same semantics) and enable interesting optimizations.5 To demonstrate the performance overhead introduced by ZAC policy enforcement, we selected the CPU-intensive tests of the jQuery library (www.jquery.com) and applied different policies to them. When executed with no restrictions, these tests generated more than 4.4 million events (property accesses, method calls, object creations, and so on) in approximately 20 seconds. Applying all the restrictions in Table 2 in the main article made the tests execute 15.5 times slower. Applying only R_ALERT reduced the overhead factor to just 3.8. To test ZAC in real-world scenarios, we developed a small prototype Firefox plugin based on it. This plug-in mimics the NoScript plug-in (www.noscript.net), which can forbid the execution of potentially malicious code. Our extension, with proper control of the generated events, is usable on many websites. Currently, users must explicitly configure the kinds of events to generate; we’re working on optimizations to automate this process.
References 1. R. Toledo, P. Leger, and É. Tanter, “AspectScript: Expressive Aspects for the Web,” Proc. 9th Int’l Conf. Aspect-Oriented Software Development (AOSD 10), ACM Press, 2010, pp. 13–24; doi:10.1145/1739230.1739233. 2. H. Masuhara, G. Kiczales, and C. Dutchyn, “A Compilation and Optimization Model for AspectOriented Programs,” Proc. 12th Int’l Conf. Compiler Construction (CC 03), LNCS 2622, Springer, 2003, pp. 46–60. 3. D. Wallach and E. Felten, “Understanding Java Stack Inspection,” Proc. 1998 IEEE Symp. Security and Privacy, IEEE Press, 1998, pp. 52–63; doi: 10.1109/SECPRI.1998.674823. 4. J. Clements, A. Sundaram, and D. Herman, “Implementing Continuation Marks in JavaScript,” Proc. 2008 Workshop Scheme and Functional Programming, ACM Press, 2008, pp. 1–9. 5. J. Clements and M. Felleisen, “A Tail-Recursive Machine with Stack Inspection,” ACM Trans. Programming Languages and Systems, vol. 26, no. 6, 2004, pp. 1029–1052.
the event types ZAC supports and the corresponding properties (fields and methods). The function bound to action simply throws an exception because invoking alert is completely forbidden.
ZAC evaluates the function bound to rule only when an object with that restriction participates in the current stack of execution, not for every event in the application.
80 I E E E S O F T W A R E | W W W. C O M P U T E R . O R G / S O F T W A R E
TABLE 3
FEATURE: WEB 2.0
Properties and methods of events supported by ZAC. Event name*
Properties**
New
fun, args
Init
target, fun, args
Call
target, fun, args, context, reflective
Exec
target, fun, args
PropRead
target, name
PropWrite
target, name, value
*Each event shares the common property parent and the common methods proceed(args), clone(), and is(). **fun: the function being used as a constructor (New and Init) or being called or executed (Call and Exec). args: the arguments of the event. target: the target of the event. context: the object performing the call. reflective: whether the call was performed using call or apply. parent: the parent event (like a stack of execution). proceed: executes the event. clone: clones the event (useful to store a reference). is(): Boolean-returning utility methods to identify the kind of event.
An alternative to simply throwing an exception is to provide, possibly under certain circumstances, an alternate “safe” behavior. For example, Java Script’s eval function is widely considered dangerous because it permits the execution of arbitrary, potentially malicious, code. However, eval has a useful application: deserialization of a JSON object from a string. Because a JSON object’s serialization format doesn’t permit functions, no arbitrary code can execute when evaluating the object serialized representation. In other words, using eval to deserialize JSON objects is safe. Figure 5 shows ZAC.R_EVAL, which only forbids the evaluation of code that isn’t in JSON format. Like ZAC.R_ALERT, rule identifies calls to a certain function—in this case, eval. The action property, instead of immediately throwing an exception, first tries to evaluate the first argument of eval(event.args[0]) as a JSON string. If the argument effectively is a JSON string, action returns the resulting
object. Otherwise, JSON.parse throws an exception; the restriction action then throws an exception, too.
Adding New Restrictions ZAC includes a set of predefi ned restrictions corresponding to common cases. Developers can also defi ne new kinds of restrictions. Figure 6 defi nes a new restriction that limits the number of windows a script can open. Stateful restrictions. A restriction can have any number of additional properties apart from rule and action. The previous example used the nWindows property to keep track of the number of windows the script opens. So, we call the restriction returned by nWindowsRestriction a stateful restriction. Adding a stateful restriction to more than one policy implies that these policies share its state. For this reason, a restriction such as the one returned by nWindowsRestriction will allow three windows in total, summing up all the windows opened by all scripts the restriction applies to. The restriction factory. To defi ne a restriction, creating an object with the appropriate properties suffices. However, using a restriction factory such as the nWindowsRestriction function has two advantages. First, we can easily parameterize the restriction (the n argument in the example). Second, we can obtain a different instance each time the factory is invoked, which can avoid the sharing issue of stateful restrictions. The proceed method. We can use proceed to execute the original behavior the event parameter represents in the script—in the example, the call to the open function. The proceed method accepts the same parameters as the original event. If specified, these parameters replace the original parameters passed to the event. If they’re omitted, the event executes with the original parameters.
var softPolicy = ZAC.newPolicy(); //fresh policy (no restrictions) //restrict only page redirections and evaluation of code in notSoEvil.js softPolicy.add(ZAC.R_LOCATION, ZAC.R_EVAL); ZAC.load(”http:// evilsite.net/notSoEvil.js”, softPolicy); //get a default policy and remove only the R_ALERT restriction for evil.js var hardPolicy = ZAC. newDefaultPolicy(); hardPolicy.remove(ZAC.R_ALERT); ZAC.load(”http://evilsite.net/evil.js”, hardPolicy); FIGURE 3. Configuration of two different policies according to the degree of trust in the scripts.
ZAC.R ALERT = { rule: function(event){ return event.isCall() && event.fun === alert; }, action: function(event){ throw ”Cannot call alert”; } }; FIGURE 4. ZAC.R_ALERT. This restriction forbids the use of alert dialogs.
ZAC.R_EVAL = { rule: function (event){ return event.isCall() && event.fun === eval; } , action: function (event){ try{ return JSON.parse(event.args[0]); } catch(e){ throw ”Eval can only be used to deserialize JSON objects.”; } } }; FIGURE 5. ZAC.R_EVAL. To prevent the introduction of potentially malicious code, this restriction limits the use of eval to deserializing JSON objects.
function nWindowsRestriction(n){ return { nWindows: 0, rule: function(event){ return event.isCall() && event.fun === document.open; }, action: function(event){ if(++this .nWindows > n){ throw ”Cannot open more than ” +n+ ” windows.”; } return event.proceed(); } }; } //add the restriction to a fresh policy var policy = ZAC.newPolicy().add(nWindowsRestriction(3)); FIGURE 6. Defining a new restriction. This restriction employs three interesting elements: a stateful restriction, a restriction factory, and event.proceed(). S E P T E M B E R /O C T O B E R 2 0 11
| IEEE
S O F T WA R E
81
FEATURE: WEB 2.0
function info(msg){ this.doPrivileged(function(){ alert(msg); }); } FIGURE 7. Use of privileged execution in info.
Privileged execution
function info(msg){ this.doPrivileged(function(){ alert(msg); } info(“I’m evil!”);
alert(..) doPrivileged(..)
info(..) evil.js R_ALERT Execution stack
Advanced Features In addition to enabling the defi nition of custom policies and restrictions, ZAC also offers more advanced features. First, privileged execution allows a piece of code to perform a potentially dangerous action on behalf of another (possibly untrusted) one. This mechanism is present in the Java Access Control platform.4 Second, developers can take advantage of AspectScript, the underlying AOP library. AspectScript aspects are written in full JavaScript, which can be used to defi ne more expressive restrictions.
Privileged Execution In some cases, one piece of code must perform a sensitive action on behalf of another. This could be the case for the info function we mentioned earlier: it might let any entity display an alert dialog, regardless of that entity’s access control policy. However, the stackbased access control mechanism doesn’t permit that. Languages such as Java can relax this constraint by executing a privileged action. This execution omits the restrictions of the objects in the control flow before the privileged action. It considers only the restrictions pertaining to objects up to the one initiating the privileged action. In terms of the stack inspection mechanism, privileged execution is analogous to ceasing to look in the stack of execution when the frame that initiated the privileged action is reached. The privileged-execution mechanism doesn’t circumvent access control. Any object can start a
R_ALERT
Policy containing the ZAC.R_ALERT restriction Stack inspection order End of stack inspection
FIGURE 8. Stack inspection in the presence of privileged execution. The info function can be used even by untrusted entities because the stack inspection stops when reaching the frame corresponding to the self-call to doPrivileged.
privileged execution, but it can’t get rid of its own restrictions because they’re maintained. In ZAC, a self-call to doPrivileged starts a privileged action, and it specifies the code to execute in this privileged context as the body of the function passed as a parameter. Figure 7 shows a possible implementation of info. Figure 8 depicts stack-based access control in the presence of a privileged execution. When alert is about to be called, the stack is inspected up to the frame that initiated the privileged action. So, the frame corresponding to the object that is subject to the ZAC.R restriction isn’t reached. Privileged execution has some dangers; a trusted entity takes complete responsibility for its actions in a privileged execution. For instance, the previously updated defi nition of info lets any object in the application, trusted or not, display alert dialogs. Nevertheless, once the flow of execution returns to untrusted entities, these entities’ restrictions apply again. doPrivileged acts as a marker method
82 I E E E S O F T W A R E | W W W. C O M P U T E R . O R G / S O F T W A R E
signaling a privileged execution. Objects can use their own implementations of doPrivileged; the only requirement is to maintain the name. Figure 9 shows a default implementation of this method that simply invokes this function argument. ZAC’s semantics for privileged execution states that any self-call to doPrivileged starts a privileged action. Nonself-calls to doPrivileged aren’t considered privileged executions. So, an untrusted object can’t call doPrivileged on a trusted object to bypass access control. Of course, because ZAC identifies privileged actions by the name doPrivileged, programmers must be careful not to use this method name inadvertently.
Exploiting AspectScript As we mentioned before, we implemented ZAC on top of AspectScript, a JavaScript extension adding support for AOP. AspectScript represents execution of a program as a series of join points (a function call, a property access, an object creation, and so on—see Table 3). A pointcut identifies a set of
join points; a piece of advice is the action to be taken at a join point matched by a pointcut. In AspectScript, an aspect is a pointcut-advice pair, in which both pointcuts and advices are plain JavaScript functions that receive a join point as a parameter. AspectScript’s aspects correspond exactly to ZAC’s restrictions; the rule property is the pointcut, and the action property is the piece of advice. ZAC implements policy enforcement (stack-based access control and privileged actions) on the basis of dynamic deployment of aspects and expressive scoping.8 ZAC depends only on AspectScript to be secure. If AspectScript generates all the events associated with the execution of all untrusted objects, these objects can’t do anything without ZAC being aware of it. This is why ZAC policies can’t be circumvented. ZAC’s implementation on top of AspectScript brings many benefits; we highlight two here. First, AspectScript includes predefi ned pointcuts that you can combine to identify more intricate actions. For example, the pointcut in Figure 10 identifies the calls to alert that occur in the body of any method of obj. Pointcuts can also match sequences of events, optionally restricted by temporal conditions. This can be useful in access control to, for instance, forbid invocations to alert that occur too frequently—say, more than one per second. Second, ZAC’s ability to reason about a program’s execution derives from AspectScript’s generation of join points for every action in the scripts, evaluating pointcuts for each of them. In a capability-based model, for instance, reasoning about the history of program execution is impossible. This is because the model considers accessing a reference and executing some methods as the only way to threaten a system. However, other interesting security properties exist that are related to the actual computation of programs. An
obj.doPrivileged = function(action){ action(); }; FIGURE 9. A possible definition of doPrivileged.
var PCs = AspectScript.Pointcuts; var pc = PCs.call(alert).and(PCs. within(obj)); FIGURE 10. Identification of calls to alert that occur in the body of any method of obj.
function nInstructionsRestriction(n){ return { nInstructions: 0, rule: function(event){ return ++nInstructions > n; }, action: function(event){ if (confirm(“This script is running for too long. Abort it?”){ throw “Cannot execute more than ” +n+ “ instructions”; } nInstructions = 0; return event.proceed(); } }; } FIGURE 11. Defining a custom restriction with ZAC.
example of a security property based on actual computation—which is actually checked by most browsers—is to ensure that third-party scripts don’t degrade the user’s interactive experience. If a script takes too long to execute, the browser suspends its execution and asks the user whether to abort the script. Although such a restriction is beyond the realm of object capabilities, Figure 11 shows that defi ning it with ZAC is straightforward. For simplicity, we use instruction count rather than actual time. The point here is to demonstrate the wide range of policies that we can express using dynamic AOP as a foundation for defi ning restrictions.
A
ccess control is crucial to most applications where multiple actors interact. This is especially true for Web 2.0 applica-
tions, where external code inclusion is very common. Enabling practical access control in this scenario poses a couple of challenges. First, it should be sufficiently efficient (both in memory and speed) to be invisible to the user. Second, it should be sufficiently expressive to allow developers to defi ne their own policies effortlessly and to not overly restrict the programming model of the code subject to access control. In ZAC, there’s still room for improvement in both areas, but it represents a fi rst step toward a solution combining both of them. ZAC is available at http://pleiad.cl/ aspectscript/zac; AspectScript is available at http://pleiad.cl/aspectscript.
References 1. ECMAScript Language Specifi cation ECMA262, 5th ed., ECMA Int’l, 2009. 2. C. Reis et al., “Browsershield: VulnerabilityDriven Filtering of Dynamic HTML,” ACM
S E P T E M B E R /O C T O B E R 2 0 11
| IEEE
S O F T W A R E 83
ABOUT THE AUTHORS
FEATURE: WEB 2.0
RODOLFO TOLEDO is a doctoral candidate in the University of
Chile’s Department of Computer Science. His research interests include language support for security-related concerns and modularization of access control via aspect orientation. Toledo has an engineering degree in computer science from the University of Chile. He’s a member of the ACM. Contact him at
[email protected].
3.
4. 5.
6.
ÉRIC TANTER is an associate professor in the University of Chile’s Department of Computer Science, where he coleads the Programming Languages and Environments for Intelligent, Adaptable and Distributed Systems Laboratory. His research interests include various dimensions of programming languages and paradigms, from foundations to applications to software engineering issues. Tanter has a PhD in computer science from the University of Nantes and University of Chile. He’s a member of the ACM, IEEE, and the Chilean Computer Science Society. Contact him at
[email protected].
7.
8.
Trans. Web, vol. 1, no. 3, 2007, article 11; doi:10.1145/1281480.1281481. T. Elrad, R.E. Filman, and A. Bader, “AspectOriented Programming,” Comm. ACM, vol. 44, no. 10, 2001, pp. 29–32. J. Gosling et al., The Java Language Specifi cation, 3rd ed., Addison-Wesley, 2005. A. Hejlsberg, S. Wiltamuth, and P. Golde, C# Language Specifi cation, Addison Wesley Longman, 2003. R. Toledo, P. Leger, and É. Tanter, “AspectScript: Expressive Aspects for the Web,” Proc. 9th Int’l Conf. AspectOriented Software Development (AOSD 10), ACM Press, 2010, pp. 13–24; doi:10.1145/1739230.1739233. C. Fournet and A.D. Gordon, “Stack Inspection: Theory and Variants,” ACM Trans. Programming Languages and Systems, vol. 25, no. 3, 2003, pp. 360–399. É. Tanter, “Expressive Scoping of Dynamically-Deployed Aspects,” Proc. 7th Int’l Conf. Aspect-Oriented Software Development (AOSD 08), ACM Press, 2008, pp. 13–24.
handles the details so you don’t have to! Professional management and production of your publication Inclusion into the IEEE Xplore and CSDL Digital Libraries Access to CPS Online: Our Online Collaborative Publishing System Choose the product media type that works for your conference: Books, CDs/DVDs, USB Flash Drives, SD Cards, and Web-only delivery!
Contact CPS for a Quote Today! www.computer.org/cps or
[email protected]
84 I E E E S O F T W A R E | W W W. C O M P U T E R . O R G / S O F T W A R E