October 01, 2015
On 01-Oct-2015 11:46, John Colvin wrote:
> On Wednesday, 30 September 2015 at 17:59:41 UTC, H. S. Teoh wrote:
>> On Wed, Sep 30, 2015 at 04:14:59PM +0000, John Colvin via
>> Digitalmars-d wrote:
>>> On Wednesday, 30 September 2015 at 14:53:31 UTC, H. S. Teoh wrote:
>>> >On Wed, Sep 30, 2015 at 08:30:47AM +0200, Jacob Carlborg via
>>> >Digitalmars-d wrote:
>>> >>On 2015-09-29 23:32, Andrej Mitrovic via Digitalmars-d wrote:
>>> >>
>>> >>>If you have plaintext passwords stored anywhere you are
>>> >>>>already
>>> >>screwed. ;)
>>> >>
>>> >>The password always starts out in plaintext, or do you hash >>it in
>>> the front end, as the users types? Since the back end >>shouldn't
>>> trust the front end, it needs to hash it again.
>>> >[...]
>>> >
>>> >The right way to do it is for the server to send a random >challenge
>>> which the front end (presumably running on the >user's machine)
>>> encrypts with the password, sending the >ciphertext back to the
>>> server.  The plaintext password is >never sent over wire, yet the
>>> only way the client can provide >the correct response is if it knows
>>> the password to begin >with.
>>> >
>>> >
>>> >T
>>>
>>> right. Nonetheless, sometimes code does have to work with sensitive
>>> data and you don't want it to leak outside the program in unexpected
>>> ways.
>>
>> Certainly.  But I have a hard time imagining a scenario where I'd use
>> assert() on sensitive data.  After all, assert() should be used to
>> verify program *logic*, not the data that the program is processing.
>> That's clearly in the realm of enforce() or just plain ole if(), IMO.
>>
>>
>> T
>
> Checks involving sensitive data after processing can definitely be a
> check of program logic.
>
> Sensitive data enters program
> Sensitive data is checked using enforce
> Sensitive data is passed to another function, but something goes wrong
> (not enough checking before, wrong function called, HDD dies, someone
> trips over a network cable), an assert is triggered, the sensitive data
> spills to stderr.
>
> A perfectly correct program in perfect circumstances will never assert,
> but real programs in real situations will.
>

To be honest to save us from this we should simply ban printing to stdout/stderr because some debug statement may print sensitive data.

Come on, there are better way to protect sensitive data then crippling language primitives/compiler switches.

Lastly - ALL data in a PC's RAM is wide open to sysadmins so anything in sitting in RAM is vulnerable anyhow.

> At the very least there should be a compiler switch to turn
> assert-printing on/off


-- 
Dmitry Olshansky
October 01, 2015
On Thursday, 1 October 2015 at 08:46:51 UTC, John Colvin wrote:
> Checks involving sensitive data after processing can definitely be a check of program logic.
>
> Sensitive data enters program
> Sensitive data is checked using enforce
> Sensitive data is passed to another function, but something goes wrong (not enough checking before, wrong function called, HDD dies, someone trips over a network cable), an assert is triggered, the sensitive data spills to stderr.
>
> A perfectly correct program in perfect circumstances will never assert, but real programs in real situations will.

In almost all cases, printing out an assertion is by far the best thing to do, and in general, the more information that's printed, the better. But if anyone is dealing with sensitive data, they _have_ to be smart about what they do with it, and if that means that they can't put it an assertion directly, because assertions print too much information, then so be it. We're talking about a minority case where almost every other program would benefit. Most programs don't even have assertions turned on in release, which is where this would matter.

If a failed assertion could print out sensitive information, then just don't put the information directly in the assertion. Heck, anyone paranoid enough about it could create a special secureAssert function or something that did something like

void secureAssert(E)(lazy E expression,
                     lazy string msg,
                     string file = __FILE__,
                     size_T line = __LINE__)
{
    version(assert)
    {
        immutable result = cast(bool)expression();
        if(!result)
            throw new AssertError(msg, file, line);
    }
}

I see no reason to make the debugging tools that we have worse because of fear of someone who's writing code that processes sensitive information. That code just needs to be written in a way that's not going to leak the information. As Dmitry points out, there are plenty of other ways for the information to be leaked. So, not improving assertions due to security concerns really isn't a valid approach IMHO.

Now, there are other reasons why we might not want to (e.g. if the performance were worse, you might not want to make assertions print additional information), but I think that it's far better for code that needs to be that secure to do its own thing than to hamper everyone over the concerns of the minority.

> At the very least there should be a compiler switch to turn assert-printing on/off

I expect that most folks who would want to avoid have assertions printing out sensitive information would still want assertions that didn't relate to sensitive information to print. A compiler switch is a pretty blunt instrument, especially when someone could write their own code which asserts without showing any sensitive information while still testing that information.

- Jonathan M Davis
October 01, 2015
On Thursday, 1 October 2015 at 09:59:41 UTC, Jonathan M Davis wrote:
> In almost all cases, printing out an assertion is by far the best thing to do, and in general, the more information that's printed, the better. But if anyone is dealing with sensitive data, they _have_ to be smart about what they do with it, and if that means that they can't put it an assertion directly, because assertions print too much information, then so be it. We're talking about a minority case where almost every other program would benefit. Most programs don't even have assertions turned on in release, which is where this would matter.
>
> If a failed assertion could print out sensitive information, then just don't put the information directly in the assertion. Heck, anyone paranoid enough about it could create a special secureAssert function or something that did something like
>
> void secureAssert(E)(lazy E expression,
>                      lazy string msg,
>                      string file = __FILE__,
>                      size_T line = __LINE__)
> {
>     version(assert)
>     {
>         immutable result = cast(bool)expression();
>         if(!result)
>             throw new AssertError(msg, file, line);
>     }
> }
>
> I see no reason to make the debugging tools that we have worse because of fear of someone who's writing code that processes sensitive information. That code just needs to be written in a way that's not going to leak the information. As Dmitry points out, there are plenty of other ways for the information to be leaked. So, not improving assertions due to security concerns really isn't a valid approach IMHO.
>
> Now, there are other reasons why we might not want to (e.g. if the performance were worse, you might not want to make assertions print additional information), but I think that it's far better for code that needs to be that secure to do its own thing than to hamper everyone over the concerns of the minority.
>
>> At the very least there should be a compiler switch to turn assert-printing on/off
>
> I expect that most folks who would want to avoid have assertions printing out sensitive information would still want assertions that didn't relate to sensitive information to print. A compiler switch is a pretty blunt instrument, especially when someone could write their own code which asserts without showing any sensitive information while still testing that information.
>
> - Jonathan M Davis

All reasonable points, so I guess it's not such a bad thing after all. I just wanted to be sure that security was considered here.
October 01, 2015
On Tuesday, 29 September 2015 at 21:02:42 UTC, Nordlöw wrote:
> As a follow-up to
>
> https://github.com/D-Programming-Language/phobos/pull/3207#issuecomment-144073495

I added a long comment about a new more flexible solution to this problem:

https://github.com/D-Programming-Language/phobos/pull/3207#issuecomment-144701371
October 01, 2015
On 10/01/2015 04:46 AM, John Colvin wrote:
> Checks involving sensitive data after processing can definitely be a
> check of program logic.
>
> Sensitive data enters program
> Sensitive data is checked using enforce
> Sensitive data is passed to another function, but something goes wrong
> (not enough checking before, wrong function called, HDD dies, someone
> trips over a network cable), an assert is triggered, the sensitive data
> spills to stderr.

I think worrying about this would be an exaggeration.

> At the very least there should be a compiler switch to turn
> assert-printing on/off

Please, no. Keep it simple and automatic. Zero-work improvement for the client.

Printing good messages in assertions is a good idea. For most ideas of sufficient complexity, situations can be imagined in which there are disadvantages. It has happened before in our community that good ideas didn't get worked on because a few folks dwelt on the disadvantages with too much vividness.

Whoever wants to work on better assert expression printing: make sure you specify which grammar constructs are supported, and how the parts involved are printed. Expressing semantics via lowering would be great. Write a DIP, discuss, implement. I'll have your six.


Andrei
October 01, 2015
On Tuesday, 29 September 2015 at 21:26:00 UTC, John Colvin wrote:
> Not necessarily. It could just be a defensive assert for something that should already have been verified/cleaned/caught earlier.
>
> auto pass = getPassword();
> pass.clean();
> assert(pass == pass.toLower());
> //and on we go ...

There are a few flaws with this:
First, your assert applies only in debug mode. You're likely not deploying your service in debug mode, so your attempt at defensive programming does nothing to protect you when you actually need it.

Second, and more critical, the way assert is apparently intended to be, is a guarantee that can be used towards optimization. The existence of an assert means that that situation can *never* happen. You take your existing code, and then later on you decide that an assert isn't enough so you add another check for release mode. In which case (as far as I understand it), you run into the following situation:

auto pass = getPassword();
pass.clean();
assert(pass == pass.toLower());
// Later on...
enforce(pass == pass.toLower());

Now not only is your assert not triggered because you're in release mode, but that assert provides a guarantee to the compiler that pass is *always* equal to pass.toLower, causing the compiler to optimize out that enforce call as it's redundant. Therefore, your assert does nothing, and your enforce now does nothing as well, masking a potential vulnerability.
October 01, 2015
On Thursday, 1 October 2015 at 14:37:55 UTC, Andrei Alexandrescu wrote:
> Whoever wants to work on better assert expression printing: make sure you specify which grammar constructs are supported, and how the parts involved are printed. Expressing semantics via lowering would be great. Write a DIP, discuss, implement. I'll have your six.

I registered a user named `nordlow` at the D Wiki but I can't find a way to write a DIP.

Help please.

October 01, 2015
On Thursday, 1 October 2015 at 16:35:51 UTC, Per Nordlöw wrote:
> Help please.

I figured it out.
October 01, 2015
On Thursday, 1 October 2015 at 14:37:55 UTC, Andrei Alexandrescu wrote:
> Whoever wants to work on better assert expression printing: make sure you specify which grammar constructs are supported, and how the parts involved are printed. Expressing semantics via lowering would be great. Write a DIP, discuss, implement. I'll have your six.
>
>
> Andrei

A first version:

http://wiki.dlang.org/DIP83
October 01, 2015
On Thursday, 1 October 2015 at 17:19:39 UTC, Per Nordlöw wrote:
> A first version:
>
> http://wiki.dlang.org/DIP83

Looks good! But I lack the knowledge to comment on the implementation details for the compiler mentioned in the DIP.

Bikesheading: could you change "being" in "([1,2,3][2] being 3) != ([1,2,4][2] being 4)" and the other examples to "is"? Using "is" is much more natural sounding English.