Brian McCutchon
Brian McCutchon

Reputation: 8584

Securely URL-encode a password

Java provides the URLEncoder class for URL-encoding Strings. But it is considered insecure to store passwords as Strings. Is this code to send a password via POST over an HttpsURLConnection output stream wr secure enough?

try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
    // Write some post params
    for (char c : pass) {
        wr.writeBytes(URLEncoder.encode(String.valueOf(c), "UTF-8"));
    }
    // Write some more
}

On the one hand, it is using Strings. On the other hand, those Strings are 1 character long, and conceptually the same after encoding. Also, it seems to me that this could fail on multi-byte characters. Would an attacker be able to locate these 1-char Strings in memory and reconstruct the original password? Is there a better way to do this?

Upvotes: 1

Views: 4289

Answers (2)

Kayaman
Kayaman

Reputation: 73528

It's true that when using Strings for passwords, you can't reliably discard them since you can't zero out the String contents manually (except through reflection) and the contents will stay in memory for an unknown time. Therefore char[] is often recommended to be used for any password input, followed by a manual zeroing of the said char[].

However the attack is in no way easy to mount since it requires access to the memory, luck with timing. It's unlikely the password will stay in the memory for very long amounts of time, as the GC does its work and the memory gets reused. In most cases this attack vector can be infeasible compared to other, simpler attacks.

Upvotes: 2

GhostCat
GhostCat

Reputation: 140407

An OutputStream has no method writeBytes; but it offers a write(byte[]) method that could be used to write all chars of the password with one call.

And beyond that: the whole idea of using HTTPS is that the connection itself is securely encrypted; so it really should not matter whether you transmit such content with single byte or multi byte bursts.

Then: keep in mind that all these classes are abstractions, that are layered upon each other. HTTPS uses TCP; and TCP packets have a certain size; in that sense there aren't single bytes going over the network anyway.

And regarding the second part of your question: you are iterating an array of char values. So it really depends how that char array was created; but normally, you don't need to worry (see here on that topic).

Upvotes: 0

Related Questions