Java - How can I completely clear a variable - java

I have a Spring Boot application that uses a CredentialsService class to store credentials as GuardedStrings and return them when requested by other classes.
Where the problem arises is in the fact that we use Checkmarx to scan our code and catch potential issues. Where storage of the usernames/passwords are not a problem anymore, I still have to use a String variable to return the plain text credentials. Checkmarx doesn't like that - especially for passwords.
This is the abbreviated view of the CredentialsService:
#Component
public class CredentialsService {
final ExecutorService executor = Executors.newSingleThreadExecutor();
private GuardedString customerApiPassword;
. . .
private StringBuilder clearCustomerApiPassword;
public CredentialsService( . . .
#Value("${customerapi.pwd}") String customerApiPassword,. . .) {
setCustomerApiPassword(customerApiPassword);
. . .
}
private void setCustomerApiPassword(String customerApiPasswordString) {
this.customerApiPassword = new GuardedString(customerApiPasswordString.toCharArray());
this.customerApiPassword.makeReadOnly();
}
public String getCustomerApiPasswordNo() {
clearCustomerApiPassword = new StringBuilder();
customerApiPassword.access(new GuardedString.Accessor() {
#Override
public void access(final char[] clearChars) {
clearCustomerApiPassword.append(clearChars);
}
});
customerApiPassword.dispose();
System.out.println("DGC: clearCustomerApiPassword is " + clearCustomerApiPassword);
Runnable clearFromMemory = () -> {
clearCustomerApiPassword = null;
System.out.println("DGC: clearCustomerApiPassword is " + clearCustomerApiPassword);
};
executor.execute(clearFromMemory);
return clearCustomerApiPassword.toString();
}
And then a requester accesses the values it needs with:
IntegrationApiUtil.setBasicAuthKey(headers, credentialsService.getCustomerApiUsername(), credentialsService.getCustomerApiPassword());
However Checkmarx is still not happy. I use the same approach for storing the GuardedString usernames and passwords and the exact same approach to clearing the Strings that are returned. Checkmarx is fine with the usernames, but it still complains about the passwords:
Method clearCustomerApiPassword; at line 24 of
src/main/java/com/.../service/CredentialsService.java
defines clearCustomerApiPassword, which is designated to contain user passwords. However, while plaintext
passwords are later assigned to clearCustomerApiPassword, this variable is never cleared from memory.
I have tried all sorts of things - a finalize method to destroy the service after it is last used, a disposeAll method to explicitly set all variables to null and call the garbage collector. With the code above I am creating a separate thread in each get method to set the 'clear' variables to null as I return the value to the requester. While I can confirm that this latest approach does provide the requester with the correct values and also sets the variables to null, nothing seems to satisfy Checkmarx.
Does anyone have any ideas?
Thanks in advance.
D

Once you put sensitive data into an immutable object like String, the data will remain in the memory for a long time. You can release the variable, but even without a physical reference the value will still sit in the memory. You can run GC, it will still be there. The only thing that would help would be a creation of another variable using the same memory space and overriding the value.
Long story short: As long as you put your password in a String, Checkmarx will complain.
You have two things you can do:
you either rely on char[] only and clear the array once used,
or use a String value if you are forced to and request a special exception for your case.

Well, you are kinda throwing away all the value of storing passwords in GuardedString by returning/transporting them as regular String.
Don't know a lot about Checkmarx, but it's just a code scanning tool, so it's easy to fool. I suggest actually fixing the problems, instead of trying to sweep them under the rug.
Notice that GuardedString constructor accepts char[], not a String. That's the first problem - you should carry your password from the source up to this point as a char[] - more about it here.
Don't return String to your consumer - return the GuardedString or at least a char[].
Depends on what consumers you are targeting with this class/library, but try to provide a way for them to access the actual passwords for as short time as possible, and clearning the char[] after usage (in a way that consumer will not have to do that himself, since he can forget)

Related

Making static method Synchronized or Not

I have a webservice call to get an authorization token and use it for subsequent webservice calls. Now what we had done earlier was whenever we make any web service call, we first make the token web service and then make the call for actual web service.
Method to get the token is as shown below. Basically what this code does is call the webservice to get the token and using GSON parse the response and get the token.
public static String getAuthTicket() {
String authTicket = null;
HttpResponse httpResponse = getAuthResponse();
String body;
if (httpResponse.getStatusLine().getStatusCode() == 200) {
try {
body = IOUtils.toString(httpResponse.getEntity().getContent());
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
ResponseTicket responseTicket = gson.fromJson(body, ResponseTicket.class);
authTicket = responseTicket.getTicket();
} catch (UnsupportedOperationException e) {
LOGGER.error("UnsupportedOperationException : ",e);
} catch (IOException e) {
LOGGER.error("IO Exception : ",e);
}
}
return authTicket;
}
This has obviously led to performance issue. Hence the party who is providing the webservice to get the token has made the token valid for 30 minutes.
So in the above method what we are thinking is to put the token in cache along with the time and check if the current time - cache time is less than 30. If time is greater than 30 we will make service call to get token and update the token with timestamp in cache.
The only thing is I am fearing is about synchronization, so that I dont get corrupt authtoken due to race condition.
I am thinking to make this static method as synchronized. Do you think is there any other better way.
The answer is: it depends.
Race conditions occur when more than one thread is accessing shared data at the same point in time. So, when you would have code such as:
private final Map<X, Y> sharedCache = new HashMap<>();
public static getAuthTicket() {
if (! sharedCache.containsKey...) {
sharedCache.put(...
...
You would be subject to a race conditions - two threads could come in at the same time, and update that shared map at the very same time; leading to all kinds of problems.
When I get your code right - you would have something similar:
private static String cachedToken = null;
public static getAuthTicket() {
if (cachedToken == null || isTooOld(cachedToken)) {
cachedToken = getAuthTicketForReal();
}
return cachedToken;
}
You probably do not want that two threads call getAuthTicketForReal() in parallel.
So, yes, making that method synchronized is a valid approach.
Where: the real question is: is it sufficient to add that keyword? Given my code - the answer is yes. You simply want to avoid that this cache is setup "in parallel" by more than one thread.
Finally: in case you are worried about the performance impact of using synchronized here - simply forget about that. You are talking about a multi-second "network based" operation; so you absolutely do not worry about the milli second of overhead that synchronized might have (making up this number - the key thing: it is so small that it doesn't matter in the context of the operation you are doing).
Regarding your comment: of course, using synchronized means that the JVM will serialize calls to that method. This means when this method needs 1 minute to return - any other calls to that method will block for that 1 minute.
In that sense; it might be a good exercise to look into ways of writing up this method in a way that does not require synchronized on method level. For example by using data structures that can deal with multiple threads manipulating them.

java associative array sort of thing with more than one data type

imagine this:
DataTypeForConfigs config
with
String keys, but values of either String, Integer, or Boolean,
in Java, JSON can do that, but I'm making a format That goes along the lines of:
number "coolness" is 9001 means
int coolness = 9001;
It's method is: Read line, read each word, think what to make of it, set it to a Variable within it's reach
Also: what would happen if another thing had its own place to put config? a null would be read? WHY? constructor thinks a file has null on it? Rage face.
Say... should I make a class called SettingVal that when given a getValue() call it would say what it is?
SO:
config["Coolness"].getValue();
return's 9001
WAIT:
How on earth would I make the getValue() method? HOW? RETURN VALUE WONT LIKE THIS!! OH CRAP!
Solution:
Another Data type comes in and checks its 'gender' (String, Bool, Int) and then checks it's value of that 'gender' (strVal, boolVar, intVar)
Return values are a big problem when dealing with this. I need a stress free version, so maybe I can have a void returning method that runs another method based on what data type it is said to hold! Am I right?
I have a temporary solution, setVar works, getVar is get*Var, where * is Str, Bool or Int.
Sadly, I Haven't yet been able to properly read it from a file, the method I made to read from a file is not working. It makes a Map<String,SettingVar>, using a HashMap constructor and returns that map, but seems whenever I try to access a variable from it that variable is null. It is probably because of IOExceptions and FileNotFoundExceptions, FileNotFound? Why? It Shouldn't be running until called. Oh, and also NullPointerExceptions Please Help!
SUBQUESTION: what happens when you MapVariable.put({NAME HERE}, varToPutIn) many times in a for loop? what about MapVariable.put({NAME HERE},new ...)?
My code in links:
https://gist.github.com/anonymous/66c4d1c2d2718a4cc9b9
because I don't have enough reputation
P.S: OK! ive made the config reader work now, and SettingVar, and SettingContainer and im working on ConfigWriter which is good, now working on a prototype for a java command prompt like thing, and soon a WHOLE OS!! wait... java is an os. thats why java virtual machine... oh. Well, how can I close this question and turn the outcome into a revolutionary new thingy for kids who want to learn to code java *cough cough* especialy ones with higher learning ability than social ability... and like to hang around with mature people who dont bully them like all the kids in their school. (Wow, that was specific)
I would use a Plain Old Java Object which you can read from JSON.
class Config {
int coolness = 9001;
String hello = "world";
boolean cool = true;
}
This way you can have fields with a variety of types.
The type you're looking for is Map<String,Object>, but it is not type-safe and you'll have to do a bunch of casting:
Map<String,Object> config = new HashMap<>();
config.put("coolness",9001);
config.put("hello","world");
config.put("cool", true);
boolean cool = (Boolean) config.get("cool");
String hello = (String) config.get("world");
int coolness = (Integer) config.get("coolness");
Generally, I'd recommend creating a dedicated class for holding your configuration (each field = one property), which is strongly typed and doesn't require casting, and then use something like Jackson to serialize/deserialize it from json, yaml, or xml.
This provides structure to your configuration, and will cause any issues with malformed configurations to show up when you start your application/load your configuration, and not in the middle of your application.
SUBQUESTION: what happens when you MapVariable.put(varToPutIn) many times in a for loop?
A Map represents a mapping. If you do this:
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.put("myKey", Integer.valueOf(i));
}
what happens is that you add a mapping from "myKey" to zero, then update it to one, two, three and so on. When the loop ends, "myKey" will map to nine.
In short, the map entry for "myKey" is behaving like a variable of type Integer that you assign to repeatedly.
I'm afraid your Gists are telling me that you simply didn't take on board what #Darth Android wrote. Rather that hashing through your code, here's a simple way to parse your config file syntax (more or less) and load it into a Map<String, Object>
Note: I have not compiled or tested this code. It is written to be read and understood, rather than borrowed.
Map<String,Object> config = new HashMap<>();
try (Scanner s = new Scanner(new FileReader(someFile))) {
while (s.hasNext()) {
// Syntax is '<type> <name> is <value>'
String[] words = s.nextLine().split("\\s+");
if (words.length != 4 || !words[2].equals("is")) {
throw MySyntaxException("unrecognizable config");
}
String type = words[0];
String name = words[1];
String val = words[3];
switch (type) {
case "number":
map.put(name, Integer.valueOf(val));
break;
case "boolean":
map.put(name, Boolean.valueOf(val));
break;
case "string":
map.put(name, val);
break;
default:
throw MySyntaxException("unknown type");
}
} catch (NumberFormatException ex) {
throw MySyntaxException("invalid number");
}
}

How to get current EC2 instance state in Java

I'm looking for some code that will return the current instance state regardless of whether the instance is currently running or not. I found some code that will return the desired result on a running instance, but when trying to find one that will work on stopped instances, I was overwhelmed by a number of similar looking classes that appeared to perform a similar operation, but in the end, did not work or were poorly documented.
Anyway, the running instance version of the code is below:
public Integer getInstanceStatus(String instanceId) {
DescribeInstanceStatusRequest describeInstanceRequest = new DescribeInstanceStatusRequest().withInstanceIds(instanceId);
DescribeInstanceStatusResult describeInstanceResult = ec2.describeInstanceStatus(describeInstanceRequest);
List<InstanceStatus> state = describeInstanceResult.getInstanceStatuses();
return state.get(0).getInstanceState().getCode();
}
So I'm basically looking for the equivalent that does not have the DescribeInstanceStatus's restriction that requires the instance to be running. I'd assume this is possible since the getCode() documentation shows it as being able to return the value 80 which denotes a stopped instance.
And once again, I answer my own question... Though I am open to other suggestions.
public Integer getInstanceStatus(String instanceId) {
DescribeInstancesRequest describeInstanceRequest = new DescribeInstancesRequest().withInstanceIds(instanceId);
DescribeInstancesResult describeInstanceResult = ec2.describeInstances(describeInstanceRequest);
InstanceState state = describeInstanceResult.getReservations().get(0).getInstances().get(0).getState();
return state.getCode();
}
If you set withIncludeAllInstances(true) on your request then you can get states for the not running instances.
DescribeInstanceStatusResult result = ec2.describeInstanceStatus(new DescribeInstanceStatusRequest()
.withInstanceIds(instanceIds).withIncludeAllInstances(true));

Why is it that RESTlet takes quite time to print the XML, sometimes

I am implementing REST through RESTlet. This is an amazing framework to build such a restful web service; it is easy to learn, its syntax is compact. However, usually, I found that when somebody/someprogram want to access some resource, it takes time to print/output the XML, I use JaxbRepresentation. Let's see my code:
#Override
#Get
public Representation toXml() throws IOException {
if (this.requireAuthentication) {
if (!this.app.authenticate(getRequest(), getResponse()))
{
return new EmptyRepresentation();
}
}
//check if the representation already tried to be requested before
//and therefore the data has been in cache
Object dataInCache = this.app.getCachedData().get(getURI);
if (dataInCache != null) {
System.out.println("Representing from Cache");
//this is warning. unless we can check that dataInCache is of type T, we can
//get rid of this warning
this.dataToBeRepresented = (T)dataInCache;
} else {
System.out.println("NOT IN CACHE");
this.dataToBeRepresented = whenDataIsNotInCache();
//automatically add data to cache
this.app.getCachedData().put(getURI, this.dataToBeRepresented, cached_duration);
}
//now represent it (if not previously execute the EmptyRepresentation)
JaxbRepresentation<T> jaxb = new JaxbRepresentation<T>(dataToBeRepresented);
jaxb.setFormattedOutput(true);
return jaxb;
}
AS you can see, and you might asked me; yes I am implementing Cache through Kitty-Cache. So, if some XML that is expensive to produce, and really looks like will never change for 7 decades, then I will use cache... I also use it for likely static data. Maximum time limit for a cache is an hour to remain in memory.
Even when I cache the output, sometimes, output are irresponsive, like hang, printed partially, and takes time before it prints the remaining document. The XML document is accessible through browser and also program, it used GET.
What are actually the problem? I humbly would like to know also the answer from RESTlet developer, if possible. Thanks

Sorrounding Logger with an If clause to avoid redundant String construction

I got a recommendation to use this syntax when logging in java:
if (logger.isLoggable(Log.FINE))
{
logger.fine("bla"+" bla"+" bla");
}
The reason for this is to avoid the redundant construction of the parameter string incase the logging level is lower than "FINE". (in the example above - 5 redundant string object. (" bla"X3, " bla bla" and "bla bla bla").
I'd like to hear what others are doing about this or if you think that this is necessary at all.
Thanks!!
Some newer logging frameworks allow you to specify arguments as parameters, and won't evaluate them if there's no logging.
The example I found is LogBack, the successor to Log4j. Here's the info: http://www.infoq.com/news/2007/08/logback
This gives you the best of both worlds, so to speak. Elegant syntax yet good performance.
Log4j code example:
if( logger.isDebugEnabled() ) {
logger.debug( "User with account " +
user.getAccount() + " failed authentication; " +
"supplied crypted password " + user.crypt(password) +
" does not match." );
}
Equivalent LogBack code:
logger.debug( "User with account {} failed authentication; " +
"supplied crypted password {} does not match.",
user.getAccount(), user.crypt(password) );
This defers the cost of message assembly until LOGBack has ascertained whether or not this message will be viewed. It doesn't defer the cost of retrieving expensive parameters, such as the password crypting in the above example.
String objects are immutable, and repeated concatenation is therefore an expensive operation. It requires repeated memory allocation, object creation and iteration. Considering that some logging calls at the finer log levels can be invoked thousands or millions of times per minute, it might be a considerable performance gain to do as you illustrate. Though, for a smaller application, it might not be worth the extra effort.
As a side note: You can save even more performance, where this is truly critical by using a constant such as this:
public static final boolean DEBUG = false;
If you now wrap the logging code in an if-block such as this, the JVM will be able to completely optimize away the debug calls when running in product mode. This is as close as you get to a C #ifdef.
if (Globals.DEBUG) {
// Logging call
}
Absolutely necessary for debug type logging. It something like 10x quicker to check the log level first than create the string and throw it away.
This is an improvement (good) but it can be improved on a little.
Set up final flags for each logging level (FINE, etc) in a global object used as config, then use a StringBuffer to build up your debugging output -- you can even format numbers into the stream at the same time.
public class MyAppConfig {
public final boolean FINE=true;
// ... other fields
}
public class MyApp {
void someFunction() {
...
int imagesProcessed;
imagesProcessed = processImages();
if (MyAppConfig.FINE) logger.fine(new StringBuffer(35).
append("Count of images processed: ").append(imagesProcessed).toString());
...
}
}
Here the string buffer is set up with an 'initial capacity' of 35 characters. If you know how many characters are going to be generated you can provide hints to StringBuffer.

Categories