Chapter 20. Safe-Tk and the Browser Plugin

This chapter describes Safe-Tk that lets untrusted scripts display and manipulate graphical user interfaces. The main application of Safe-Tk is the Tcl/Tk plugin for Web browsers like Netscape Navigator and Internet Explorer.

Safe-Tk supports network applets that display user interfaces. The main vehicle for Safe-Tk is a plugin for Netscape Navigator, Mozilla and Internet Explorer. The plugin supports Tcl applets, or Tclets, that are downloaded from the Web server and execute inside a window in a Web browser. For the most part, Tcl/Tk applications can run unchanged in the plugin. However, security policies place some restrictions on Tclets. The plugin supports multiple security policies, so Tclets can do a variety of interesting things in a safe manner.

You can configure the plugin to use an existing wish application to host the Tcl applets if you require a newer version of Tk, or the plugin can load the Tcl/Tk shared libraries and everything runs in the browser process. You can use a custom wish that has extensions built in or dynamically loaded. This gives intranet applications of the plugin the ability to access databases and other services that are not provided by the Tcl/Tk core. With the security policy mechanism you can still provide mediated access to these resources. This chapter describes how to set up the plugin.

Jeff Hobbs recently updated the plugin to use Tcl/Tk 8.4. Compiled versions of the plugin are available as part of the Tcl Dev Kit from ActiveState. The source code of the plugin is freely available. You can recompile the plugin against newer versions of Tcl/Tk, or build custom plugins that have your own Tcl extensions built in. You can find its sources at:

Tk in Child Interpreters

A child interpreter starts out with just the core Tcl commands. It does not include Tk or any other extensions that might be available to the parent interpreter. This is true whether or not the child interpreter is declared safe. You add extensions to child interpreters by using a form of the load command that specifies an interpreter:

load {} Tk child

Normally, load takes the name of the library file that contains the extension. In this case, the Tk package is a static package that is already linked into the program (e.g., wish or the plugin), so the file name is the empty string. The load command calls the Tk initialization procedure to register all the Tcl commands provided by Tk.

Embedding Tk Windows

By default, a slave interpreter that loads Tk gets a new top-level window. Wish supports a -use command line option that directs Tk to use an existing window as dot. You can use this to embed an application within another. For example, the following commands run a copy of Wish that uses the .embed toplevel as its main window:

toplevel .embed
exec wish -use [winfo id .embed] somescript.tcl &

More often, embedding is used with child interpreters. If the interpreter is not safe, you can set the argv and argc variables in the slave before loading Tk:

interp create trustedTk
interp eval trustedTk 
     [list set argv [list -use [winfo id .embed]]]
interp eval trustedTk [list set argc 2]
load {} Tk trustedTk

If the child interpreter is safe, then you cannot set argv and argc directly. The easiest way to pass -use to a safe interpreter is with the safe::loadTk command:

safe::interpCreate safeTk
safe::loadTk safeTk -use [winfo id .embed]

When Tk is loaded into a safe interpreter, it calls back into the master interpreter and evaluates the safe::TkInit procedure. The job of this procedure is to return the appropriate argv value for the slave. The safe::loadTk procedure stores its additional arguments in the safe::tkInit variable, and this value is retrieved by the safe::TkInit procedure and returned to the slave. This protocol is used so that a safe interpreter cannot attempt to hijack the windows of its master by constructing its own argv variable!

Safe-Tk Restrictions

When Tk is loaded into a safe interpreter, it hides several Tk commands. Primarily these are hidden to prevent denial of service attacks against the main process. For example, if a child interpreter did a global grab and never released it, all input would be forever directed to the child. Table 20-1 lists the Tk commands hidden by default from a safe interpreter. The Tcl commands that are hidden in safe interpreters are listed on page 295.

Table 20-1. Tk commands omitted from safe interpreters

bell

Rings the terminal bell.

clipboard

Accesses the CLIPBOARD selection.

grab

Directs input to a specified widget.

menu

Creates and manipulates menus, because menus need grab.

selection

Manipulates the selection.

send

Executes a command in another Tk application.

tk appname

Sets the application name.

tk_chooseColor

Color choice dialog.

tk_chooseDirectory

Directory chooser dialog.

tk_getOpenFile

File open dialog.

tk_getSaveFile

File save dialog.

tk_messageBox

Simple dialog boxes.

toplevel

Creates a detached window.

wm

Controls the window manager.

If you find these restrictions limiting, you can restore commands to safe interpreters with the interp expose command. For example, to get menus and toplevels working, you could do:

interp create -safe safeTk
foreach cmd {grab menu menubutton toplevel wm} {
    interp expose safeTk $cmd
}

Instead of exposing the command directly, you can also construct aliases that provide a subset of the features. For example, you could disable the -global option to grab. Aliases are described in detail in Chapter 19.

The Browser plugin defines a more elaborate configuration system to control what commands are available to slave interpreters. You can have lots of control, but you need to distribute the security policies that define what Tclets can do in the plugin. Configuring security policies for the plugin is described later.

The Browser Plugin

The HTML EMBED tag is used to put various objects into a Web page, including a Tcl program. Example 20-1 shows the EMBED tag used to insert a Tclet:

Example 20-1. Using EMBED to insert a Tclet

<EMBED
   TYPE="application/x-tcl"
   PLUGINSPAGE="http://www.tcl.tk/plugin/"
   WIDTH="400"
   HEIGHT="300"
   SRC="eval.tcl"
</EMBED>

The width and height are interpreted by the plugin as the size of the embedded window. The src specifies the URL of the program. These parameter names (e.g., width) are case sensitive and should be lowercase. In the above example, eval.tcl is a relative URL, so it should be in the same directory as the HTML file that has the EMBED tag. The window size is fixed in the browser, which is different from normal toplevels in Tk. The plugin turns off geometry propagation on your main window so that your Tclet stays the size allocated.

There are also "full window" Tclets that do not use an EMBED tag at all. Instead, you just specify the .tcl file directly in the URL. In this case, the plugin occupies the whole browser window and will resize as you resize the browser window.

The embed_args and plugin Variables

The parameters in the EMBED tag are available to the Tcl program in the embed_args variable, which is an array with the parameter names as the index values. For example, the string for a ticker-tape Tclet can be passed in the EMBED tag as the string parameter, and the Tclet will use $embed_args(string) as the value to display:

<EMBED src=ticker.tcl width=400 height=50 string="Hello World">

Note that HTML tag parameters are case sensitive. Your Tclet may want to map all the parameter names to lowercase for convenience:

foreach {name value} [array get embed_args] {
   set embed_args([string tolower $name]) $value
}

The plugin array has version, patchLevel, and release elements that identify the version and release date of the plugin implementation.

Example Plugins

The plugin home page is a great place to find Tclet examples. There are several plugins done by the Tcl/Tk team at Sunlabs, plus links to a wide variety of Tclets done on the Net.

My first plugin was calculator for the effective wheel diameter of multigear bicycles. Brian Lewis, who built the Tcl 8.0 byte-code compiler, explained to me the concept and how important this information is to bicycle enthusiasts. The Tclet that displays the gear combinations on a Tk canvas and lets you change the number of gears and their size. You can find the result at:

Setting Up the plugin

There are plugin versions for UNIX, Windows, and Macintosh. The installation details vary somewhat between platforms and between releases of the plugin. The following components make up the plugin installation:

  • The plugin shared libraries (i.e., DLLs)The Web browser dynamically loads the plugin implementation when it needs to execute a Tclet embedded in a Web page. There is a standard directory that the browser scans for the libraries that implement plugins.

  • The Tcl/Tk script librariesThe plugin needs the standard script libraries that come with Tcl and Tk, plus it has its own scripts that complete its implementation. Each platform has a plugin script directory with these subdirectories: tcl, tk, plugin, config, safetcl, and utils. The plugin implementation is in the plugin directory.

  • The security policiesThese are kept in a safetcl directory that is a peer of the Tcl script library.

  • The trust configurationThis defines what Tclets can use which security policies. This is in a config directory that is a peer of the Tcl script library.

  • Local hooksLocal customization is supported by two hooks, siteInit and siteSafeInit. The siteInit procedure is called from the plugin when it first loads, and siteSafeInit is called when each applet is initialized. It is called with the name of the slave interpreter and the list of arguments from the <EMBED> tag. You can provide these as scripts that get loaded from the auto_path of the master interpreter. Chapter 12 describes how to manage script libraries found in the auto_path. The plugin also sources a personal start up script in which you can define siteInit and siteSafeInit. This script is ~/.pluginrc on UNIX and plugin/tclplugin.rc on Windows and Macintosh.

Security Policies and Browser Plugin

Tclets run in a safe interpreter that is set up with the safe base facilities described on page 300. This limits a Tclet to a display-only application. To do something more interesting, you must grant the Tclet more privilege. The extra functions are bundled together into a security policy, which is implemented as a set of command aliases. Unlike a Java applet, a Tclet can choose from different security policies. A few standard security policies are distributed with the plugin, and these are described below. You can also create custom security policies to support intranet applications. You can even choose to grant certain Tclets the full power of Tcl/Tk. The policy command is used to request a security policy:

policy name

The policies that are part of the standard plugin distribution are described below. The home, inside, and outside policies all provide limited network access. They differ in what set of hosts are accessible. The default trust configuration lets any Tclet request the home, inside, or outside policy.

  • homeThis provides a socket and fconfigure commands that are limited to connecting to the host from which the Tclet was downloaded. You can specify an empty string for the host argument to socket to connect back to the home host. This policy also supports open and file delete that are similar to the Tempfile policy shown in Example 19-9 on page 304. This provides limited local storage that is inside a directory that is, by default, private to the Tclet. Files in the private directory persist after the Tclet exits, so it can maintain long term state. Tclets from the same server can share the directory by putting the same prefix=partialurl argument in their EMBED tag. The partialurl must be a prefix of the Tclet's URL. Finally, the home policy automatically provides a browser package that is described later.

  • insideThis is just like the home policy, except that the site administrator controls a table of hosts and ports to which untrusted slaves can connect with socket. A similar set of tables control what URLs can be accessed with the browser package. This is similar to the Safesock policy shown in Example 19-8 on page 302. The set of hosts is supposed to be inside the firewall. The local file storage used by this policy is distinct from that used by the home and outside policies. This is true even if Tclets try to share by using the prefix=partialurl parameter.

  • outsideThis is just like the home and inside policies, except that the set of hosts is configured to be outside the firewall. The local file storage used by this policy is distinct from that used by the home and inside policies.

  • trustedThis policy restores all features of Tcl and Tk. This policy lets you launch all your Tcl and Tk applications from the Web browser. The default trust map settings do not allow this for any Tclet. The trust map configuration is described later.

  • javascriptThis policy provides a superset of the browser package that lets you invoke arbitrary Javascript and to write HTML directly to frames. This does not have the limited socket or temporary file access that the home, inside, and outside policies have. However, the javascript policy places no restrictions on the URLs you can fetch, plus it lets Tclets execute Java-script, which may have its own security risks. The default trust map settings do not allow this for any Tclet.

The Browser Package

The browser package is bundled with several of the security policies. It makes many features of the Web browser accessible to Tclets. They can fetch URLs and display HTML in frames. However, the browser package has some risks associated with it. HTTP requests can be used to transmit information, so a Tclet using the policy could leak sensitive information if it can fetch a URL outside the firewall. To avoid information leakage, the inside, outside, and home policies restrict the URL that can be fetched with browser::getURL. Table 20-2 lists the aliases defined by the browser package.

Table 20-2. Aliases defined by the browser package

browser::status string

Displays string in the browser status window.

browser::getURL url ?timeout? ?newcallback? ?writecallback? ?endcallback?

Fetches url, if allowed by the security policy. The callbacks occur before, during, and after the url data is returned.

browser::displayURL url frame

Causes the browser to display url in frame.

browser::getForm url data ?raw? ?timeout? ?newcallback? ?writecallback? ?endcallback?

Posts data to url. The callbacks are the same as for browser::getURL. If raw is 0, then data is a name value list that gets encoded automatically. Otherwise, it is assumed to be encoded already.

browser::displayForm url frame data ?raw?

Posts data to url and displays the result in frame. The raw argument is the same as in browser::getForm.

The browser::getURL function uses the browser's built-in functions, so it understands proxies and supports ftp:, http:, and file: urls. Unfortunately, the browser::getURL interface is different from the http::geturl interface. It uses a more complex callback scheme that is due to the nature of the browser's built-in functions. If you do not specify any callbacks, then the call blocks until all the data is received, and then that data is returned. The callback functions are described in Table 20-3.

Table 20-3. The browser::getURL callbacks

newcallback name stream url mimetype datemodified size

This is called when data starts to arrive from url. The name identifies the requesting Tclet, and the stream identifies the connection. The mimetype, datemodified, and size parameters are attributes of the returned data.

writecallback name stream size data

This is called when size bytes of data arrive for Tcllet name over stream.

endcallback name stream reason data

This is called when the request has completed, although there may be some final bytes in data. The reason is one of: EOF, NETWOR_ERROR, USER_BREAK, or TIMEOUT.

