-
Notifications
You must be signed in to change notification settings - Fork 65
Security
Executive summary: Rserve should be used locally only with local (unix) sockets for local communication that does not require authentication and should only be used with TLS and OCAP mode if used remotely. All other methods have inherent security implications, the rationale and details are discussed in length below.
Rserve has been originally developed for local communication for Java process to be able to start R and perform computations. Therefore Rserve will by default only listen on a local interface allowing processes on the same machine to perform R computations. When using TCP port, any process on the local machine can connect to Rserve and perform computations in R. Note that R by design allows arbitrary code execution and even though some people have tried to impose some limits, such efforts are by definition futile, because R can compute on the language and must be able to access native code for its operation so most such efforts are easily defeated. You can assume that a user that is able to perform eval tasks via Rserve has access to the host as the user that is running the server. If that is not intended please read below about the different modes of operation and available security options.
The default mode of operation is to bind to a TCP port and accept connections. This enables any process by any user to connect to the server. A more secure way for local operation is to bind to a local (unix) socket, because that allows you to use unix file system permissions to restrict the access to that socket. For example, by using the socket
option and setting sockmod 0700
you can restrict access only to the user that has started Rserve. This is the recommended deployment for local operations.
However, it is often necessary to allow access from remote machines or by multiple users. In that case it is highly advisable to use some authentication mechanism.
Rserve has several authentication modes which offer varying level of protection (from none to reasonable). The most simple and also the most insecure is the plain-text password authentication (plaintext enable
, advertized as ARpt
uses CMD_login
). Obviously, this is very insecure if not combined with any other security mechanism (such as TLS) since the packet contains the username and password in plain text and thus has been always discouraged.
The second option is the old unix-crypt based password authentication which uses password hash and salt, (advertized as ARuc
, uses CMD_login
). It is not safe, because the amount of entropy in the salt is relatively small and the hashing algorithm very simple and fast thus it is generally possible to brute-force the password based on an observed value. Hence for all practical purposes this should be considered as unsafe as the plain text method.
The third built-in option is RSA-based authentication (CMD_keyReq
+ CMD_secLogin
). It requires the client to obtain a nonce and a public key from the server which then has to be sent with the encrypted authentication details back to server. This is secure against snooping even over insecure channels, because the credentials are encrypted. Note that Rserve version <= 1.8-9 allowed replay attacks on non-forked servers (typically Windows) where issuing CMD_secLogin
without CMD_keyReq
was possible if the same key was used. This issue was fixed in Rserve 1.8-10 and did not affect forked servers (the recommended deployment). Unfortunately only few clients implement this authentication method (e.g., see RS.authkey
and RS.login
in RSclient).
The three methods above are part of the QAP1 protocol. Rserve supports tunneling of QAP1 over TLS/SSL (see also TLS SSL support) so some of the concerns can be alleviated by enabling communication only over a secure layer. Furthermore, Rserve 1.8-8 and higher allows client TLS authentication using client certificates which should be the preferred method of authentication for all new clients. For more options see also OCAP mode below.
Password management is based on the password file. In most cases (with the exception of password file caching and user-switching) the password file is readable by the (authenticated) Rserve process so due to arbitrary code execution via CMD_eval
it can be assumed that the user has access to it. Rserve supports plain passwords (highly discouraged) and passwords based on MD5 or SHA1 hashes (only SHA1 should be used nowadays). The passwords file is a text file where each line has the form:
[@]username[/uid[,gid]] {$MD5|$SHA1|password}
If the username is prefixed with @
prefix then that user is allowed to execute control commands (control commands have been removed since Rserve 1.8). Leading #
denotes a comment line and is ignored. Example:
## regular user "john" with password "foo"
john foo
## user "admin" can use controls commands, sha1 of the password "admin!"
@admin $21010de43f356a98feb77754c1d8ec3e67f1ae6b
On the note of caching and user-switching: cachepwd yes
in conjunction with uid
/gid
and su client
can be used to secure the password file by running the server as root
and then switching uid/gid for the client process. This way the password file can be made root
-readable only and also it isolates the server process from users preventing signals etc. Obviously, the inherent danger in that is that it requires the server to run as root
in order to switch users which enables another potential attack vector with root
privileges.
As discussed above, one fundamental issue with using the "normal" Rserve mode is that it allows arbitrary R code execution by design. This is great when serving an IDE locally or when arbitrary computations are necessary, but it is problematic if such a service is to be exposed remotely. Authentication as discussed above can potentially limit the access to that service, but once authenticated there are no limits. However, it may be desirable to only expose well-curated R code as a service with well-defined input checks. For this purpose Rserve 1.7 has introduced a special Object Capabilities (OCAP) mode in which all commands other than CMD_OCcall
are disabled.
In short, capabilities are R functions. Only such individual R functions explicitly defined by the server and passed (as reference) to the client can be called by the client. The OCAP mode enables many other features and is discussed in more detail in OCAP mode, but in this context the main feature is that at first when a connection is established the client has no capabilities whatsoever, so it is up to the server to define what the client is allowed to do. Therefore the server can choose to only provide a single authentication capability which has to be called to the server's satisfaction before it provides further capabilities to the client. Moreover, the server can choose to expose individual specific functions which are guarded against arbitrary code execution by the virtue that no parsing is being done in the call and only constants are allowed (and thus no side-effects).
For all modern applications this is strongly recommended way of using Rserve. It allows the application to fully control the API allowed over the wire and prevent arbitrary code execution. It also allows arbitrarily complex authentication and authorization schemes.