Supplemental Material: doPrivileged()

Privileged access was added to the Security objective for Oracle’s Java 11 1Z0-819 Exam, but was not part of the objectives for the now retired 1Z0-816 Exam. We created this Supplemental Material and are releasing it free of charge for all those readers who purchased one of our Java 11 Study Guides. You should read this section carefully before taking the 1Z0-819 Exam. See other changes on The 1Z0-819 Exam page.

Overview

Some Java programs run in an environment where the user does not have full control over the program. In other words, the program runs a privileged action on behalf of the user. The idea for the developer is straight-forward:

  • I have a privileged action I need run for a user
  • I need to verify the user has the proper permission before running the action
  • I need to make sure they are limited in what actions they can run
  • I need to make sure they don’t using caching or other tricks to skip the permission check

Java performs a privileged action using the AccessController.doPrivileged() method found in the java.security package. While using this method is not commonly used by most Java developers, it is required knowledge for the 1Z0-819 Exam.

1. The doPrivileged() method

A common example Oracle likes to use is reading a system property. The idea is that the programmer is only allowed to read a specific predefined system property.

import java.security.*;
public class MySecretReader {
   private static final String KEY = "secret.option";
   public String getSecret() {
      return AccessController.doPrivileged(
         new PrivilegedAction<String>() {
            public String run() {
               return System.getProperty(KEY);
            }
         });
   }
}

Here KEY is a constant that cannot be changed by the user. The idea here is that a user’s privilege is temporarily elevated so they can read the secret.option value within the system.

2. Ensure Principle of Least Privilege

When executing a privileged action, it is important to ensure that only the minimum access is granted. This is known as the principle of least privilege. Can you spot what’s wrong with the following example?

import java.security.*;
public class MySecretReader {
   public String getSecret(String magicWord) {
      return AccessController.doPrivileged(
         new PrivilegedAction<String>() {
            public String run() {
               return System.getProperty(magicWord);  // DON'T DO THIS!
            }
         });
   }
}

In this example, the caller is able to specify which value they want to read. This is considered a poor practice as it allows them to read any property within the system. Oracle refers this as a tainted input. Put simply, don’t trust anything the user provides when dealing with security. Also use a constant or predefined list to confirm they are accessing only what the original developer intended.

For the exam, be wary of any code that allows the user to access data that they specify, rather than the original programmer.

3. Don’t Expose Sensitive Information

Another important aspect of using doPrivileged() is ensuring sensitive data is protected. For example, can you spot the security risk in this code?

import java.security.*;
import java.util.*;
public class MySecretReader {
   private final List<Integer> codes = ...
   public List<Integer> getSecret() {
      return AccessController.doPrivileged(
         new PrivilegedAction<List<Integer>>() {
            public List<Integer> run() {
               return codes;  // DON'T DO THIS!
            }
         });
   }
}

Even though codes is marked final, the content can still be modified after the doPrivileged() is complete. This poses an unacceptable security risk. A much safer version would be to return an immutable copy of the list, such as:

      return AccessController.doPrivileged(
         new PrivilegedAction<List<Integer>>() {
            public List<Integer> run() {
               return Collections.unmodifiableList(codes);
            }
         });

Note that this works because Integer values are immutable. If the contents of the List were mutable, such as List<StringBuilder>, you want to copy them as well.

4. Don’t Elevate Permissions

Privilege elevation or escalation occurs when a user is mistakenly given access to a higher privilege than they should have access to. One way to prevent privilege elevation is to use to the AccessController.checkPermission() method before calling doPrivileged(), then execute the command with limited permissions.

