I know there is getPermissions() method but I don't know how to use it. How can I check using JSch, if user can read files?
First, you should generally ask a functional question (what do you want to achive), to get an useful answer. You ask for an implementation/technical detail, hence my possibly useless technical answer:
SftpATTRS.getPermissions() returns numerical representation of *nix permissions:
https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation
It's on its own NOT enough to determine, if the current user has permissions to read the file. In addition you have to know: who is the owner of the file (the getUId returns owner ID, but there's no API in SFTP to map that to/from username) and what is a group of the file (the getGId, the same).
So you can only be sure that user can read the file, when everyone have permissions to do so. What you can tell by presence of flag 0004 (read permissions for other class). But lack of the flag does not mean user cannot read the file, e.g. in case user is an owner of the file and there's flag 0400 (read permissions for owner class).
Also note that, when the remote system is not *nix (e.g. it's Windows), the getPermissions() value is usually irrelevant anyway.
Non-trivial, but only reliable way, is to dig into JSch source code and extract new API to open file for reading. Then you can just try to open the file (you do not have to read anything actually) to tell, if user has permissions to do so.
In general, there is no point trying to detect, if you have permissions for an operation. Try the operation and see if it succeeds or not.
Related
I'm working on a client that gets a credential from a server and stores it in a file. I'd like to a) make the file readable only by the owner and b) check before subsequent use that the file is readable only by the owner.
This is trivial on Linux. My problem is with Windows.
Should I delete all the ACEs other than the owner's that grant read permission? Or just delete all ACEs other than the owner's?
Or is it sufficient to add "deny" ACEs for the group and "Everyone"?
Or some third way?
I'm aware that a file can have inherited access rights but I'm not sure how to detect that and deauthorize everyone but the owner.
If it's relevant, the application that creates the file is in Java and the application that uses the file is in C++.
Is there any way in Java to write out to a temporary file securely?
As far as I can tell, the only way to create a temporary file (createTempFile) does't actually open it at the same time, so there's a race condition between file open & file write. Am I missing something? I couldn't find the C source code behind createFileExclusively(String) in UnixFileSystem.java, but I doubt it can really do anything since the file open occurs in the Java code after the temp file is created (unless it tries to do something with file locks?).
The problem
Between when the temporary file is created & you open it, a malicious attacker could unlink that temporary file & put malicious stuff there. For example, an attacker could create a named pipe to read sensitive data. Or similarly if you eventually copy the file by reading it, then the named pipe could just ignore everything written & supply malicious content to be read.
I remember reading of numerous examples of temporary file attacks in the past 10+ years that exploit the race condition between when the name appears in the namespace and when the file is actually opened.
Hopefully a mitigating factor is that Java set's the umask correctly so a less-privileged user can't read/write to the file and typically the /tmp directory restricts permissions properly so that you can't perform an unlink attack.
Of course if you pass a custom directory for the temporary file that's owned by a less-privileged user who's compromised, the user could do an unlink attack against you. Hell, with inotify, it's probably even easier to exploit the race condition than just a brute force loop that does a directory listing.
http://kurt.seifried.org/2012/03/14/creating-temporary-files-securely/
Java
use java.io.File.createTempFile() – some interesting info at http://www.veracode.com/blog/2009/01/how-boring-flaws-become-interesting/
for directories there is a helpful posting at How to create a temporary directory/folder in Java?
Java 7
for files use java.io.File.createTempFile()
for directories use createTempDirectory()
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
Since Java 7 we have OpenOption.
An object that configures how to open or create a file.
Objects of this type are used by methods such as newOutputStream, newByteChannel, FileChannel.open, and AsynchronousFileChannel.open when opening or creating a file.
Of particular interest is StandardOpenOptions.CREATE_NEW.
Create a new file, failing if the file already exists. The check for the existence of the file and the creation of the file if it does not exist is atomic with respect to other file system operations.
So, you can do something like this:
FileChannel mkstemp() {
Path path = Files.createTempFile(null, null);
Files.delete(path);
return FileChannel.open(path, WRITE, CREATE_NEW);
}
Implementing the same template behaviour is left as exercise to the reader.
Keep in mind that on many systems, just because a file doesn't have a name doesn't at all mean it's inaccessible. For example, on Linux open file descriptors are available in /proc/<pid>/fd/<fdno>. So you should make sure that your use of temporary files is secure even if someone knows / has a reference to the open file.
You might get a more useful answer if you specify exactly what classes of attacks you are trying to prevent.
Secure against other ordinary userid's? Yes, on any properly functioning multi-user system.
Secure against the your own userid or the superuser? No.
During an installation process I need to check if a userprovided path is writable to a specified user.
The Path (A UNC Path like \fileserver\share) may not be writable to the user, who is executing the Setup.exe (It's a Windows-Only Software), so I think How do you check for permissions to write to a directory or file? may not work for me.
I know in Java7 there will be a new Filesystem-API, but Java7 is not released yet.
EDIT:
User 1 - runs the installer
User 2 - runs the installed application
If user 1 get an error "Permission denied" I still don't know, about user 2. I need to check the permission for an other useraccount during the process of installation.
I may use net use /user:<user2> <passwd2> but I'm not sure, if I get all information I need. I get the information, that the path exists, but not, if User 2 is allowed to write.
before java 7, you don't have standard way to check if a user can write to a java file using standard library. this is because the old java io just is not power enough.
for example, File.canWrite() will not work if consider file owner, etc....
what you can do is check it in directly, for example, try to write a empty line to it. (this need to consider you application,if your application just don't care a blank line at end and auto delete ending blank lines , then it works..... this is just an example, you can get many tricky ways considering your applicaton.
I'm coding a little library which will handle xml files to store some data, and I need this data to be handled only by the methods I provide in my library.
I know that xml is readable for both human and machine, and that if somebody really wants to modify the xml file he'll probably do it, so... do any of you have an idea that could work?
You can store more information in it, such as a hash of the content (before the hash was inserted of course).
When you will reload this file, you can check the hash. If it doesn't match with the current hash of your file, well it has been modified.
Well, there is no definitive way to block access to that file. But you can use several measures to make it hard on manual overriding of the file.
First thing you can do is lock the file (need to ensure OS compatibility) for as long as your application is running. Anyone can circumvent an OS file lock, but it is not trivial for an average user.
Second, you can consider encrypting the file on application termination. Restoring the key can be done from application code inspection, but again - a non-trivial effort.
As you said above, you have already implented a method that detects file changes, and you want a way how to prevent these modifications.
Usally, that's not possible. I'll explain at the end.
You have a few choices what to do:
If you want to prevent modifications while the program is running, you can lock the file. This will prevent applications from accessing it, but when your program exits, the lock will be released. (Example)
If you want to prevent access while the program is not running, you'll have to change file system permissions to forbid the user to edit the file. This is way more difficult as it is filesystem-related, and some filesystems like FAT haven't got file permissions at all.
You could write a "daemon" script that watches for file changes and revert them.
But all these possibilities have one problem - a program usally has the same permissions as the user, so everything the program does can be undone by the user. If your program has access, the user has too.
If you lock a file, the user could use a tool like Unlocker to release the lock, and edit it anyway. If your program sets file permissions, the user can simply change them back. On some systems, it might be possible to prevent this, but then your program looses access too. Bad. If you write a daemon, the user can kill it.
The only possibility is to have the program running with more rights than the user, and store the data on a place where the user has no access too. As example, on Windows, you can run it as a service. This requries the user to not have Administrator rights (or root, on Unix systems).
If the user is admin or root, you've lost, as he has full access to the system and you can't hide. (on Windows, there is one more level, the SYSTEM user, but an admin user can easily get these rights too).
Append a hash of the file concatenated with a secret key to the end of the file. Like an XML comment
<!-- 0123456789abcdefabcdef0123456789 -->
Upon opening the file you hash it again with the appended secret key and verify it.
Some psuedo code to clarify.
# Read
secret = "Secret key"
file = get_file_contents("file.xml")
content = strip_trailing_comment(file)
hash = get_content_hash(file)
if sha1(content + secret) == hash:
# File is valid
# Write
secret = "Secret key"
content = content_to_xml()
hash = sha1(content + secret)
content_with_hash = append_comment(hash)
write_to_file("file.xml", content_with_hash)
Hope that clears up potential misunderstandings. This way the code is still human readable, if you want that, and hard to tamper with.
As I understand from discussions and your question, you want to store the data as xml, and difficult for user to open/modify it.
In that case you will have to do some additional work:
Create the xml file with hash information as suggested by Colin HEBERT
Zip the file with password protection, the password to which only your app will know
There is a question on stackoverflow on how to password protect your zip file
In this approach, mind you, the xml file does not even become readable.
If you want your files to be readable, then you could probably use a seperate user id for your application (unix user id or windows userid) as owner of the files. and only allow that user to modify the files, but still this won't be a 100% solution.
Okay I have a folder say... http://oldserver.net/file/index.jar
How would I be able to protect the file "index.jar" from being downloaded from regular web browsers?
I've seen this done before, I just want to protect it from being accessed from web browsers, and keep it strictly java download access only.
What I mean by java download access only is, I could simply use a java downloader to download index.jar. But I can't download it via web browser.
How would I protect the file "index.jar" ?
Thanks:)
You need to think about what this requirement means specifically - from the point of view of your server, how can it tell whether an incoming request is a "java download" or not?
In short, I don't think there's a way to do exactly what you're after. The classic way to secure resources would be by requiring authentication (i.e. you need a valid username and password to get the index.jar file) but it doesn't sound like that's what you want here.
Bear in mind that Java simply sends HTTP requests (or other protocols that it knows how to speak) down a connection. Any other program could send identical requests, so there's quite simply no way to enforce this limit in the way that you've specified.
One approach that might simulate what you're after is to not have the index.jar accessible via HTTP, so browsers wouldn't be able to get at it by default, and then access it via another protocol in Java (e.g. FTP, SFTP, whatever). Though as mentioned above, any tool that can speak this new protocol would be able to download the file.
Another approach would be to look for Java-specific headers, such as the User-Agent field (assuming this is populated with something recognisable). But again - this is not secure, as any tool could send through the same headers and impersonate a java download.
If you mean in your question that you only want your files to be downloaded by a specific Java application, then things get a bit more feasible. You can distribute an application that contains some authentication (e.g. public/private key pair) and have the server challenge for this when index.jar is requested. But even then this is dubious - by definition the Java app has to contain sufficient information to authenticate as itself; and by definition you have to distribute this information publically; so it wouldn't be difficult to extract the private keys and have some other application masquerade as your Java one.
Basically, I can't see any way around this issue given the confines you've stated. If there's a narrower scope you'd be willing to entertain you may be able to come up with a viable compromise, but right now the answer is simply "no".
Technically, you can't. Whatever request HTTP Java makes, another HTTP client program can be made that makes the same.
However, you can make it slightly more difficult. You can put the file behind HTTP digest authentication and include the password in the JAR of the Java program the password or can check the user agent server-side.
See e.g. get_browser() and Apache 2 authorization and authentication.
You can make your file read only so that no one can modify actual file but there comes a problem that even java cant modify the file.
So if you need to modify the file,you need to make a new file of same extension and copy entire data from main file to new file and delete the main file and modify the new file and change the name of new file to old file name.
There is a function in java to set read only:
File newTempFile=new File("mytext.txt");
newTempFile.setReadOnly();
You could create a web application that serves your file. Here you could check for the user agent string in the request and decide on that user agent string whether to serve the file or not. For this to work, your "java downloader" must have an identifiable user agent string and your application must "know" it.
Of course any bad guy who knows this, could make his browser send you the same user agent string, so this in not really secure :-/
If your index.jar is very important, do not make it available for download in any of the methods mentioned. As soon as it is available for download and ends up on the client computer, inside java or not, it will be hacked.
Some code should only run on the server.