0

I want to show a warning if a file is read that is not owned by the user that started the JVM.

In my application, this file can make the program write arbitrary files. So I want to reduce the risk of a privilege escalation attack, if an admin processes this file.

Files.getOwner(path)

retruns a UserPrincipal that represents the file owner. But I can't find a platform independent way to check if this UserPrincipal matches the current user.

I could use

System.getProperty("user.name")

to get the current user and try to match the names. But these properties can be manipulated and this doesn't work if the file owner is a group, for example.

Basic7x7
  • 31
  • 5
  • I'd expect the OS already blocks users from accessing files they shouldn't. That should extend to files read/written by a JVM started by that user. – Jorn Mar 20 '23 at 16:03
  • @Jorn The problem is not that the file is written by an admin and the user can't read it. The opposite is the case. A user wrote a malicious file and the admin processes it. – Basic7x7 Mar 20 '23 at 16:14

2 Answers2

1

If you can reliably tell the owner of a file but not the owner of the process we could combine those two: create a temporary file, get the owner and remove the file again.

File tempFile = File.createTempFile("MyAppName-", ".tmp");
UserPrincipal u = Files.getOwner(tempFile.toPath());
tempFile.deleteOnExit();
tempFile.delete();

// UserPrincipal u will contain the current process user.
Queeg
  • 7,748
  • 1
  • 16
  • 42
  • Tested this and it seems to work fine on Linux and Windows. The trick does not work if the temporary directory is mounted to a device that doesn't support file ownership, but the target file is on another device and has an owner. For example, NTFS returns always the root user on Linux. But these edge cases are not that important for my use case, so I think I will use this trick. – Basic7x7 Mar 27 '23 at 15:52
0

If you already have a principal of the file owner, the question would remain how to reliably get the current user running the application.

Maybe this solution can help? However it seems to make use of Sprint security: https://www.javaguides.net/2019/06/spring-security-get-current-logged-in-user-details.html

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetails = (UserDetails) authentication.getPrincipal();

// getUsername() - Returns the username used to authenticate the user.
System.out.println("User name: " + userDetails.getUsername());

// getAuthorities() - Returns the authorities granted to the user.
System.out.println("User has authorities: " + userDetails.getAuthorities());
Queeg
  • 7,748
  • 1
  • 16
  • 42