does not seem to like wrapping _code
[parrot.git] / docs / pdds / pdd18_security.pod
blob9d5d8046c74846684ea4af300b0ce73ca6662c3b
1 # Copyright (C) 2007-2010, Parrot Foundation.
2 # $Id$
4 =head1 PDD 18: Security Model
6 =head2 Abstract
8 This PDD describes the security infrastructure of Parrot.
10 =head2 Version
12 $Revision$
14 =head2 Description
16 Parrot will be used in a variety of different application contexts, each with
17 its own unique security needs.
19 =over 4
21 =item * Small devices such as cell phones need tight control over resource
22 usage (CPU, memory, etc).
24 =item * Web applications need filtering and validation of incoming data and
25 blocks to prevent the use of unfiltered data in execution contexts (SQL,
26 system calls, runtime eval, etc).
28 =item * Web browser embedding, i.e. client-side execution of high-level
29 languages, needs control over resource access on the client machine (local
30 disk access, local network connections), sandboxing for downloaded code,
31 limits on what code can be loaded and executed, and limits on certain dynamic
32 features (runtime eval of code, modification of global namespaces).
34 =item * Database engine embedding, i.e. server-side execution of high-level
35 languages as stored procedures, also needs control over resource access (disk
36 access, network connections), and limits on loaded code, but additionally
37 needs administrator configured lists of allowed libraries and library paths.
39 =item * Security auditing tools need hooks in the compilation process for
40 static analysis.
42 =back
44 =head2 Implementation
46 Parrot's security infrastructure is not an independent, encapsulated
47 subsystem.  It is a series of related features and functionality spread
48 throughout the virtual machine.
50 =head3 Resource Quotas
52 Resource quotas ensure that an interpreter doesn't use more CPU time, memory,
53 or system resources than are allowed. Quotas are most useful when running code
54 in a managed environment such as a web, database, or game server where no one
55 interpreter is allowed to consume too many resources and impact the system too
56 badly. CPU time is managed by the runloop. The memory system handles memory
57 quotas, the I/O system handles file open and pending I/O count quotas, and so
58 on.
60 =head3 Privileges
62 A privilege system is used to restrict code from performing certain
63 actions. When privilege checking is in force the code may need a particular
64 privilege to load a library, or open a file.
66 Privileges can be quite broad, on the order of "allow file I/O", or as
67 fine-grained as allowing/denying the right to run one particular opcode.
68 Privileges are discrete entities, They are also hierarchical, one privilege
69 can be specified to follow from another privilege (the privilege FOO may be
70 automatically granted to anything with the privilege BAR). Anything with the
71 ALL privilege is automatically granted all other privileges in the system.
72 Privileges are user-definable, but user-defined privileges can only give
73 grants of rights, they cannot take them (BAZ may grant its privileges to any
74 user with FOO privileges, but it can't automatically grant itself all the FOO
75 privileges).
77 A few example privileges:
79 =over 4
81 =item ALL
83 Granted all privileges.
85 =item IO
87 May run I/O operations.
89 =item INVOKE
91 May invoke subroutines, methods, or return continuations.
93 =item RETURN
95 May invoke return continuations (not subroutines or methods). (RETURN
96 privileges are granted to anyone with INVOKE privileges.)
98 =item SYSCALL
100 May run a system call.
102 =item COMPILE
104 May compile code from string source at runtime (eval).
106 =item LOAD
108 May load libraries at runtime.
110 =back
112 =head4 Users
114 For the most part, a "user" in the Parrot privilege system doesn't correspond
115 to a literal user (though it may, if Parrot is running embedded in a database
116 engine or multi-user gaming system). A user is a bundle of privileges,
117 identified by a user ID, and authenticated with a pass key. The privilege ID
118 can be cheaply passed around, and validated whenever a restricted action is
119 performed.
121 =head4 Opcode Disabling
123 All opcodes in Parrot can be selectively disabled, by short name (C<print>),
124 long name (including signature, C<print_sc>), or by group (C<io>, C<net>,
125 C<load>, C<compile>). They can also be selectively enabled, by defining a
126 privilege with "disable all", and then allowing only specific opcodes.
128 When running in a secured mode, all dynamically loaded opcode libraries are
129 disabled by default, and have to be explicitly enabled (individually, as a
130 group, or by a system-wide configuration).
132 Opcodes are tagged with their group in their definition, and may be tagged in
133 multiple groups, as in:
135   inline op print(in INT) :base_io,io {
136       ...
137   }
139 =head4 Library Loading
141 In certain environments, it's desirable to be able to restrict what libraries
142 may be loaded by code running on the virtual machine. The allowed library list
143 is defined in a system-wide configuration file, or set at runtime by a user
144 with administrative privileges. Libraries may be signed, with the key
145 specified in the library list and verified on loading. Libraries that can't be
146 signed (C libraries), can be check-summed to ensure that the library you load
147 is the exact file you expect.
149 Generally, library loading restrictions are useful in an embedded environment
150 like a database engine or web browser, or a multi-user environment like a web
151 hosting server, where arbitrarily extended behavior is a security risk. It can
152 also be a useful development tool, as running your daily development
153 environment with library loading restrictions turned on means you always know
154 exactly what dependencies the code base has.
156 =head4 Resource Access
158 Access to resources such as the local disk, network, are controlled through
159 the privilege system. Resource access limitations are a combination of
160 disabled opcodes, blocked library loading, and privilege checks within
161 standard libraries for I/O, network, etc.
163 =head3 Sandboxing
165 A sandbox is a virtual machine within the virtual machine. It's a safe zone to
166 contain code from an untrusted source. In the extreme case, a sandbox is
167 completely isolated from all outside code, with no access to read or write to
168 the surrounding environment. In the general case, a sandbox will have the
169 ability to read from, but not write to the surrounding environment (global
170 namespaces, for example), with a very narrow and carefully filtered route to
171 send some data back to the code that called it. The sandbox system works
172 together with the privileges system, in that by default code in the sandbox
173 has no privileges outside the sandbox, but may be granted privileges.
175 =head3 Data Firewall
177 Any data that originates from user input (command-line, user prompt, web form,
178 file access, network operation) is a potential security risk. The best place
179 to trap bad data is at the point of entry, before it touches a single line of
180 code. When the data firewall is enabled, all data entering from an external
181 source or crossing a sandbox barrier is subjected to filter rules. The filter
182 rules in force are configurable, and filters can be selectively enabled and
183 disabled for particular types and sources of data.
185 Data filters can be sanitizing or validating. Sanitizing data filters modify
186 the data as it passes (escaping quotes, encoding entities, etc). Validating
187 filters check that the data meets certain conditions (the presence or absence
188 of specific features), and when it fails to meet those conditions, the data is
189 blocked from passing the firewall (returning an empty string or PMCNULL
190 instead of the expected data). Data filters can also be user-defined, as a
191 regular expression (PGE rule) or subroutine.
193 The same filter rules applied within the data firewall can be called
194 explicitly on any data.
196 =head3 Bytecode Validation
198 In normal operation the interpreter assumes that the bytecode that it executes
199 is valid -- that is, any parameters to opcodes are sane, data structures are
200 intact. When bytecode validation is enabled, however, Parrot assumes that
201 bytecode is not necessarily valid. The interpreter then, at runtime, makes
202 sure that all specified register numbers are within valid range, and string
203 and PMC structures used are valid.
205 =head3 Auditing Hooks
207 Even in dynamic languages, it's possible to perform a degree of static
208 analysis for security risks. The opcode syntax tree (OST) produced by the
209 language compiler is a good data source for static analysis checks, because
210 it's low-level enough that you can check for individual opcodes that will be
211 called (checking for I/O, networking, and other similar operations, or unknown
212 dynamically-loaded opcodes), and high-level enough that you still have access
213 to substantial metadata from the parse. The standard compiler tools already
214 have the ability to add and remove stages from the compilation process. Static
215 analysis tools can be implemented by stopping the standard compilation at the
216 OST phase, and inserting an additional phase to scan the OST. Because the OST
217 form is standard across high-level languages running on Parrot, the tools can
218 be written once and applied to many languages.
220 =head2 References
222 "Exploring the Broken Web": L<http://talks.php.net/show/osdc07>
224 "Safe ERB": L<http://agilewebdevelopment.com/plugins/safe_erb>
226 pecl/filter: L<http://us2.php.net/filter>
228 Rasmus Lerdorf for the term "data firewall".
230 =cut
232 __END__
233 Local Variables:
234   fill-column:78
235 End:
236 vim: expandtab shiftwidth=4: