Using trusted functions

Learn about security features in Acrobat JavaScript.

By Thom Parker – August 7, 2008

 

Level: Intermediate
Scope: Acrobat 7 and Later
Prerequisites: Familiarity with Acrobat and Acrobat JavaScript

Since the time that scripting was added to Acrobat and PDF, security has been an issue of concern. With the growing ubiquity of the Internet, things are getting worse all the time. Spam is all-pervasive, and it seems that every day hackers come up with new ways to invade our computers. Fortunately, Acrobat JavaScript has always been a sandboxed environment where local-file-system access is heavily controlled, and certain types of potentially dangerous operations are restricted to a reasonably safe context. But even with these restrictions, this early system was loose and somewhat ad hoc. And it also presents a problem. There are situations where it is necessary and appropriate to perform some of these potentially dangerous operations. How do we deal with these situations?

In Acrobat 7, Adobe formalized Acrobat security for JavaScript with the concept of “Privilege,” and introduced the “Trusted Function” as a way of creating privilege.

What’s privilege?

All operations in Acrobat JavaScript are divided into two categories - privileged and non-privileged. For example, the standard operations used on forms are non-privileged, such as calculations, hiding and showing fields, resetting a form and submitting a form. These are all standard, benign operations. However, something like accessing the Identity Object is privileged. The Identity Object contains the user’s name, e-mail and other proprietary information. This is not information you would want just any script to be able to access.

Any object, function or property in the Acrobat JavaScript Reference marked as privileged is potentially dangerous and can only be run from a privileged context. All entries in the Acrobat JavaScript Reference have a “Quick Bar” (or “Rights Bar” depending on the version of the documentation) at the top of the entry. The Quick Bar for the Identity Object is shown below.

The red “S” in the third column indicates this object can only be accessed from a Privileged Context, and there is a
note that explains this more explicitly. If the third column of Rights Bar is empty, then the object, function or property is considered safe and can be run from any context in Acrobat or PDF.

Whether or not a particular JavaScript object, function or property is privileged is determined solely by Adobe. They have a security team that works night and day to figure out where security holes exist and plug them.

What’s a privileged context?

Within Acrobat and PDF, there are many different locations where scripts can be used. Some of these locations are on the user’s system and some are inside a PDF. Supposedly, if a script is on the user’s system, then they know about it. The only way it could have been placed on the user’s system is by someone who has physical access to the system. So, these scripts are considered a privileged context. These privileged locations include Folder Level scripts, Batch Scripts and the JavaScript Console Window.

Conversely, scripts in a PDF could come from anywhere. Without a special mechanism, such as digital certificates, it’s impossible to know the true origin of a PDF. So scripts in a PDF are not to be trusted. All scripting locations inside a PDF, such as form fields, are considered non-privileged. Of course, there’s an exception. If a PDF has been certified and the digital certificate is on the user’s system, and the certificate has been validated against the PDF, then the scripting locations in the PDF can be considered privileged. But this is a rare exception. As a general rule, all scripts inside a PDF are restricted to benign, non-privileged operations.

There are times, particularly in automation scripting, where it is necessary to run a privileged operation from a non-privileged context. To get over this hump, Adobe created the Trusted Function.

What’s a trusted function?

The trusted function is most useful for automation scripting. Automation scripts are usually created with what are called Folder Level Script files. These JavaScript files are placed in a special Acrobat folder on the user’s system. They are loaded and run when Acrobat starts up, and only when Acrobat starts up.

The general idea is that an automation script sets up variables, data and functions that will be used at a later time for some special automation task. Usually, the script will also set up some kind of user interface item, such as a toolbar button or menu item to run the script that uses the functions, variables and data that were created by the Folder Level script.

The issue here is that while the Folder Level script is privileged (because it’s on the user’s system), the functions, variables and data created with the Folder Level script are not privileged. Say, for example, I want to create a toolbar button that when pressed replaces the last page of a PDF. To do that, I create a Folder Level JavaScript file and in it I place code for an ordinary function that replaces the PDF page and code for creating a toolbar button that calls the function for replacing the page.

Unfortunately, this won’t work. The JavaScript command for replacing a page is privileged and the ordinary function created in the folder-level script is non-privileged. To handle this dilemma, I have to make the ordinary function a trusted function using app.trustedFunction(), as shown below.

// Page Replacement Function
var ReplaceLastPage = app.trustedFunction( function(cPath) {
	app.beginPriv();
	this.replacePages(this.numPages-1, cPath); app.endPriv();
});

Let’s examine how this code works. The app.trustedFunction()has a single input that is an ordinary function. The code above uses an unnamed function that’s defined inline. This is just a convenient way to set up a trusted function. The ordinary function could have been defined somewhere else as a named function and then passed into app.trustedFunction() using the function’s name. The return value from app.trustedFunction() is exactly the same function that was passed in, but now that function has privilege and can be called from any execution context, even a script inside a PDF.

Trusted functions cannot be created just anywhere. They can only be created within a privileged context. But once created, they can be used anywhere. In the example above, the replace function is created in a Folder Level script, which is privileged when it is loaded and run at startup by Acrobat.

There is one last part to creating a trusted function. Notice the app.beginPriv() and app.endPriv() lines of code. These lines bracket the parts of the function that need to be privileged. They must be present for code to be privileged.

That’s really all there is to creating a trusted function. The most important parts are that it has to be done from an already privileged context, and the privileged parts inside the function must be bracketed with the app.beginPriv() and app.endPriv() functions.

You can find more information on privilege, the trusted function and all the various Acrobat JavaScript features used in this article in the Acrobat JavaScript Guide and Acrobat JavaScript Reference at the link below. Look under the “Documentation” tab.
https://www.adobe.com/devnet/acrobat.html



Related topics:

JavaScript

Top Searches:


0 comments

Comments for this tutorial are now closed.

Comments for this tutorial are now closed.