Home > Articles > Programming > Java

  • Print
  • + Share This
This chapter is from the book

Security Managers and Permissions

Once a class has been loaded into the virtual machine and checked by the verifier, the second security mechanism of the Java platform springs into action: the security manager. The security manager is a class that controls whether a specific operation is permitted. Operations checked by the security manager include the following:

  • Creating a new class loader
  • Exiting the virtual machine
  • Accessing a field of another class by using reflection
  • Accessing a file
  • Opening a socket connection
  • Starting a print job
  • Accessing the system clipboard
  • Accessing the AWT event queue
  • Bringing up a top-level window

There are many other checks such as these throughout the Java library.

The default behavior when running Java applications is that no security manager is installed, so all these operations are permitted. The applet viewer, on the other hand, enforces a security policy that is quite restrictive.

For example, applets are not allowed to exit the virtual machine. If they try calling the exit method, then a security exception is thrown. Here is what happens in detail. The exit method of the Runtime class calls the checkExit method of the security manager. Here is the entire code of the exit method:

public void exit(int status)
{
  SecurityManager security = System.getSecurityManager();
  if (security != null)
      security.checkExit(status);
  exitInternal(status);
}

The security manager now checks if the exit request came from the browser or an individual applet. If the security manager agrees with the exit request, then the checkExit method simply returns and normal processing continues. However, if the security manager doesn't want to grant the request, the checkExit method throws a SecurityException.

The exit method continues only if no exception occurred. It then calls the private native exitInternal method that actually terminates the virtual machine. There is no other way of terminating the virtual machine, and because the exitInternal method is private, it cannot be called from any other class. Thus, any code that attempts to exit the virtual machine must go through the exit method and thus through the checkExit security check without triggering a security exception.

Clearly, the integrity of the security policy depends on careful coding. The providers of system services in the standard library must always consult the security manager before attempting any sensitive operation.

The security manager of the Java platform allows both programmers and system administrators fine-grained control over individual security permissions. We describe these features in the following section. First, we summarize the Java 2 platform security model. We then show how you can control permissions with policy files. Finally, we explain how you can define your own permission types.

Java Platform Security

JDK 1.0 had a very simple security model: Local classes had full permissions, and remote classes were confined to the sandbox. Just like a child that can only play in a sandbox, remote code was only allowed to paint on the screen and interact with the user. The applet security manager denied all access to local resources. JDK 1.1 implemented a slight modification: Remote code that was signed by a trusted entity was granted the same permissions as local classes. However, both versions of the JDK provided an all-or-nothing approach. Programs either had full access or they had to play in the sandbox.

Starting with Java SE 1.2, the Java platform has a much more flexible mechanism. A security policy maps code sources to permission sets (see Figure 9-6).

Figure 9-6

Figure 9-6 A security policy

A code source is specified by a code base and a set of certificates. The code base specifies the origin of the code. For example, the code base of remote applet code is the HTTP URL from which the applet is loaded. The code base of code in a JAR file is a file URL. A certificate, if present, is an assurance by some party that the code has not been tampered with. We cover certificates later in this chapter.

A permission is any property that is checked by a security manager. The Java platform supports a number of permission classes, each of which encapsulates the details of a particular permission. For example, the following instance of the FilePermission class states that it is okay to read and write any file in the /tmp directory.

FilePermission p = new FilePermission("/tmp/*", "read,write");

More important, the default implementation of the Policy class reads permissions from a permission file. Inside a permission file, the same read permission is expressed as

permission java.io.FilePermission "/tmp/*", "read,write";

We discuss permission files in the next section.

Figure 9-7 shows the hierarchy of the permission classes that were supplied with Java SE 1.2. Many more permission classes have been added in subsequent Java releases.

Figure 9-7

Figure 9-7 A part of the hierarchy of permission classes

In the preceding section, you saw that the SecurityManager class has security check methods such as checkExit. These methods exist only for the convenience of the programmer and for backward compatibility. They all map into standard permission checks. For example, here is the source code for the checkExit method:

public void checkExit()
{
   checkPermission(new RuntimePermission("exitVM"));
}

