>
> You start by configuring the client with an initial user name and
> password. Later on, you reconfigure it to use another, "bogus"
> password. As soon as the server rejects the "bogus" user name and
> password, the client starts using the initial credentials again and
> authenticates successfully. Right?
>

Actually, not quite right.

There are two instances of the class XMLRPCProxy whose init source code was
provided. The first instance is configured to use a regular user's
username/password. The second instance is configured to use an admin user's
username/password.

When the human giving the admin password provides an incorrect password to
the second instance, then the regular user's credentials configured in the
first instance appear to be used instead by the second instance when
authenticating to Apache. This can be seen by checking
the os.environ.get('REMOTE_USER') on the server side (which is running
Apache httpd). The /var/log/messages trace from our server code's use of
logger shows the admin RPCs are being called by a regular user and failing
(because the REMOTE_USER var is not "admin").

The first instance's regular user's credentials are never invalid. There can
be more than one connection to httpd using the same regular user's
credentials.
Both ends of the connection are Apache. This is Apache XML-RPC talking to
the Apache Server.

I don't know what Apache is doing when talking to Apache as far as it's use
of a protocol under the hood, but I'm sure that's an implementation detail a
user of the library should not have to deal with directly, which is why when
I saw this behavior, I took time to point it out.

*without* the use of the Authenticator class (indeed, I haven't got
> the slightest idea, why you are using both) and with a complete source
> code example.
>

I am using the Authenticator class because the basic authentication over
https has failed otherwise. I'd rather not use it.

Thanks,
Greg

Software Architect
Medstrat, Inc.



> On Thu, Apr 1, 2010 at 6:06 PM, Greg Smethells <gsmethe...@medstrat.com>
> wrote:
>  > ---------- Forwarded message ----------
> > From: Greg Smethells <gsmethe...@medstrat.com>
> > To: xmlrpc-a...@ws.apache.org
> > Date: Thu, 18 Mar 2010 10:22:21 -0500
> > Subject: Connection re-use bug in XML-RPC 3.1.3
> >
> > XML-RPC Developers,
> >
> > There is a security hole in the re-use of server connections when
> > basic authentication is involved.
> >
> > Context:
> > We have an XML-RPC client that connects to a server over HTTPS and
> > requires basic authentication. Initially, the app starts up using a
> > 1st username/password and our java.net.Authenticator does a
> > setDefault() to our own WebServerAuthenticator class. It's
> > getPasswordAuthentication() is called by HttpURLConnection and the
> > connection succeeds on the server. I cannot tell if it is ever used,
> > but the XmlRpcClientConfigImpl also has its setBasicUserName and
> > setBasicPassword set on the xmlrpcClient instance. Everything looks
> > good at that point.
> > Then, we have an administration dialog we use to configure the server
> > side, which is where the issue starts to come up. The
> > username/password at this point is different than when the app first
> > signed into the server. A new WebServerAuthenticator class is
> > setDefault()-ed with this admin (2nd) username/password and a new
> > XmlRpcClientConfigImpl is instantiated and set to the admin's (2nd)
> > user/pass and a new xmlrpcClient is also instantiated and set to the
> > new client config. On the server side, I can see the client try to log
> > in as the admin (2nd); however, if I provide a bogus password, I can
> > see the basic auth fail on the server side AND THEN the original
> > (1st) username/password (not the admin (2nd) credentials) are used to
> > sign in and the RPC returns successfully (no exception thrown for
> > password mismatch!). Unbeknownst to the app the xmlrpcClient has used
> > credentials that were not asked to be used!
> >
> > Source Code:
> > This is called during construction of the client-side server proxy ...
> >                        // Assign an Authenticator to pass username
> > and password data during HTTPS requests
> >                        // Required for getting past Apache
> > authentication (.htaccess)
> >                        Authenticator.setDefault(new
> > WebServerAuthenticator(username, password));
> >                        // Create the XML-RPC client
> > XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
> > // Set-up the URL to the XML-RPC server
> > config.setServerURL(new URL("https://"; + ipAddress + "/" + cgiScript));
> > // Set-up the log-in credentials that provide our actual security
> > config.setBasicUserName(username);
> > config.setBasicPassword(password);
> > config.setEnabledForExtensions(true);
> > // WARNING: must be as high enough to allow all timeouts given to call()
> > config.setConnectionTimeout(30 * 1000);        // Timeout for connecting
> > config.setReplyTimeout(MAX_TIMEOUT * 1000);    // Timeout for XML-RPC
> > replies
> > xmlrpcClient = new XmlRpcClient();
> > xmlrpcClient.setConfig(config);
> > // Timeout after "timeout" seconds ("timeout" seconds x 1000
> milliseconds)
> > TimingOutCallback callback = new TimingOutCallback(15 * 1000);
> > // Fault tolerant connect
> > try {
> > Object[] result;
> > Object[] params = new Object[] {};
> > if( testRPC.length() > 0 ) {
> > // Asynchronous remote procedure call
> > xmlrpcClient.executeAsync(testRPC, getParams(params), callback);
> > result = (Object[]) callback.waitForResponse();
> >
> > // If we did not throw an exception and got here, then we are connected
> >  state = CONNECTED;
> > // Finish any internal state set-up
> > setupState(result);
> > Console.print("Connection opened to " + toString());
> > }
> > else {
> > // Assume we are "connected"
> > state = CONNECTED;
> > Console.print("Proxy created for " + toString());
> > }
> > }
> > catch(TimeoutException e) {
> > setState(e.getMessage(), ADDRESS_UNREACHABLE);
> > }
> > catch(XmlRpcException xrex) {
> > parseState(xrex.getMessage());
> > }
> > catch(Exception ex) {
> > parseState(ex.getMessage());
> > }
> > catch(Throwable t) {
> > parseState(t.toString());
> > }
> > }
> > else {
> > state = CONNECTION_NOT_ALLOWED;
> > }
> > Thanks,
> > Greg
> >
> > Software Architect
> > Medstrat, Inc.
> >
> >
> >
> >
> > --
> > Germanys national anthem is the most boring in the world - how telling!
> >
>
>
>
> --
> Germanys national anthem is the most boring in the world - how telling!
>

Reply via email to