I am trying to improve our code security. We use a static code analysis tool named CheckMarx. The tool is new at the company, in particular we are the only team to work on iOS with objective C.
I have a parameter class to connect to a server, it contains server address, port, few parameters, login and password
The password should not be taped by user but. It is retrieved as a token from another strong authentication service each time needed. It should not be saved as persistant value (because it change every time), so keychain do not looks to answer my need.
For the demo project, the user will tap it in a textField. That demo projet is under security validation.
When running the analysis, I get a 'heap inspection' vulnerability :
https://cwe.mitre.org/data/definitions/244.html about the password. In theory i understand the problem I should clear the memory space where the password was stored, but I have no idea to achieve this, in objective C.
The password is an NSString, which is immutable, so if i try to overwrite the NSString, I will only create a new string and let the old one somewhere in the heap. (And if I overwrite it anyway in dealloc method, i get another warning saying that hardcoded string is a bad practice for password).
renaming the variable into another dummy variable name like MyDummyPropThatContainsData
1) ARC will clear the pointer but i do not think it will clean up the heap. So i believe this is not a false positive. Am i wrong ?
2) I have try using a NSMutableString allocated with MAX_SIZE_PASSWORD. I use the setString method to set the variable (at the same place). I erase it in the dealloc method by calling setString method with a dummy value of exactly MAX_SIZE_PASSWORD. It removed the warning, is it a good practice ?
I am quite sure that this should be another warning saying that hardcoded string is a bad practice for password, but it is not detected. I suppose the bad practice remains ...
3) I have thought to use a char* so i would be able to memset it later, but it sounds bad to me. I am afraid that it could be a reliability and maintenance issue. Is this could solve my problem ? is it recommanded with ARC to manage myself allocation of char * everywhere I need to manage passwords ?
I have found nothing in objective C to prevent Heap Inspection vulnerabilities. Is there some common way to prevent that in objective C ?
Do you know some good points where to start ?
Any help appreciated !
One comment and also a recipe. In a system that supports either no swap or an encrypted swap, nil-ling out the data is mostly moot. The main remaining attack to discovering the password is directly attaching to the running app. I use the keychain modes to defend against this attack.
The goal is to erase the secret on the heap.
As I keep passwords in my keychain, they are returned as an NSData BLOB. This is key. You can then initialize an NSString with the BLOB's bytes and disallow the string from owning them (freeWhenDone: NO). While I cannot guarantee that NSString does not copy the data, it appears to be the case. (Make sure you do not specify an encoding that causes the NSString to have to recast the data. UTF-8 generally works fine.)
When you are done with the password NSString, release it. (Using ARC, set it to nil.)
Now the key to cleaning up the heap is to use the NSData routine to enumerate through each of its byte arrays, typically there is only one, and then set the bytes to NULL. If you prefer, you can bang in random bytes. You can now release the NSData BLOB.
Yes, this breaks all of the rules of mutability preservation. That is what unsafe pointer operations are for. They are unsafe. But you are also doing something in a specific place for a very good reason.
As this is a rather delicate operation, I hesitate to share code that implements the above algorithm. IMO, you need to be responsible for your own security hygiene.
If the above isn't clear, I'm happy to refine the answer further.
Related
It is hard to find a good heading for this, but i think my problem comes clear if i post a small code snipped:
SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM
instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM
My question is now, is the used RAM that was allocated at the first construction reused at the second construction? Or is the RAM of the first instance marked as unused for the garbage collector and the second construction is done with a completely new instance with a different portion of RAM?
If the first is true, what with this:
while(true) {
final SomeObject instance = SomeObject(importantParameter);
}
Will then, each time the while is repeated, the RAM be reused?
It's unspecified. The answer is a resounding "maybe".
The language specification never says what happens to unreachable objects, since it's unobservable to the program. (That's what being unreachable means).
In practice, the native Dart implementation uses a generational garbage collector.
The default behavior would be to allocate a new object in "new-space" and overwrite the reference to the previous object. That makes the previous object unreachable (as long as you haven't store other references to it), and it can therefore be garbage collected. If you really go through objects quickly, that will be cheap, since the unreachable object is completely ignored on the next new-space garbage collection.
Allocating a lot of short-lived objects still has an overhead since it causes new-space GC to happen more often, even if the individual objects don't themselves cost anything.
There is also a number of optimization that may change this behavior.
If your object is sufficiently simple and the compiler can see that no reference to it ever escapes, or is used in an identical check, or ... any other number of relevant restrictions, then it might "allocation sink" the object. That means it never actually allocates the object, it just stores the contents somewhere, perhaps even on the stack, and it also inlines the methods so they refer to the data directly instead of going through a this pointer.
In that case, your code may actually reuse the memory of the previous object, because the compiler recognizes that it can.
Do not try to predict whether an optimization like this happens. The requirements can change at any time. Just write code that is correct and not unnecessarily complex, then the compiler will do its best to optimize in all the ways that it can.
In short: is it fast/cheap? Does it make sense to store a value from NSUserDefaults in memory for faster access?
Longer: say, i have significant number of values to be stored and read from NSUserDefaults; with the need to access(read) those values frequently.
In the snippet below, i initialize a private stored property, and keep it synced with corresponding NSUserDefaults value - so when i need to read it, i read the property.
If reading from the defaults directly is in fact fast, i'd remove the private property, obviously. But i'm unsure of that. Is it fast?
private var _loggedIn = NSUserDefaults.standardUserDefaults().boolForKey("loggedIn")
public var loggedIn: Bool {
get {
return _loggedIn
}
set {
_loggedIn = newValue
NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: "loggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
Clarification for future readers: the question is about reading, not writing/synchronizing, which is (as pointed in the answers) not fast nor cheap.
.synchronize() is called in the setter for a valid reason - in my specific case it is important to have it synched right away, so i sacrifice performance for logic integrity. In general cases, you should consider whether you need to call it - or let the system pick appropriate time for writing.
..In fact, now that i look at it, i see keeping the stored property as it is in the snippet, will provide logic integrity (as long as access from other places happens via the getter, and not directly from userDefaults). So i can avoid synchronizing here as well.
Reading is cheap. There is a generous caching in place and everything happens in RAM. Mutating is relatively cheap, but the system will still have to store the contents to non-volatile memory (a .plist file on the flash) at regular intervals.
Explicit synchronising isn't cheap. It eats time and more energy.
So for reads it is fine, but with a lot of writes I would still do it in a separate container and serialise only as needed.
It's unlikely to have a significant performance impact, but you can profile that yourself using Instruments to ensure the performance impact is negligible.
I made some performance tests with Instruments as #mipadi has suggested the past year and my conclusion was there is no substantial difference.
As I pointed out in a comment above, it's very important to detect which of those NSUserDefaults writes we want to be done straightaway. Just in those particular cases use synchronize method, otherwise leave iOS to handle that work to obtain better performance.
It's all fine unless you use NSUserDefaults as a database. synchronize () will write the complete plist file, so if you store megabytes of data, and then synchronize a lot, performance and/or battery life will suffer.
But check out this question as well: How often are NSUserDefaults synchronised?
An interesting detail is that user defaults will be written when your application terminates. Someone might experiment what happens if your program crashes right after changing NSUserdefaults; if that counts as "termination".
Im constantly being given an error that reads *** -[NSKeyValueObservance retain]: message sent to deallocated instance 0x86c75f10. I have tried running the Zombies template and here is the screenshot of what it provides.
It points to a managedObject, and I'm having trouble figuring out where the object is being deallocated. Here is the block of code that the compiler takes me to after each crash.
- (void)setIsFavourite:(BOOL)isFavourite shouldPostToAnalytics:(BOOL)shouldPostToAnalytics;
{
// check whether we need to generate preferences objects just in time
if(!self.preferences && !self.series.preferences /*&& isFavourite*/)
{
if(self.series)
{
[self.series addPreferencesObject];
}
else
{
[self addPreferencesObject];
}
}
//Crash In here
self.preferences.isFavourite = #(isFavourite);
self.series.preferences.isFavourite = #(isFavourite);
EDIT: If you need to see a larger size of the image here is a larger resolution link.
OK, I hit something similar and found a way to debug this kind of issue with NSKeyValueObservance. To debug, do the following:
In Xcode, open the "Breakpoint Navigator".
Add a new symbolic breakpoint with:
-[NSKeyValueObservance _initWithObserver:property:options:context:originalObservable:]
To that breakpoint, add an action and set it to "Debugger Command".
Set the following command: expr (void)NSLog(#"observer <0x%p>: %# <%p>, property: %#", $arg1, (id)NSStringFromClass((id)[(id)$arg3 class]), $arg3, (id)$arg4)
Click the "Automatically continue after evaluating expression".
Now you can run your application and take the steps necessary to reproduce your crash. And yes, you'll want NSZombies enabled. Note: it's going to run slow and you're going to get a ton of debug output, but just be patient. It'll get there eventually.
When you hit the crash when trying to message a deallocated NSKeyValueObservance, you'll be presented with the address of the original object. Highlight the address and hit cmd-e to enter the text in the search buffer. Then hit cmd-g find the next occurrence of the string in the debugger output. You're going to potentially find the address a couple of times, so look for the address that follows the observer <0x?????> output. The output on that line should tell you what object is being observed and for which property.
In my case, when I figured this all out, it turned out that I was observing a synthesized property that depended on an object in array and during a certain operation, the order of the objects in the array changed without doing the correct KVO notifications, and that caused my crash.
Are you using manual reference counting? If so, why? Convert your app to ARC. Manual reference counting is painful at best, and ARC is much better.
I am an experienced iOS and Mac OS developer and can do either, but I far prefer ARC. It's much less fussy and error-prone.
There is a feature built into Xcode that will convert your project to ARC for you. You might have to do some cleanup afterwords, but it's worth it.
If you do that your problem will likely go away.
As to the specifics, your screenshot is far too small to be able to read it. You will need to post a full-sized image if you want somebody to try to figure out what's going on.
However, in broad terms it sounds to me like you have an autorelease bug.
in manual reference counted code, lots of system method return objects that are "autoreleased." That means that when you receive them their retain count is positive (usually 1) so they stick around. However, they have been added to the "autorelease pool," which means that they are going to be released on the next pass through the event loop if nobody retains them first.
When you receive an autoreleased object you should either accept that it will be released once your current method returns, or retain it.
If you are trying to write Core Data code using manual reference counting and don't understand this then you are setting yourself up for failure.
Core Data is pretty complex, and you should have a solid understanding of Cocoa memory management before attempting to write a program that uses it, especially if you're using manual reference counting.
I have a need to ensure the user-inputed string in a UITextField is cleared from memory immediately after it has been used. If I set field.text = #"" or nil and let it go out of scope it should ge gone but I am not sure if it is guaranteed to be released immediately and even if it is, I dont think the OS actually clears the data, it seems likely it is just marked as unused and the data in it is still there until overwritten by something else.
The .text property of the field is a normal NSString and I have looked around for ways to get a useable pointer to its contents using the various CFString / CString methods but none of them work. For example CFStringGetCharactersPtr and CFStringGetCStringPtr both either return const-pointers which cant be written to, or often NULL (the docs say it may return null "if the internal storage of the String does not allow this to be returned efficiently") and from my testing it always returns NULL.
Is there anyway to do this?
answering my own question to be clear:
I got a reply from an apple employee at the devforums and he confirms it is pretty much impossible. His suggestion was to do everything yourself based on UITextInput and not use NSString or UITextField at all.
with MBaas services getting really affordable, and easy to use, I was wondering if anyone could give me an advice on the following design choice ?
Context: Send the content of an NSDictionary for remote storage. So the idea is to build a key/value relation, on the fly.
How:
using the piece of code here, it is possible to retrieve the name of an instance variable. so, the key/value relation results from [{ivar_name ="the value I'm interested in from this ivar"}, etc.... ]
I understand the limitations of the proposed code, but I think they are outweighed by the benefits.
In my case, the dictionary will not live beyond the class life-cycle, so I should not keep strong references on ivars, when the View is removed from the stack. Furthermore, it's going to be NSString taken from TextFields.
However, there is one question I can't really answer: if the ivars I'm looking at are part of reusable UITableViewCells (ex: IBOutlet textField in a UItableviewCell), should I make a copy of the textField.text or can I keep a reference on the string pointed at by textField.text? or it doesn't matter?
Thanks !