Each class has a protection domain, an object that encapsulates both the code source and the collection of permissions of the class. When the SecurityManager needs to check a permission, it looks at the classes of all methods currently on the call stack. It then gets the protection domains of all classes and asks each protection domain if its permission collection allows the operation that is currently being checked. If all domains agree, then the check passes. Otherwise, a SecurityException is thrown.

Why do all methods on the call stack need to allow a particular operation? Let us work through an example. Suppose the init method of an applet wants to open a file. It might call

Reader in = new FileReader(name);

The FileReader constructor calls the FileInputStream constructor, which calls the checkRead method of the security manager, which finally calls checkPermission with a FilePermission(name, "read" object. Table 9-1 shows the call stack.

Table 9-1. Call Stack During Permission Checking

Class

Method

Code Source

Permissions

SecurityManager

checkPermission

null

AllPermission

SecurityManager

checkRead

null

AllPermission

FileInputStream

constructor

null

AllPermission

FileReader

constructor

null

AllPermission

applet

init

applet code source

applet permissions

. . .

The FileInputStream and SecurityManager classes are system classes for which CodeSource is null and permissions consist of an instance of the AllPermission class, which allows all operations. Clearly, their permissions alone can't determine the outcome of the check. As you can see, the checkPermission method must take into account the restricted permissions of the applet class. By checking the entire call stack, the security mechanism ensures that one class can never ask another class to carry out a sensitive operation on its behalf.

  • void checkPermission(Permission p) 1.2

    checks whether this security manager grants the given permission. The method throws a SecurityException if the permission is not granted.

  • ProtectionDomain getProtectionDomain() 1.2

    gets the protection domain for this class, or null if this class was loaded without a protection domain.

  • ProtectionDomain(CodeSource source, PermissionCollection permissions)

    constructs a protection domain with the given code source and permissions.

  • CodeSource getCodeSource()

    gets the code source of this protection domain.

  • boolean implies(Permission p)

    returns true if the given permission is allowed by this protection domain.

  • Certificate[] getCertificates()

    gets the certificate chain for class file signatures associated with this code source.

  • URL getLocation()

    gets the code base of class files associated with this code source.

Security Policy Files

The policy manager reads policy files that contain instructions for mapping code sources to permissions. Here is a typical policy file:

grant codeBase "http://www.horstmann.com/classes"
{
   permission java.io.FilePermission "/tmp/*", "read,write";
};

This file grants permission to read and write files in the /tmp directory to all code that was downloaded from http://www.horstmann.com/classes.

You can install policy files in standard locations. By default, there are two locations:

  • The file java.policy in the Java platform home directory
  • The file .java.policy (notice the period at the beginning of the file name) in the user home directory

During testing, we don't like to constantly modify the standard policy files. Therefore, we prefer to explicitly name the policy file that is required for each application. Place the permissions into a separate file, say, MyApp.policy. To apply the policy, you have two choices. You can set a system property inside your applications' main method:

System.setProperty("java.security.policy", "MyApp.policy");

Alternatively, you can start the virtual machine as

java -Djava.security.policy=MyApp.policy MyApp

For applets, you instead use

appletviewer -J-Djava.security.policy=MyApplet.policy MyApplet.html

(You can use the -J option of the appletviewer to pass any command-line argument to the virtual machine.)

In these examples, the MyApp.policy file is added to the other policies in effect. If you add a second equal sign, such as

java -Djava.security.policy==MyApp.policy MyApp

then your application uses only the specified policy file, and the standard policy files are ignored.

As you saw previously, Java applications by default do not install a security manager. Therefore, you won't see the effect of policy files until you install one. You can, of course, add a line

System.setSecurityManager(new SecurityManager());

into your main method. Or you can add the command-line option -Djava.security.manager when starting the virtual machine.

java -Djava.security.manager -Djava.security.policy=MyApp.policy MyApp

In the remainder of this section, we show you in detail how to describe permissions in the policy file. We describe the entire policy file format, except for code certificates, which we cover later in this chapter.

A policy file contains a sequence of grant entries. Each entry has the following form:

grant codesource
{
   permission1;
   permission2;
   . . .
};

The code source contains a code base (which can be omitted if the entry applies to code from all sources) and the names of trusted principals and certificate signers (which can be omitted if signatures are not required for this entry).

The code base is specified as

codeBase "url"

If the URL ends in a /, then it refers to a directory. Otherwise, it is taken to be the name of a JAR file. For example,

grant codeBase "www.horstmann.com/classes/" { . . . };
grant codeBase "www.horstmann.com/classes/MyApp.jar" { . . . };

The code base is a URL and should always contain forward slashes as file separators, even for file URLs in Windows. For example,

grant codeBase "file:C:/myapps/classes/" { . . . };

The permissions have the following structure:

permission className targetName, actionList;

The class name is the fully qualified class name of the permission class (such as java.io.FilePermission). The target name is a permission-specific value, for example, a file or directory name for the file permission, or a host and port for a socket permission. The actionList is also permission specific. It is a list of actions, such as read or connect, separated by commas. Some permission classes don't need target names and action lists. Table 9-2 lists the commonly used permission classes and their actions.

Table 9-2. Permissions and Their Associated Targets and Actions

Permission

Target

Action

java.io.FilePermission

file target (see text)

read, write, execute, delete

java.net.SocketPermission

socket target (see text)

accept, connect, listen, resolve

java.util.PropertyPermission

property target (see text)

read, write

java.lang.RuntimePermission

createClassLoader
getClassLoader
setContextClassLoader
enableContextClassLoaderOverride
createSecurityManager
setSecurityManager
exitVM
getenv.variableName
shutdownHooks
setFactory
setIO
modifyThread
stopThread
modifyThreadGroup
getProtectionDomain
readFileDescriptor
writeFileDescriptor
loadLibrary.libraryName
accessClassInPackage.packageName
defineClassInPackage.packageName
accessDeclaredMembers.className
queuePrintJob
getStackTrace
setDefaultUncaughtExceptionHandler
preferences
usePolicy

(none)

java.awt.AWTPermission

showWindowWithoutWarningBanner
accessClipboard
accessEventQueue
createRobot
fullScreenExclusive
listenToAllAWTEvents
readDisplayPixels
replaceKeyboardFocusManager
watchMousePointer
setWindowAlwaysOnTop
setAppletStub

(none)

java.net.NetPermission

setDefaultAuthenticator
specifyStreamHandler
requestPasswordAuthentication
setProxySelector
getProxySelector
setCookieHandler
getCookieHandler
setResponseCache
getResponseCache

(none)

java.lang.reflect.ReflectPermission

suppressAccessChecks

(none)

java.io.SerializablePermission

enableSubclassImplementation
enableSubstitution

(none)

java.security.SecurityPermission

createAccessControlContext
getDomainCombiner
getPolicy
setPolicy
getProperty.keyName
setProperty.keyName
insertProvider.providerName
removeProvider.providerName
setSystemScope
setIdentityPublicKey
setIdentityInfo
addIdentityCertificate
removeIdentityCertificate
printIdentity
clearProviderProperties.providerName
putProviderProperty.providerName
removeProviderProperty.providerName
getSignerPrivateKey
setSignerKeyPair

(none)

java.security.AllPermission

(none)

(none)

javax.audio.AudioPermission

play
record

(none)

javax.security.auth.AuthPermission

doAs
doAsPrivileged
getSubject
getSubjectFromDomainCombiner
setReadOnly
modifyPrincipals
modifyPublicCredentials
modifyPrivateCredentials
refreshCredential
destroyCredential
createLoginContext.contextName
getLoginConfiguration
setLoginConfiguration
refreshLoginConfiguration

(none)

java.util.logging.LoggingPermission

control

(none)

java.sql.SQLPermission

setLog

(none)

As you can see from Table 9-2, most permissions simply permit a particular operation. You can think of the operation as the target with an implied action "permit". These permission classes all extend the BasicPermission class (see Figure 9-7 on page 774). However, the targets for the file, socket, and property permissions are more complex, and we need to investigate them in detail.

File permission targets can have the following form:

file

a file

directory/

a directory

directory/*

all files in the directory

*

all files in the current directory

directory/-

all files in the directory or one of its subdirectories

-

all files in the current directory or one of its subdirectories

<<ALL FILES>>

all files in the file system

For example, the following permission entry gives access to all files in the directory /myapp and any of its subdirectories.

permission java.io.FilePermission "/myapp/-", "read,write,delete";

You must use the \\ escape sequence to denote a backslash in a Windows file name.

permission java.io.FilePermission "c:\\myapp\\-", "read,write,delete";

Socket permission targets consist of a host and a port range. Host specifications have the following form:

hostname or IPaddress

a single host

localhost or the empty string

the local host

*.domainSuffix

any host whose domain ends with the given suffix

*

all hosts

Port ranges are optional and have the form:

:n

a single port

:n-

all ports numbered n and above

:-n

all ports numbered n and below

:n1-n2

all ports in the given range

Here is an example:

permission java.net.SocketPermission "*.horstmann.com:8000-8999", "connect";

Finally, property permission targets can have one of two forms:

property

a specific property

propertyPrefix.*

all properties with the given prefix

Examples are "java.home" and "java.vm.*".

For example, the following permission entry allows a program to read all properties that start with java.vm.

permission java.util.PropertyPermission "java.vm.*", "read";

You can use system properties in policy files. The token ${property} is replaced by the property value. For example, ${user.home} is replaced by the home directory of the user. Here is a typical use of this system property in a permission entry.

permission java.io.FilePermission "${user.home}", "read,write";

To create platform-independent policy files, it is a good idea to use the file.separator property instead of explicit / or \\ separators. To make this simpler, the special notation ${/} is a shortcut for ${file.separator}. For example,

permission java.io.FilePermission "${user.home}${/}-", "read,write";

is a portable entry for granting permission to read and write in the user's home directory and any of its subdirectories.

Figure 9-8

Figure 9-8 The policy tool

Custom Permissions

In this section, you see how you can supply your own permission class that users can refer to in their policy files.

To implement your permission class, you extend the Permission class and supply the following methods:

  • A constructor with two String parameters, for the target and the action list
  • String getActions()
  • boolean equals()
  • int hashCode()
  • boolean implies(Permission other)

The last method is the most important. Permissions have an ordering, in which more general permissions imply more specific ones. Consider the file permission

p1 = new FilePermission("/tmp/-", "read, write");

This permission allows reading and writing of any file in the /tmp directory and any of its subdirectories.

This permission implies other, more specific permissions:

p2 = new FilePermission("/tmp/-", "read");
p3 = new FilePermission("/tmp/aFile", "read, write");
p4 = new FilePermission("/tmp/aDirectory/-", "write");

In other words, a file permission p1 implies another file permission p2 if

  1. The target file set of p1 contains the target file set of p2.
  2. The action set of p1 contains the action set of p2.

Consider the following example of the use of the implies method. When the FileInputStream constructor wants to open a file for reading, it checks whether it has permission to do so. For that check, a specific file permission object is passed to the checkPermission method:

checkPermission(new FilePermission(fileName, "read"));

The security manager now asks all applicable permissions whether they imply this permission. If any one of them implies it, then the check passes.

In particular, the AllPermission implies all other permissions.

If you define your own permission classes, then you need to define a suitable notion of implication for your permission objects. Suppose, for example, that you define a TVPermission for a set-top box powered by Java technology. A permission

new TVPermission("Tommy:2-12:1900-2200", "watch,record")

might allow Tommy to watch and record television channels 2–12 between 19:00 and 22:00. You need to implement the implies method so that this permission implies a more specific one, such as

new TVPermission("Tommy:4:2000-2100", "watch")

Implementation of a Permission Class

In the next sample program, we implement a new permission for monitoring the insertion of text into a text area. The program ensures that you cannot add "bad words" such as sex, drugs, and C++ into a text area. We use a custom permission class so that the list of bad words can be supplied in a policy file.

The following subclass of JTextArea asks the security manager whether it is okay to add new text:

class WordCheckTextArea extends JTextArea
{
   public void append(String text)
   {
      WordCheckPermission p = new WordCheckPermission(text, "insert");
      SecurityManager manager = System.getSecurityManager();
      if (manager != null) manager.checkPermission(p);
      super.append(text);
   }
}

If the security manager grants the WordCheckPermission, then the text is appended. Otherwise, the checkPermission method throws an exception.

Word check permissions have two possible actions: insert (the permission to insert a specific text) and avoid (the permission to add any text that avoids certain bad words). You should run this program with the following policy file:

grant
{
   permission WordCheckPermission "sex,drugs,C++", "avoid";
};

This policy file grants the permission to insert any text that avoids the bad words sex, drugs, and C++.

When designing the WordCheckPermission class, we must pay particular attention to the implies method. Here are the rules that control whether permission p1 implies permission p2.

  • If p1 has action avoid and p2 has action insert, then the target of p2 must avoid all words in p1. For example, the permission

    WordCheckPermission "sex,drugs,C++", "avoid"

    implies the permission

    WordCheckPermission "Mary had a little lamb", "insert"
  • If p1 and p2 both have action avoid, then the word set of p2 must contain all words in the word set of p1. For example, the permission

    WordCheckPermission "sex,drugs", "avoid"

    implies the permission

    WordCheckPermission "sex,drugs,C++", "avoid"
  • If p1 and p2 both have action insert, then the text of p1 must contain the text of p2. For example, the permission

    WordCheckPermission "Mary had a little lamb", "insert"

    implies the permission

    WordCheckPermission "a little lamb", "insert"

You can find the implementation of this class in Listing 9-4.

Note that you retrieve the permission target with the confusingly named getName method of the Permission class.

Because permissions are described by a pair of strings in policy files, permission classes need to be prepared to parse these strings. In particular, we use the following method to transform the comma-separated list of bad words of an avoid permission into a genuine Set.

public Set<String> badWordSet()
{
   Set<String> set = new HashSet<String>();
   set.addAll(Arrays.asList(getName().split(",")));
   return set;
}

This code allows us to use the equals and containsAll methods to compare sets. As you saw in Chapter 2, the equals method of a set class finds two sets to be equal if they contain the same elements in any order. For example, the sets resulting from "sex,drugs,C++" and "C++,drugs,sex" are equal.

The program in Listing 9-5 shows how the WordCheckPermission class works. Type any text into the text field and click the Insert button. If the security check passes, the text is appended to the text area. If not, an error message is displayed (see Figure 9-9).

Figure 9-9

Figure 9-9 The PermissionTest program

You have now seen how to configure Java platform security. Most commonly, you will simply tweak the standard permissions. For additional control, you can define custom permissions that can be configured in the same way as the standard permissions.

Listing 9-4. WordCheckPermission.java

 
 1. import java.security.*;
 2. import java.util.*;
 3.
 4. /**
 5.  * A permission that checks for bad words.
 6.  * @version 1.00 1999-10-23
 7.  * @author Cay Horstmann
 8.  */
 9. public class WordCheckPermission extends Permission
10. {
11.    /**
12.     * Constructs a word check permission
13.     * @param target a comma separated word list
14.     * @param anAction "insert" or "avoid"
15.     */
16.    public WordCheckPermission(String target, String anAction)
17.    {
18.       super(target);
19.       action = anAction;
20.    }
21.
22.    public String getActions()
23.    {
24.       return action;
25.    }
26.
27.    public boolean equals(Object other)
28.    {
29.       if (other == null) return false;
30.       if (!getClass().equals(other.getClass())) return false;
31.       WordCheckPermission b = (WordCheckPermission) other;
32.       if (!action.equals(b.action)) return false;
33.       if (action.equals("insert")) return getName().equals(b.getName());
34.       else if (action.equals("avoid")) return badWordSet().equals(b.badWordSet());
35.       else return false;
36.    }
37.
38.    public int hashCode()
39.    {
40.       return getName().hashCode() + action.hashCode();
41.    }
42.
43.    public boolean implies(Permission other)
44.    {
45.       if (!(other instanceof WordCheckPermission)) return false;
46.       WordCheckPermission b = (WordCheckPermission) other;
47.       if (action.equals("insert"))
48.       {
49.          return b.action.equals("insert") && getName().indexOf(b.getName()) >= 0;
50.       }
51.       else if (action.equals("avoid"))
52.       {
53.          if (b.action.equals("avoid")) return b.badWordSet().containsAll(badWordSet());
54.          else if (b.action.equals("insert"))
55.          {
56.             for (String badWord : badWordSet())
57.                if (b.getName().indexOf(badWord) >= 0) return false;
58.             return true;
59.          }
60.          else return false;
61.       }
62.       else return false;
63.    }
64.
65.    /**
66.     * Gets the bad words that this permission rule describes.
67.     * @return a set of the bad words
68.     */
69.    public Set<String> badWordSet()
70.    {
71.       Set<String> set = new HashSet<String>();
72.       set.addAll(Arrays.asList(getName().split(",")));
73.       return set;
74.    }
75.
76.    private String action;
77. }

Listing 9-5. PermissionTest.java

 
 1. import java.awt.*;
 2. import java.awt.event.*;
 3. import javax.swing.*;
 4.
 5. /**
 6.  * This class demonstrates the custom WordCheckPermission.
 7.  * @version 1.03 2007-10-06
 8.  * @author Cay Horstmann
 9.  */
10. public class PermissionTest
11. {
12.    public static void main(String[] args)
13.    {
14.       System.setProperty("java.security.policy", "PermissionTest.policy");
15.       System.setSecurityManager(new SecurityManager());
16.       EventQueue.invokeLater(new Runnable()
17.          {
18.             public void run()
19.             {
20.                JFrame frame = new PermissionTestFrame();
21.                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
22.                frame.setVisible(true);
23.             }
24.          });
25.    }
26. }
27.
28. /**
29.  * This frame contains a text field for inserting words into a text area that is protected
30.  * from "bad words".
31.  */
32. class PermissionTestFrame extends JFrame
33. {
34.    public PermissionTestFrame()
35.    {
36.       setTitle("PermissionTest");
37.       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
38.
39.       textField = new JTextField(20);
40.       JPanel panel = new JPanel();
41.       panel.add(textField);
42.       JButton openButton = new JButton("Insert");
43.       panel.add(openButton);
44.       openButton.addActionListener(new ActionListener()
45.          {
46.             public void actionPerformed(ActionEvent event)
47.             {
48.                insertWords(textField.getText());
49.             }
50.          });
51.
52.       add(panel, BorderLayout.NORTH);
53.
54.       textArea = new WordCheckTextArea();
55.       add(new JScrollPane(textArea), BorderLayout.CENTER);
56.    }
57.
58.    /**
59.     * Tries to insert words into the text area. Displays a dialog if the attempt fails.
60.     * @param words the words to insert
61.     */
62.    public void insertWords(String words)
63.    {
64.       try
65.       {
66.          textArea.append(words + "\n");
67.       }
68.       catch (SecurityException e)
69.       {
70.          JOptionPane.showMessageDialog(this, "I am sorry, but I cannot do that.");
71.       }
72.    }
73.
74.    private JTextField textField;
75.    private WordCheckTextArea textArea;
76.    private static final int DEFAULT_WIDTH = 400;
77.    private static final int DEFAULT_HEIGHT = 300;
78. }
79.
80. /**
81.  * A text area whose append method makes a security check to see that no bad words are added.
82.  */
83. class WordCheckTextArea extends JTextArea
84. {
85.    public void append(String text)
86.    {
87.       WordCheckPermission p = new WordCheckPermission(text, "insert");
88.       SecurityManager manager = System.getSecurityManager();
89.       if (manager != null) manager.checkPermission(p);
90.       super.append(text);
91.    }
92. }
  • Permission(String name)

    constructs a permission with the given target name.

  • String getName()

    returns the target name of this permission.

  • boolean implies(Permission other)

    checks whether this permission implies the other permission. That is the case if the other permission describes a more specific condition that is a consequence of the condition described by this permission.

  • + Share This
  • 🔖 Save To Your Account

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020