import java.security.*;
public class MySecretReader {
   public void readData(Runnable task, String path) {
      // Check permission
      Permission permission = new java.io.FilePermission(path,"read");
      AccessController.checkPermission(permission);

      // Execute task with limited permission
      final var permissions = permission.newPermissionCollection();
      permissions.add(permission);
      AccessController.doPrivileged(
         new PrivilegedAction<Void>() {
            public Void run() {
               task.run();
               return null;
            }
         },
         // Using a limited context prevents privilege elevation
         new AccessControlContext(
            new ProtectionDomain[] {
               new ProtectionDomain(null, permissions)
            })
         );
   }
}

Don’t worry if you can’t write code like this, most developers never have to. For the exam, though, you should understand that the permission is being checked and the action is executed with a specific context.

5. Be wary of Permission Caching

The last rule you need to know for the exam is to be weary of cached permissions. It is perfectly acceptable to cache permission information, but the permission needs to be checked every time the user accesses it.

For example, assuming there’s a User class with appropriate attributes, methods and constructors, can you spot the problem in this code?

import java.security.*;
import java.util.*;
public class SecretFile {
   private static Map<String, User> data = new HashMap<>();
   public static SecretFile get(String key) {
      var cacheRecord = data.get(key);
      if (cacheRecord != null) {
         // DON'T DO THIS!
         return cacheRecord.getValue();
      }
      
      final var permission = Permission permission 
         = new PropertyPermission(key,"read");
      AccessController.checkPermission(permission);

      final var permissions = permission.newPermissionCollection();
      permissions.add(permission);
      var secret = AccessController.doPrivileged(
         new PrivilegedAction<SecretFile>() {
            public SecretFile run() {
               return new SecretFile();
            }
         }, new AccessControlContext(new ProtectionDomain[] {
               new ProtectionDomain(null, permissions) }));
      data.put(key, new User(secret, permission));
      return secret;
   }
}

Did you spot it? It might be hard to see, but there’s no permission check when the data is read from the cache! The permission is checked when the data is first read from the cache but not on subsequent calls. We can easily fix this though by checking the permission when it is read from the cache:

      var cacheRecord = data.get(key);
      if (cacheRecord != null) {
         AccessController.checkPermission(cacheRecord.getPermission());
         return cacheRecord.getValue();
      }

In this example, we see that cached permissions can be safe to use but we have to make sure the permission is validated when it is read the first time and on each request from the cache.

Conclusion

There, you’re done! This post covered the overall topics around Privileged Access that you need to know for the 1Z0-819 Exam. The following bullet points summarize the kinds of things you should be watching for on the 1Z0-819 Exam:

  • Always validate user input and never allow it to grant access to arbitrary data
  • Never give the user unlimited access to the system
  • Prevent privilege elevation by validating security
  • Never return privileged objects directly or in a way that they can be modified
  • Ensure cached permissions are validated on every call

If you enjoyed this section, you can read more about it in Oracle’s Secure Coding Guidelines for Java SE document.

studying for and taking an exam during a pandemic

Update (11/05/2020): Read The 1Z0-819 Exam page to learn how you can easily our Java 11 Study Guides to prepare for Oracle’s 1Z0-819 Exam, as well as the 1Z0-817 Upgrade Exam.

In the past two weeks, I’ve taken two certification exams: The AWS Associate Architect and the Java 11 819 exam. Taking a certification exam during a pandemic was not a good idea for me. I didn’t realize that until a few days before the first of the two exams.

It’s easy to read about how people are using all they time they have during lockdown/pandemic to accomplish things. In May, I talked to someone who got two AWS certs and talked about wonderful it was to have so much extra time to study. By contrast, this is how I was doing in May.

I’m posting this about my experiences with the certs because it is ok to not be normal right now. Some people are going to be able to study in these times (if that’s you, buy my Java 11 certification book!) But if that’s not you, it is ok. You aren’t alone.

Why I took the two exams

Work set a goal for me to take the AWS Professional Architect exam. We then downgraded it to the AWS Associate Architect exam. (you need the knowledge of the associate architect on the professional).

For the Oracle Java 11, 1Z0-819, I wanted to make sure the existing book Scott and I wrote was appropriate to study for the restructured exam. (It is). Which meant taking it as close to when it came out as possible.

