Whenever I start my app I have the following code:
C.userPreferences = getSharedPreferences("default",0);
C.userPreferencesEditor = C.userPreferences.edit();
C.something = C.userPreferences.getStringSet(C.SOMETHING, null);
C.something = C.something == null ? new HashSet<String>() : C.something;
for(String str : C.something){
Log.d("debugging C.something",str);
}
And this correctly logs "one","two" from the string set.
Afterwards I have the following function:
C.something.add("name");
C.userPreferencesEditor.putStringSet(C.SOMETHING, C.something);
C.userPreferencesEditor.apply(); //or with .commit();
And debugging shows "one","two" and "name".
When I restart the app and debug for the first time I only obtain "one" and "two".
Any idea on why this happens? tyvm
This says
Objects that are returned from the various get methods must be treated as immutable by the application.
More specifically:
Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.
Can you try copying the HashSet you retrieved, adding a new entry to the copy, and saving it in preferences?
BTW - I'd be really curious to know why this is the way it is - not very intuitive...
Related
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)
I'm trying to read the public certificate names from a smartcard to display to the user before they sign a file using a gemalto smartcard.
I've followed the getInfo example from iaikPkcs11Wrapper demos as below :
Module pkcs11Module = Module.getInstance(settings.getCryptoDll());
Slot[] slotList;
try{
slotList = pkcs11Module.getSlotList(true);
}catch(TokenException tex){//module is not initialised
tex.printStackTrace();
pkcs11Module.initialize(new DefaultInitializeArgs());
slotList = pkcs11Module.getSlotList(true);
}
for (Slot slot : slotList) {
Token token = slot.getToken();
iaik.pkcs.pkcs11.Session session = token.openSession(true, SessionReadWriteBehavior.RO_SESSION, null, null);
session.findObjectsInit(null);
Object[] objects = new Object[0];
try {
objects = session.findObjects(1);
This fails always at the line objects = findObjects(1); with a CKR_TEMPLATE_INCONSISTENT exception.
As I understand from the documentation session.findObjectsInit(null) should just return all accessible objects on the card and you can then compare them for type.
I have various smartcards and they all fail like this, I've also tried calling session.findObjectsInit(tempObj) with a GenericTemplate object and a X509PublicKeyCertificate which both return the same exception, and with an X509AttributeCertificate which returns no objects but does not throw the exception.
I'd appreciate any pointers anyone can give. Or do I need to create a matching template object using GenericTemplate? I'm unsure why I'm getting the exception as I thought passing the object into the getObjectInit method filtered for thet object so anything returned should match.
EDIT
I've subsequently tried with other templates and ones for objects not on the card just return an empty array- no exception and ones I think are on the cards just throw the ckr_template_inconsistent exception, any help would be gratefully received.
EDIT2
I've now tried with some new 'V3' cards, which do infact work, all my test cards work using another technique (we currently use capicom via com4J for signing), so maybe there is an issue with the iaik wrapper, or gclib.dll (or me).
I am writing an Assertion Generator Plugin in Java to fetch a user details from Session Store and modify the values in Assertion(SAML 2.0) accordingly.
I am able to identify the method(Link) using which I can pull the user values from Session Store (agentAPIObject.getSessionVariables()) based on SessionID, but, I am having trouble writing a code to fetch specific parameters from the session store. (speficially around setting values for Attribute method and making it as an array)
Can someone post a sample code if you have ever seen/written around it, so that I can fetch user attributes from Session Store.
I am having trouble understanding Java docs around it.
Thanks in advance,
The API mentions this:
responseAttributeList - On successful return from this method (YES is
returned), this output parameter contains the retrieved variable names
and their values. If the method returns UNRESOLVED, this parameter
includes variables that could not be retrieved.
You'll need to create two AttributeList Objects. If the response of getSessionVariables(...) is YES, then the variable responseAttributeList will contain the session variables. Since Java uses references, that same variable responseAttributeList will be updated. You can then use getAttributeAt(...) to access the Attribute Objects.
String sessionID = "sampleID";
ResourceContextDef rcd = //whatever it needs to be equal to
AttributeList requestAttributeList = new AttributeList();
AttributeList responseAttributeList = new AttributeList();
if(getSessionVariables(sessionId, rcd, requestAttributeList, responseAttributeList) == YES){
Attribute att = responseAttributeList.getAttributeAt(0);//or whatever index.
}
Remember to carefully read the API.
NOTE: This is just pseudo code. I have not tested this. However, this should be plenty enough to get you going where you need to.
i have a list of objects:
List<TaskDataValue> configuredTaskData = sourceofdata;
I am iterating the list, to change a property from an object WITHIN the object:
for (int i=0; i<configuredTaskData.size(); i++) {
FieldConfiguration fc = configuredTaskData.get(i).getSettings();
String fieldName = configuredTaskData.get(i).getName();
if (newLabels.containsKey(fieldName)) {
fc.setLabel(newLabels.get(fieldName));
configuredTaskData.get(i).setSettings(fc);
}
}
although what is happening is that every TaskDataValue.getSettings.label is set to the last one,
sounds like configuredTaskData.get(i).setSettings(fc); is setting not only to i but to evry one
What can be happening here ?
using java 1.6
Check where you create the TaskDataValues in sourceofdata. Is it possible that they all have been configured with the same FieldConfiguration instance?
The most likely reason for something like this to happen is that you only actually have one TaskDataValue object - or inside TaskDataValue there is an object that there is only one of.
Because that object is shared any change made to it from one reference is also seen from all the other references.
For example:
List<TaskDataValue> tdvs = ...;
TaskDataValue v = new TaskDataValue();
tdvs.add(v);
tdvs.add(v);
tdvs.add(v);
That code creates one single TaskDataValue object and adds three references to that object to the list. If you change a setting inside tdvs.get(1) you will also see 2 and 3 change too.
I have a problem related to Java servlet sessions. I don't understand why the getAttribute() function of the session object is used before setAttribute(); Here is the code:
Vector buylist=(Vector)session.getAttribute("Register");
if (action.equals("del")) {
String del = request.getParameter("deli");
int d = (new Integer(del)).intValue();
buylist.removeElementAt(d);
}
session.setAttribute("Register", buylist);
Thanks.
This code intends to save back the modified vector represented by Register session attribute.
However you dont need to set the attribute back even after some elements are removed or added because its the reference anyways thats stored in session and any changes to it are essentially being applied to the same object.
Because Register attribute may be set from some other place (like. from jsp(in bad case),Servlet or Filter . . )
The only explanation I can think of is: first of all you you retrieve the vector, then make the change and after store it back into session object.
The code is either broken or the setAttribute() is futile.
If you get a mutable container (like a list or a vector) from the session, then it's not necessary to put it again into the session. It's the equivalent of this code:
session.setAttribute("Register", buylist);
session.setAttribute("Register", buylist);
session.setAttribute("Register", buylist);
None but the first line have an effect.
The other possibility is that the code has a bug and what really was meant was this:
Vector buylist = session.getAttribute("Register");
if( buylist == null ) {
buylist = new Vector();
session.setAttribute("Register", buylist);
}
i.e. create a new vector if it doesn't exist already.