As simple as possible, as complex as necessary

Copying Windows file permissions in Lucee

30 June 2021

There is a currently unresolved regression bug in Lucee affecting file uploads, which is worth being aware of.

When you upload a file using Lucee it isn't saved directly to the destination path, but is first stored in the server's GetTempDirectory() location before being moved to where you've specified it should be.

(Update 7 July 2021: Charlie Arehart has a useful explanation of the basic mechanics of file uploading in CFML.)

Having this intermediate step is good for security as it allows the OS to detect viruses before the file is placed anywhere it might do damage.

Inherited permissions

Prior to Lucee, an uploaded file would inherit the destination directory's permissions, as you would expect. But thereafter that stopped happening and the file instead keeps the permissions of the GetTempDirectory() path.

This means, for example, that if you upload an image to a directory with web server read permissions, the new file won't in fact be readable by the web server, unless the GetTempDirectory() path also has that permission.

Security checks

Of course, using a web accessible upload destination isn't good security practice anyway. Alongside the anti-malware detection mentioned above, other safety checks such as IsImageFile() and other MIME type checking should first be performed in code. Again this needs doing in an intermediate location not accessible to the web, after which the file can be moved to its public destination.

So the recommended workflow is:

  1. Upload the file using FileUpload() or equivalent, specifying an intermediate, protected destination path.
  2. Lucee will first save the file to the GetTempDirectory() path and then move it to your destination.
  3. Perform your MIME checks on the file while it's in the intermediate location.
  4. Finally, FileMove() the file to its final destination.

Setting the permissions

But how do you ensure the file has the right permissions for that final location?

I'm not a Linux user, but if you are on that platform Lucee has a built-in function FileSetAccessMode() which I assume will allow you to control file permissions.

Unfortunately there is no Windows equivalent, but if we drop down to java there are tools we can use to achieve what we want fairly easily.

The following UDF can be used with an uploaded file once it's been security checked and moved to its final location to ensure it has the permissions of its parent (containing) directory.

public void function copyParentDirectoryPermissions( required string filePath, required string parentDirectoryPath ){
	//built-in Java classes with required static methods
	var Paths = CreateObject( "java", "java.nio.file.Paths" );
	var Files = CreateObject( "java", "java.nio.file.Files" );
	var aclViewClass = CreateObject( "java", "java.nio.file.attribute.AclFileAttributeView" ).getClass();
	//create "path" java objects to work with
	var parentFolderPath = Paths.get( JavaCast( "string", arguments.parentDirectoryPath ), [] );
	var filePath = Paths.get( JavaCast( "string", arguments.filePath ), [] );
	//create "views" of the respective ACLs
	var parentFolderAclView = Files.getFileAttributeView( parentFolderPath, aclViewClass, [] );
	var fileAclView = Files.getFileAttributeView( filePath, aclViewClass, [] );
	//copy the folder ACL to the file
	fileAclView.setAcl( parentFolderAclView.getAcl() );

View UDF as a Gist

Posted on . Updated


  • Formatting comments: See this list of formatting tags you can use in your comments.
  • Want to paste code? Enclose within <pre><code> tags for syntax higlighting and better formatting and if possible use script. If your code includes "self-closing" tags, such as <cfargument>, you must add an explicit closing tag, otherwise it is likely to be mangled by the Disqus parser.
Back to the top