Timing and needing to pass

This was unfortunate timing. When I took the AWS Practitioner and AWS Associate Developer, I didn’t know if I would pass on the first shot. But I figured that i’d rather pay out of pocket for a second attempt (knowing what to study the second time) than overstudy the first time around. However, a re-take would have been after the Java exam. Which meant I had no hope of remembering the AWS stuff for a retake. So the “one and done” approach was far less than ideal. (My employer didn’t pressure me about passing during pandemic. But I didn’t want to go through all of that only to have to take it again)

I’m already Java 11 certified. So it didn’t matter what score I got. Still, it’d be embarrassing to fail an exam that I author a book about!

How studying went

As I wrote in my AWS blog post,

While things have been better since Memorial Day, I don’t know if I’d all them good. One of the problems I have with working from home full time during pandemic is remembering stuff. I remember things spatially. And apparently, I can only remember so much that happens in the same place in a day. So during the week, work “takes” all of that. So I’ve found it incredibly difficult to retain anything and had to learn the same things over and over and over…

This was a major impediment to studying for the AWS exam. It wasn’t for the Java exam, because I already know most of that material. (There are some things I have to “re-learn” for each attempt at an exam though because I don’t have them memorized.) Also, I didn’t fully study for the Java exam because of lack of time and because I’d rather do worse than go through that again.

Mock exams are an important part of studying for a certification exam. I wrote for the AWS exam

I also got frustrated during (practically) every mock exam when I couldn’t remember stuff I knew I “should” be able to. This gave my brain the opportunity to freak about about all the other stuff I’m worried about (going back to a coronavirus winter and the like)

I didn’t get frustrated for the Java ones because I knew what was going on. Also, while I was having trouble concentrating, I knew it didn’t matter. That said, I wasted a bunch of time trying. I just kept making the same mistakes over and over.

It’s funny because I always study with the mock tests at home. But I’m home far less overall. The concentration energy I have is going to other things (like my actual job). Whereas normally, I “get home” and am in a different mental space.

How taking the test went

While I was able to concentrate in the AWS testing center far better then at home, I still had a problem. I couldn’t recall stuff “I learned” at home. So I got frustrated because the problems from home felt like they were following me. This is something I’ll have to be careful with when we finally do go back to the office. I’m sure I’m accumulating all sorts of “mental debt” with things that I’m not learning as well as “normally.” But at least then it won’t be an open ended stretch of time ahead of me.

For the Java test, I was fine at the testing center. I was able to recall stuff far better than I did at home. Including stuff I didn’t study.

My score

On the AWS exam, I got a 760 (passing is 720). On the Java one, I got 72% (passing is 68%.) Both of these are lower than what I normally get on cert tests. But a pass, is a pass :).

(I found a couple of errors on the Java test. They might still be shaking it out.)

Why I think it was so difficult

First of all, I don’t do the lion share of studying for a certification exam from home under normal conditions. I study on the subway. I make “cheat sheets” of things I need to memorize and leave them in different spots (my desk at work, a paper to carry around the robotics lab, etc.) This allows me to “anchor” things I learn to specific spots.

Second, it’s been hard enough to do my job from home all the time. Learning/remembering more things from home on top of that is not helpful.

Third, I keep comparing how I’m doing to “normal.” I like to push myself as I can (at times). I like to feel productive by knowing I accomplished so much. Things aren’t normal. And I have trouble convincing myself that shouldn’t be the baseline. So when I did worse than normal, it was like a frequent reminder of this.

In Conclusion

I don’t want to take another certification exam until things are far closer to normal. In particular, I want my work stuff out of the middle of my apartment, not to be “using up” my finite ability to retain things from home on work and to have a commute again.

Don’t Panic: Oracle announces new Java OCP 11 Exam!

