Java File Permissions – Don’t Check Permissions before Use

Last modified on May 25th, 2015 by Joe.

This tutorial is part of Java NIO tutorial series. In this tutorial, let us get introduced to Files class from java.nio.file package, it offers static methods to operate on files and directories. Let us start our Java files tutorial with permissions. How to check a file if it has a certain permission before operating on it. Like check if a file has a read permission before reading it or a directory has a write permission before writing on it. Before going into how to check permissions, lets think about should we really do it? Or is this the right approach? My opinion is no, we should not check before we use it. Are you aware of TOCTTOU (pronounced ‘Tock too’).

joker

TOCTTOU is short form for “Time to Check to Time of Use”. We do a permission check and then based on result we perform operation on the respective object. What will happen if the permission is changed in between? This might lead to security holes as our logic is based on this race condition. A possible solution to this scenario is to design our application logic to directly perform the action and if it is allowed let the operation complete and if not let us have a fallback. So eventually going to exception handling mechanism based programming.

Is Readable, Hidden, Writable, Executable?

Now let us learn about how to check file permissions. Be aware of TOCTTOU and use the below accordingly. I suggest an alternate approach below instead of checking for permissions and acting based on it.

package com.javapapers.java.nio;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FilePermissionNIO {
	public static void main(String args[]) {

		Path file = Paths.get("C:\\Users\\Cycle\\Desktop\\a.html");

		boolean isRegularFile = Files.isRegularFile(file);
		boolean isHidden = Files.isReadable(file);
		boolean isReadable = Files.isReadable(file);
		boolean isExecutable = Files.isExecutable(file);
		boolean isSymbolicLink = Files.isSymbolicLink(file);

		Path directory = Paths.get("C:\\Users\\Cycle\\Desktop");
		boolean isDirectory = Files.isDirectory(directory);
		boolean isWritable = Files.isWritable(directory);

	}

}

Nice thing about these methods by default can identify symbolic links and trace to the real file and check for permission. It provides argument if it is not required to do so.

Exceptions Thrown

These methods are actually convenience methods. This delegates to some other APIs and eventually to native file system calls. AccessDeniedException is checked exception and a type of IOException. It is thrown when a file system operation is denied due to insufficient permissions. AccessControlException is a RuntimeException and it is thrown by the SecurityManager when a security policy is restricting the required operation on the file.

		Path file = Paths.get("C:\\Users\\Cycle\\Desktop\\a.txt");
		Files.delete(file);

Delete a file using the above line of code and then change the permission to read-only. Now try to delete the file and you will get the following exception on a Windows operating system and this is dependent on the native calls.

Exception in thread "main" java.nio.file.AccessDeniedException: C:\Users\Cycle\Desktop\a.txt
	at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
	at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
	at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
	at java.nio.file.Files.delete(Files.java:1126)
	at com.javapapers.java.nio.FilePermissionNIO.main(FilePermissionNIO.java:24)

Operation based on File Permissions

People have different opinions on this. I strongly believe we should follow “strategy-B” to design our programs when encountering file permission based decision scenarios. Generally exception handling mechanism is not to be used for decision making or branching but this scenario is different.

package com.javapapers.java.nio;

import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FilePermissionNIO {
	public static void main(String args[]) throws IOException {

		Path file = Paths.get("C:\\Users\\Cycle\\Desktop\\a.txt");
		String userMessage = "";
		
		userMessage = strategyA(file);
		System.out.println("Strategy A: " + userMessage);

		userMessage = strategyB(file);
		System.out.println("Strategy B: " + userMessage);
	}

	public static String strategyA(Path file) throws IOException {
		String userMessage = "";
		boolean isWritable = Files.isWritable(file);
		if (isWritable) {
			Files.delete(file);
			userMessage = "Deleted Successfully!";
		} else {
			userMessage = "File is not writable.";
		}
		return userMessage;
	}

	public static String strategyB(Path file) throws IOException {
		String userMessage = "";
		try {
			// do not check for permission
			// just go ahead and delete
			// if denied, act based on it
			Files.delete(file);
			userMessage = "Deleted Successfully!";
		} catch (AccessDeniedException ade) {
			ade.printStackTrace();
			userMessage = ade.getMessage() + " File is not writable.";
		}
		return userMessage;
	}
}

Please share your opinion as comments for this tutorial as it will really help.

Comments on "Java File Permissions – Don’t Check Permissions before Use"

  1. Anders says:

    Please avoid using implementation dependent device and dudirectory separators. This examples doesn’t work in Unix, OSX or Linux. And it doesn’t need to be that.

    And yes, I do agree with you.
    It is normal to have the needed access to files your program work with. If not, that is an exception that is needed to be handle…

  2. Pushparaj S says:

    Hi Joe…

    Very nice article. Keep going.

    Regards

    Pushparaj S

  3. Vishwam says:

    Hi Joe,
    Good article. Will be waiting to read more articles from you.

    Regards
    Vishwam

  4. Anuj says:

    Hi Joe, Article is nice. I have two question.

    1. I am still not clear strategy B is exception and should be handled for file system only.
    2. Jor and Anders, why this example will not work for Unix, OSX and Linux. What should be in this case ?

  5. Mohammad says:

    Hi , joe Very nice article. Keep going.

  6. Shahid Khan says:

    Very nice looking for more such article

  7. Arjun Gole says:

    Hi, Joe this is very nice article on java.nio but i want know how do achieve this when doing operations on file using java.io

  8. Pratik says:

    Nice approach to code for such situations ,thanks joe

  9. Dzung Tran says:

    Hi Joe,
    Best thank for your article, Very nice. I really like it.
    But When I read it, I try to find somethings which is not good point when we use strategy-B. In my opinion It will be better when we know good point and not good point of 1 solution, and we will know correctly when we can use it.

    What do you think about the performance of strategy-B ? The time to throw 1 exception maybe need more than check isWritable.
    Is it good if we have a lot of locals try to detele 1 file at the same time ? and only 1 local can delete it, other local maybe got FileNotFoundException not AccessDeniedException.

    Finally, best thanks for your posts. I really like your website.

    Regards, Dzung

  10. […] File Permissions […]

  11. Lalit kumar says:

    Thanks for giving such a information, can you tell me something more about Java NIO..?

Comments are closed for "Java File Permissions – Don’t Check Permissions before Use".