Stephen Scott
Stephen Scott

Reputation: 63

Alter user password via jdbc. Problems with passes containing question marks

I have a problem with altering a users password when the password contains a question mark char. I do not encounter this problem with any other char so far, it seems specific to the question mark char.

If i alter a users password in sqlplus using the following sql:
Alter user Stephen identifed by "NewPassword?" REPLACE "OldPassword";
Then it changes the pass successfully and I can login using the new pass 'NewPassword?'.

However if I execute the same SQL via jdbc:
final String query = "ALTER user Stephen identified by \"NewPassword?\" REPLACE \"OldPassword\"";
stmt.executeUpdate(query);

I then cannot log in using the pass 'NewPassword?'.

Checking the hashcodes for the password when entered via sqlplus and jdbc show that they are different. Somehow when I run the statement in jdbc it is entering something other than 'NewPassword?'.

I don't seem to have any problems with the following passwords: NewPassword, NewPassword\, NewPassword'. It just seems to be the question mark that is causing problems.
Debugging shows the code point (dec) is 63 for the question mark so it doesn't look like its being changed midway.

Does anyone have any idea what could be causing this behaviour? I'm at a loss at the moment, I'm considering preventing passes with question marks to bypass this problem for now.

Upvotes: 6

Views: 6954

Answers (2)

Luke Woodward
Luke Woodward

Reputation: 64959

To use JDBC to change the password of an Oracle user you need to do two things:

  • put the password directly in the SQL string (bind parameters cannot be used),
  • disable escape processing.

You can't use bind variables because the username and password are not sent to the database as single-quoted strings.

The ? in the SQL string is being taken as a bind variable placeholder, and because of this the SQL string is getting mangled at some point by Oracle JDBC. Disabling escape processing on the statement stops this from happening. Try:

Statement s = conn.createStatement();
s.setEscapeProcessing(false);
s.executeUpdate("ALTER user Stephen identified by \"newPassword?\" replace \"oldPassword\"");

If you are setting the password programmatically, your code should also ensure that the new and old passwords do not contain any " characters, to avoid SQL injection.

Upvotes: 7

Cameron Skinner
Cameron Skinner

Reputation: 54296

Try implementing it using a PreparedStatement and see if you get the same problem. Question marks are used in PreparedStatements as placeholders, so maybe the JDBC driver is getting confused. It shouldn't, but might be worth checking.

PreparedStatement p = conn.prepareStatement("ALTER user Stephen identified by ? replace ?");
p.setString(1, "NewPassword?");
p.setString(2, "OldPassword");
p.execute();

If this works then it's probably a bug in the driver.

Upvotes: 2

Related Questions