Update (11/05/2020): Read The 1Z0-819 Exam page to learn how you can easily our Java 11 Study Guides to prepare for Oracle’s 1Z0-819 Exam, as well as the 1Z0-817 Upgrade Exam.

Oracle has announced a new Java SE 11 Developer 1Z0-819 exam. In doing so, they are also retiring the 1Z0-815 and 1Z0-816 exams, effective October 1st, 2020. Don’t panic! The new exam is basically a combined version of the 1Z0-815 and 1Z0-816 exams.

In fact, Jeanne and I worked with Oracle staff to help design the objective set for the new 1Z0-819 exam. For example, we’re responsible for removing CallableStatement‘s and assertions. You’re welcome!

This means our existing study guides are perfectly suited to help you pass this new exam. We recommend studying for the new exam with one of the following two options:

Is the new exam easier?

Not really. The new 1Z0-819 exam covers a broad range of material. And you have to know it all on the same day instead of split across two different exams.

What are the benefits of the new 1Z0-819 exam?

To begin with, it costs less. One exam instead of two. Additionally, there are less questions.

The breadth of material does have an advantage: if you don’t do well on one topic, it is likely to be less points on the exam.That said, you only have 90 minutes on the new exam, as opposed to 180 minutes on the old exams, but you have less questions to answer.

What about the Upgrade Exam?

Oracle is keeping the Upgrade OCP Java 11 1Z0-817 exam. Like the new 1Z0-819 exam, our Complete Study Guide can be used for the upgrade exam. You also just use the Programmer II book, as we added an Upgrade Appendix just for this exam.

What don’t I need to study?

You need to know almost everything that was on the 1Z0-815 and 1Z0-816 exams for the 1Z0-819 exam. There are a few topics that you no longer need to worry about for the exam:

  • Characteristics of Java (platform independence, backwards compatibility, etc)
  • Running a basic program from the command line (except modules)
  • Java Assertions
  • JDBC CallableStatement

How do the new objectives map to our Java 11 Study guides?

We created a helpful mapping so you know what to study for the new exam.

1Z0-819 ObjectivesProgrammer I (1Z0-815) ChapterProgrammer II (1Z0-816) ChapterComplete Study Guide Chapter
Working with Java data types3 – Operators
4 – Making Decisions
5 – Core Java APIs
6 – Lambdas and Functional Interfaces
1 – Java Fundamentals3 – Operators
4 – Making Decisions
5 – Core Java APIs
6 – Lambdas and Functional Interfaces
12 – Java Fundamentals
Controlling Program Flow4 – Making Decisions4 – Making Decisions
Java Object-Oriented Approach2 – Java Building Blocks
7 – Methods and Encapsulation
8 – Class Design
9 – Advanced Class Design
1 – Java Fundamentals2 – Java Building Blocks
7 – Methods and Encapsulation
8 – Class Design
9 – Advanced Class Design
12 – Java Fundamentals
Exception Handling10 – Exceptions5 – Exceptions, Assertions, and Localization10 – Exceptions
16 – Exceptions, Assertions, and Localization
Working with Arrays and Collections5 – Core Java APIs3 – Generics and Collections5 – Core Java APIs
14 – Generics and Collections
Working with Streams and Lambda expressions6 – Lambdas and Functional Interfaces4 – Functional Programming
7 – Concurrency
6 – Lambdas and Functional Interfaces
15 – Functional Programming
18 – Concurrency
Java Platform Module System11 – Modules6 – Modular Applications11 – Modules
17 – Modular Applications
Concurrency7 – Concurrency18 – Concurrency
Java I/O API8 – I/O
9 – NIO.2
19 – I/O
20 – NIO.2
Secure Coding in Java SE Application11 – Security22 – Security
Database Applications with JDBC10 – JDBC21 – JDBC
Localization5 – Exceptions, Assertions, and Localization16 – Exceptions, Assertions, and Localization
Annotations2 – Annotations13 – Annotations