Per and I discussed the recent string clearing changes and think that most of them should be rolled back. Having clear on exit set on all random strings, random seeds and all decrypted data is often not needed. Having the flag propagade through string operations is probably also not desired in the general case.
I think your point is valid. Setting the flag is probably unecessarily cautious for the places you mentioned. I think for passwords and keys it should still be set.
If we assume that its rarely being set, I think there is a good reason for propagating it in string operations. Otherwise, it seems difficult to use it in practice, since its often impossible to make sure all intermediate values are being flagged.
On Wed, 14 Aug 2013, Martin Nilsson (Opera Mini - AFK!) @ Pike (-) developers forum wrote:
So, no one against reverting then.
If we assume that its rarely being set, I think there is a good reason for propagating it in string operations. Otherwise, it seems difficult to use it in practice, since its often impossible to make sure all intermediate values are being flagged.
The major issue with this is that pike have shared strings (and this, incidentally, makes the whole concept of 'secure' strings rather odd, they should have been a separate class entirely).
Let's say that you set the 'password' that users enter as secure. Given how people select passwords you will soon have most strings marked as secure, especially if the flag is propagated through string operations (As an example, consider what happens after set_secure(""))
On Thu, Aug 15, 2013 at 03:40:01PM +0000, Per Hedbor () @ Pike (-) developers forum wrote:
The major issue with this is that pike have shared strings (and this, incidentally, makes the whole concept of 'secure' strings rather odd, they should have been a separate class entirely).
i thought that was the case, at least my impression from the discussion about it was that once a string was marked secure, it would no longer be shared.
certainly a simple string should not become secure just because its contents happens to be the same as another one somewhere else entirely that is secure.
what should happen is that if i add a secure string to a non-secure one, the new string should be secure too, and no-longer shared.
greetings, martin.
i thought that was the case, at least my impression from the discussion about it was that once a string was marked secure, it would no longer be shared.
No, that is not at all how it works. They are still just as shared as normal strings.
So it is indeed not really all that useful.
In a multi user system like a MUD or similar you can probe for passwords (if they are marked as secure) without logging in by just testing if a string you create is marked as secure or not.
Or use _next() to iterate through all strings allocated in the Pike process.
or reset a string a million times and measure the difference.
at which string size does clearing the memory become a performance problem?
how about reversing the whole operation, clear all strings by default and allow the developer to mark strings as unsecure where performance actually matters.
or clear all strings below a certain size whether they are secure or not. that would at least hinder some timing attacks.
it's a question whether the preference is for speed or security
is this an appropriate way to test this?
gauge{ int i=100000000; while(i){ string a = String.secure("this is a short string"); a = 0; i--; } };
(6) Result: 72.9443
gauge{ int i=100000000; while(i){ string a = "this is a short string"; a = 0; i--; } };
(7) Result: 29.1452
greetings, martin.
Yes. And, at no time should anything but performance be prioritized for the basic types, in my opinion.
actually, it was a good way to measure the impact of securing a string, but not suficient to find out if a string is secure:
string a = String.secure("this is a short string"); gauge{ int i=100000000; while(i){ string b = "this is a short string"; b = 0; i--; } }; Result: 29.1494
this shows that setting a new string to the same value as a secure string doesn't make it secure.
it needs more cleverness.
but any trick like: string a = String.secure("this is a short string"); gauge{ int i=10000000; while(i){ string b = a+"this is a short string"; b = 0; i--; } }; Result: 20.7256
or even: gauge{ int i=10000000; while(i){ string b = a; b = 0; i--; } }; Result: 6.72067
didn't give any difference in measurement compared to:
string c = "this is a short string"; gauge{ int i=10000000; while(i){ string b = c+"this is a short string"; b = 0; i--; } }; Result: 20.709 or gauge{ int i=10000000; while(i){ string b = c; b = 0; i--; } }; Result: 6.72388
not clever enough...
(i made the loop shorter to not have to wait so long for the results, but i think the effects are the same)
greetings, martin.
It makes a lot more sense to have a different string object for secure strings, that isn't shared. I'd like to see that. But only a small part of Pike and cmods would be able to use it, if someone doesn't come up with something clever.
(But if there were a way of making a more generic string object that Pike and modules understand - then it would have nice effects for transparent uses of data-on-disk, data-on-network or mmaped data.)
pike-devel@lists.lysator.liu.se