Configuring Security Policies

There are three aspects to the plugin security policy mechanism: policies, features, and trust maps. A policy is an umbrella for a set of features that are allowed for certain Tclets based on the trust map. A feature is a set of commands and aliases that are defined for a safe interpreter that requests a policy. The trust map is a filter based on the URL of the Tclet. In the future, trust may bet determined by digital signatures instead of URLs. The trust map determines whether a Tclet can request a given policy.

Note

Configuring Security Policies

Security Policies are configured for each client.

Remember that the configuration files affect the client machine, which is the workstation that runs the Web browser. If you create Tclets that require custom security policies, you have the burden of distributing the configuration files to clients that will use your Tclets. You also have the burden of convincing them that your security policy is safe!

The config/plugin.cfg File

The main configuration file is the config/plugin.cfg file in the plugin distribution. This file lists what features are supported by the plugin, and it defines the URL filters for the trust map.

The configuration file is defined into sections with a section command. The policies section defines which Tclets can use which security policies. For example, the default configuration file contains these lines in the policies section:

section policies
    allow home
    disallow intercom
    disallow inside
    disallow outside
    disallow trusted
    allow javascript ifallowed trustedJavaScriptURLS 
          $originURL

This configuration grants all Tclets the right to use the home policy, disallows all Tclets from using the intercom, inside, outside, and trusted policies, and grants limited access to the javascript policy. If you are curious, the configuration files are almost Tcl, but not quite. I lost an argument about that one, so these are stylized configuration files that follow their own rules. For example, the originURL variable is not defined in the configuration file but is a value that is tested later when the Tclet is loaded. I'll just give examples here and you can peer under the covers if you want to learn how they are parsed.

The ifallowed clause depends on another section to describe the trust mapping for that policy. For the javascript policy, the config/plugin.cfg file contains:

section trustedJavascriptURLs
    allow http://sunscript.sun.com:80/plugin/javascript/*

Unfortunately, this server isn't running anymore, so you may want to add the Scriptics Web server to your own configuration:

allow http://www.tcl.tk:80/plugin/javascript/*

You can use a combination of allow and disallow rules in a section. The arguments to allow and disallow are URL string match patterns, and they are processed in order. For example, you could put a liberal allow rule followed by disallow rules that restrict access, or vice versa. It is probably safest to explicitly list each server that you trust.

Policy Configuration Files

Each security policy has a configuration file associated with it. For example, the outside policy uses the file outside.cfg file in the config directory. This file specifies what hosts and ports are accessible to Tclets using the outside policy. For the inside and outside policies, the configuration files are similar in spirit to the safesock array used to configure the Safesock security policy shown on page 302. There are a set of allowed hosts and ports, and a set of excluded hosts. The excluded hosts are an exception list. If a host matches the included set but also matches the excluded set, it is not accessible. There is an included and excluded set for URLs that affect browser::geturl. The settings from the Tempfile policy shown on page 304 are also part of the home, inside, and outside configuration files. The configuration files are well commented, and you should read through them to learn about the configuration options for each security policy.

Security Policy Features

The aliases that make up a security policy are organized into sets called features. The features are listed in the main config/plugin.cfg configuration file:

variable featuresList {url stream network persist unsafe}

In turn, each security policy configuration file lists what features are part of the policy. For example, the config/home.cfg file lists these features:

section features
    allow url
    allow network
    allow persist unless {[string match {UNKNOWN *} 
        [getattr originURL]]}

Each feature is implemented in a file in the safetcl directory of the distribution. For example, the url feature is implemented in safetcl/url.tcl. The code in these files follows some conventions in order to work with the configuration mechanism. Each one is implemented inside a namespace that is a child of the safefeature namespace (e.g., safefeature::url). It must implement an install procedure that is called to initialize the feature for a new Tclet. It is inside this procedure that the various allow/disallow rules are checked. The cfg::allowed command supports the rule language used in the .cfg files.

Creating New Security Policies

This book does not describe the details of the configuration language or the steps necessary to create a new security policy. There are several manual pages distributed with the plugin that explain these details. They can be found on the Web at:

If you are serious about tuning the existing security policies or creating new ones, you should read the existing feature implementations in detail. As usual, modifying a working example is the best way to proceed! I think it is a very nice property of the plugin that its security policies are implemented in Tcl source code that is clearly factored out from the rest of the Tcl/Tk and plugin implementation. With a relatively small amount of code, you can create custom security policies that grant interesting abilities to Tclets.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.12.240