Abstract. Type specialization can serve as a powerful tool in enforcing safety properties on foreign code. Using the specification of a monitoring interpreter, polyvariant type specialization can produce compiled code that is guaranteed to obey a specified safety policy. It propagates a security state at compile-time and generates code for each different security state. The resulting code contains virtually no run-time operations on the security state, at the price of some code duplication. A novel extension of type specialization by intersection types limits the amount of code duplication considerably, thus making the approach practical.A few years back, mobile code was merely an exciting research subject. Meanwhile, the situation has changed dramatically and mobile code is about to invade our everyday lives. Many applications load parts of their code -or even thirdparty extension modules-from the network and run it on the local computer. Web browsers are the most prominent of these applications, but many others (e.g., mobile agents) are gaining importance quickly.The advent of these applications and related incidents has brought an increasing awareness of the problems involved in executing foreign and potentially hostile programs. Clearly, it should be guaranteed that foreign code does not compromise the hosting computer, by crashing the computer (data integrity), by accessing/modifying data that it is not supposed to access (memory integrity) or -more generally-by using resources that it is not supposed to use. A generally accepted way of giving this guarantee is to execute the code in a sand box. Conceptually, a sand box performs monitored execution. It tracks the execution of foreign code and stops it if it attempts an illegal sequence of actions. A property that can be enforced in this way is called a safety property.Such sand box environments have been conceived and implemented with widely different degrees of sophistication. The obvious approach to such a sand box is to perform monitoring by interpreting the code. However, while the approach is highly flexible it involves a large interpretation overhead. Another approach, taken by the JDK [14], is to equip strategic functions in a library with calls to a security manager. A user-provided instantiation of the security manager is then responsible to keep track of the actions and to prevent unwanted actions. The latter approach is less flexible, but more efficient. Java solves the problem of data and memory integrity statically by subjecting all programs to a bytecode verification process [18].