Preamble: This might be a giant noob mistake, all the developers on my team are a little fuzzy at the Java 101 here so if we\'re worrying about nothing please let me know. [
My concern here is that a string literal being passed could be cached and opens potential security holes.
Your concern is only partially valid. A String literal is one that is actually present as a literal in a Java class file. A password provided by a user is not a String literal; instead it is a String object, and it will not be placed in the permanent generation unless you invoke String.intern()
.
Now assuming that you are not committing the folly of invoking String.intern()
, your other concern of having passwords around in memory ought to be addressed. This is already next to impossible in Java (due to the copying of objects performed by garbage collectors), and the JSF lifecycle makes it impossible (by requiring the construction of String objects for input values). The following bit of code was written by me to allow for managed beans to store passwords as character arrays by converting Strings to char[] arrays (and vice versa), but it is useful only for the sake of compliance checks if you've realized that the String
objects could lie around for sometime in memory:
@FacesConverter("Char[]Converter")
public class CharArrayConverter implements Converter
{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String newValue)
{
if(newValue == null)
{
return newValue;
}
return newValue.toCharArray();
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
if(value == null)
{
return null;
}
char[] inputValue;
try
{
inputValue = (char[]) value;
}
catch(ClassCastException ccex)
{
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Object was not present in the desired format", null);
throw new ConverterException(message);
}
return new String(inputValue);
}
}
The converter is used in the Facelet as:
...
<p>
<h:outputLabel for="password" value="#{msg['Signup.password.label']}" />
<h:inputSecret id="password" value="#{userManager.signupRequest.password}" converter="Char[]Converter" />
</p>
...