You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Mark Ebbers (JIRA)" <ji...@apache.org> on 2017/10/06 11:08:00 UTC
[jira] [Commented] (SSHD-775) SftpSubSystem::sendStatus leaks
Exception information
[ https://issues.apache.org/jira/browse/SSHD-775?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16194458#comment-16194458 ]
Mark Ebbers commented on SSHD-775:
----------------------------------
I did not find any guidelines regarding the 'error message' string part of the SSH_FX_STATUS response message and the latest draft RFC only stated the following:
{quote}
*9.1. Status Response*
error message
Human readable description of the error.
{quote}
So I did a quick investigation of the source of the latest version of OpenSSH and it appears that OpenSSH only returns a small set of error messages.
{code:java}
Openssh-7.2p2/sftp-server.c
status_to_message(u_int32_t status)
{
const char *status_messages[] = {
"Success", /* SSH_FX_OK */
"End of file", /* SSH_FX_EOF */
"No such file", /* SSH_FX_NO_SUCH_FILE */
"Permission denied", /* SSH_FX_PERMISSION_DENIED */
"Failure", /* SSH_FX_FAILURE */
"Bad message", /* SSH_FX_BAD_MESSAGE */
"No connection", /* SSH_FX_NO_CONNECTION */
"Connection lost", /* SSH_FX_CONNECTION_LOST */
"Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
"Unknown error" /* Others */
};
return (status_messages[MIN(status,SSH2_FX_MAX)]);
}
openssh-7.2p2/sftp-common.c
/* Convert from SSH2_FX_ status to text error message */
const char *
fx2txt(int status)
{
switch (status) {
case SSH2_FX_OK:
return("No error");
case SSH2_FX_EOF:
return("End of file");
case SSH2_FX_NO_SUCH_FILE:
return("No such file or directory");
case SSH2_FX_PERMISSION_DENIED:
return("Permission denied");
case SSH2_FX_FAILURE:
return("Failure");
case SSH2_FX_BAD_MESSAGE:
return("Bad message");
case SSH2_FX_NO_CONNECTION:
return("No connection");
case SSH2_FX_CONNECTION_LOST:
return("Connection lost");
case SSH2_FX_OP_UNSUPPORTED:
return("Operation unsupported");
default:
return("Unknown status");
}
/* NOTREACHED */
}
{code}
Based on the source of OpenSSH I suggest two possible options:
h3. Option 1
{code:java}
public static String resolveStatusMessage(final Throwable t) {
if (t == null) {
return "";
} else if ((t instanceof NoSuchFileException) || (t instanceof FileNotFoundException)) {
return "No such file or directory";
} else if (t instanceof InvalidHandleException) {
return "Invalid handle";
} else if (t instanceof FileAlreadyExistsException) {
return "File already exists";
} else if (t instanceof DirectoryNotEmptyException) {
return "Directory not empty";
} else if (t instanceof NotDirectoryException) {
return "Not a directory";
} else if (t instanceof AccessDeniedException) {
return "Permission denied";
} else if (t instanceof EOFException) {
return "End of file";
} else if (t instanceof OverlappingFileLockException) {
return "Lock conflict";
} else if (t instanceof UnsupportedOperationException) {
return "Operation unsupported";
} else if (t instanceof InvalidPathException) {
return "Invalid filename";
} else if (t instanceof IllegalArgumentException) {
return "Invalid parameter";
} else if (t instanceof UnsupportedOperationException) {
return "Operation unsupported";
} else if (t instanceof UserPrincipalNotFoundException) {
return "Unknown principal";
} else if (t instanceof FileSystemLoopException) {
return "Link loop";
} else if (t instanceof SftpException) {
return "Failure";
}
return "Unknown error";
}
{code}
h4. Motivation
* This version is somewhat more verbose and clearer to the client in the case something goes wrong than OpenSSH.
* No use of the exception message itself to prevent information leakage. Also not needed. For example the NoSuchFileException has a reference to the file which could not be found, but the client already knowns which file because it initiated the request.
* The SFTPException can be a problem. For example see _SftpSubSystem::doRemove(): throw new SftpException(SftpConstants.SSH_FX_FILE_IS_A_DIRECTORY, p.toString() + " is a folder");_ If this is the case the client will receive a "Failure". However the client also received the substatus SSH_FX_FILE_IS_A_DIRECTORY....
h3. Option 2
{code:java}
private static String resolveSubStatusMessage(int status) {
switch (status) {
case SSH_FX_OK:
return "Success";
case SSH_FX_EOF:
return "End of file";
case SSH_FX_NO_SUCH_FILE:
return "No such file or directory";
case SSH_FX_PERMISSION_DENIED:
return "Permission denied";
case SSH_FX_FAILURE:
return "Failure";
case SSH_FX_OP_UNSUPPORTED:
return "Operation unsupported";
}
return "Unknown error";
}
{code}
h4. Motivation
* Inline with OpenSSH.
* Based on substatus instead of Throwable.
* Does not make the client smarter then needed.
* One might consider to also use this option to resolve a message for _SftpException.getStatus()_.
I go for option 2 in my project. I think the combination of status + substatus is already enough information for the client especially with option 2.
h4. Sources
*SFTP RFC draft 13*
* https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
* 9.1. Status Response
* 11. Implementation Considerations
* 13. Security Considerations
*OpenSSH 7.2p2 source code*
* http://archive.ubuntu.com/ubuntu/pool/main/o/openssh/openssh_7.2p2.orig.tar.gz
> SftpSubSystem::sendStatus leaks Exception information
> -----------------------------------------------------
>
> Key: SSHD-775
> URL: https://issues.apache.org/jira/browse/SSHD-775
> Project: MINA SSHD
> Issue Type: Improvement
> Affects Versions: 1.6.0
> Reporter: Mark Ebbers
> Priority: Minor
> Labels: security
>
> I'm using SSHD-core 1.6.0 in my own Sftp server implementation and make use of the rooted file-system. Now did I notice that a client did try to rename a file, which was no longer available, and got a response with the substatus SSH_FX_NO_SUCH_FILE and the message ' Internal NoSuchFileException: /srv/sftp/chroot/11738/file.txt'.
> As a client I now know the following two things:
> * The full path on the file-system.
> * The server was written in Java. (NoSuchFileException)
> I noticed that the SftpSubsystem.sendStatus(Buffer, int, Throwable) uses the SftpHelper.resolveStatusMessage() method to create a message string to be send to the client without further checking what information is inside the Exception message.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)