May 02

On Wednesday, 1 May 2024 at 23:24:01 UTC, NotYouAgain wrote:

>

On Wednesday, 1 May 2024 at 14:33:42 UTC, Steven Schveighoffer wrote:

>

..
...
I don't see how public by default affects memory safety.

I don't recall claiming it was related to memory safety. It is cleary not.

The word safe surely does not only apply to memory safety, now does it.

As far as D is trying to be "safe by default", this is in the context of memory safety only.

>

Most breaches that have affected me, personally, have been API breaches.

https://nordicapis.com/8-significant-api-breaches-of-recent-years/

I can't see how a language can stop people from not exposing API they didn't intend to expose.

Just the top one on the list:

"With the Optus API beach, attackers discovered a publicly exposed endpoint that didn’t require authentication."

How is D possibly going to enforce that certain API routes on a high-level framework have framework-specific authentication enabled?

-Steve

May 01
On Wednesday, May 1, 2024 5:52:30 AM MDT NotYouAgain via Digitalmars-d wrote:
> No doubt this will create controversy too.. why.. I don't know... but anyway....
>
> Declarations within a D module (other than import declarations)
> are public by default.
> This includes public by default in a class too btw.
>
> Programmers from many of the other major languages will have to deal with this surprise (in addition to the surprise of how private has taken on a completely new meaning in D).
>
> Not discussing private here! We all know what will happen if we do. So don't!
>
> Question 1 - is 'public by default' a sensible default for a language that is aiming to be safe by default?
>
> Here's an interesting article relating to Kotlin, where I believe public is also the default. It kinda sets the stage....
>
> https://discuss.kotlinlang.org/t/kotlins-default-visibility-should-be-intern al/1400
>
> Question 2 - if public is not a sensible default for a language that is aiming to be safe by default, is it too late to change it?
>
> Question 3 - if a change was made, what would become the new default?
>
> Please be respectful in your comments, if you have anything to say.

For the most part, public and private really don't have anything to do with @safe or memory safety. The primary exception would be when an @safe / @trusted public API is being presented, but the internals are doing @system stuff that has to be @trusted.

In such cases, if symbols are accidentally left public rather than private, then @trusted code could be making assumptions that are not valid if any external code accesses the symbols which were supposed to be private. But even then, anything @system which is done with those private symbols will be treated as @system, so the @safety system will prevent you from doing anything that isn't memory safe with those symbols. It's just that if @trusted functions make assumptions about the state of the symbols which are not necessarily valid if external code has access to those members, then @trusted would be treating stuff as @safe when it shouldn't, which could lead to memory safety problems.

So, in a case such as that, having a symbol accidentally marked as public could create @safety issues, but for the vast majority of code, it won't, and so @safety and symbol visibility are largely orthogonal concerns (just not 100% orthogonal).

Rather, I'd say that the bigger problem with public by default is simply that it makes it easier to have symbols that were supposed to be private end up in your public API. Then you can end up in a situation where something that you thought was private is being used by external code somewhere, and when you make a change that should only affect your code's internals, it could break user code.

So, there's definitely an argument to be had that private by default would be better, because then you have a lower risk of accidentally having symbols be part of your public API when you didn't intend for them to be. However, at the same time, it's quite trivial to just slap

private:

at the top of the module if that's a concern. And there are a number of folks who would argue that all symbols should be explicitly marked with public or private anyway (which I'm not a big fan of, but it does work better with maintainability and code reviews when the attributes affecting a symbol are directly on the symbol rather than somewhere else in the file).

Also, it's far more problematic to use

public:

because it will also affect imports, and you don't want to accidentally make imports public. So, having private as the default could lead to more issues with imports, because folks who wanted public on most of their symbols but didn't want to mark them individually would likely be inclined to put

public:

at the top of their module and would then likely run into problems as a result, whereas slapping

private:

at the top of the module isn't error-prone in the same way.

In many respects, I am inclined to think that it would be better for private to be the default (at least as long as public: is changed to not affect imports), but at the same time, in my experience, it's pretty rare that symbols end up being public when they weren't supposed to be, and even when they do, since they're undocumented, it's usually only a problem if someone goes spelunking in the code and starts using undocumented stuff that's public.

Ultimately both public by default and private by default work just fine, and the issues that you get with one or the other usually aren't a big deal. So, I don't think that it's all that big a deal which one a language goes with.

And if we wanted to be particularly concerned about it, then arguably, the correct solution would be to just require that visibility attributes be directly on the symbols to fix the problem, which would be annoying in some cases, but mass-applying attributes often has a tendency to cause problems, and public: in particular can be pretty bad because of how it affects imports.

- Jonathan M Davis



May 02
On Thursday, 2 May 2024 at 00:27:40 UTC, Steven Schveighoffer wrote:
> ..
> ...

Either I accidently made by agrument absurd, or you are intentionally redirecting my argument to make it sound absurd?

I was of course referring to API's in the sense the 'safety' extends to more than just memory safety. I'm sure you would agree here.

In any case, the abstract notion of safety was the inherent topic for this discussion, not memory safety.

So referring back to the Subject: "Is public by default an unsafe default?"

I'd have to say yes, it is, because the surface for accidents (and attacks) is bigger than what it would otherwise have been.

What are my chances of hacking an API that was accidently private (because that was the default)? I'd say my chances decrease. They surely don't increase.

What are my chances of accidently using a private implementation property/method, when the implementation is all 'public by default'. I'd say my chances certainly increase. They surely don't decrease.

A few posts ago someone mentioned liking to program in a language because it was public by default. But liking or not liking, is not related to safe or unsafe.

I don't like locking all my windows and doors.

I'd like to leave them open.

In the past, I actually often forget to do just that (in a place I no longer live in). The consequences? I got broken into 6 times (although not really broken into, since they just climbed in through an open window).

I'd say private by default has the same advantages (and disadvantages) of locked by default. But I still prefer the minor inconvenience of private by default.

I was pleasantly surprised that you can in fact take some control over this in D.

So I encourage more D programmers to do just that.


module m;
@safe:
private:

....

May 02
On Thursday, 2 May 2024 at 00:30:44 UTC, Jonathan M Davis wrote:
> ... However, at the same time, it's quite trivial to just slap
>
> private:
>
> at the top of the module if that's a concern.

Yes, had I known that I likely would not have created this thread ;-)

Still, i guess it's highlight that option as being available, for those who (like me) did not know.

I encourage people to use it more often - if you can 'remember' to do that.

I cannot recall the last time I forgot to lock my car when leaving it, but I expect it will happen one day, and 'hopefully' nobody will know till I get back to it.
May 02
On Wednesday, 1 May 2024 at 23:24:01 UTC, NotYouAgain wrote:
> On Wednesday, 1 May 2024 at 14:33:42 UTC, Steven Schveighoffer wrote:
>> ..
>> ...
>> I don't see how public by default affects memory safety.
>>
>> -Steve
>
> I don't recall claiming it was related to memory safety. It is cleary not.
>
At least in D @safe is only about memory safety - and even that is not the default :-/
May 02
On Wednesday, 1 May 2024 at 11:52:30 UTC, NotYouAgain wrote:
>
> Question 1 - is 'public by default' a sensible default for a language that is aiming to be safe by default?

It's sensible - that's how C works after all. But it probably isn't optimal. Ideally `private` would be the default in my view.

> Question 2 - if public is not a sensible default for a language that is aiming to be safe by default, is it too late to change it?

Well, since we're going to have editions it could be changed easier than otherwise. But still, it's probably not worth it. It's still a good deal of migration work for those with lots of old code, over what's more a matter of taste than an universally agreed pain point.

> Question 3 - if a change was made, what would become the new default?

The (present module-level) `private` visibility attribute I guess.


May 02
On 5/2/24 13:01, Dukc wrote:
> On Wednesday, 1 May 2024 at 11:52:30 UTC, NotYouAgain wrote:
>>
>> Question 1 - is 'public by default' a sensible default for a language that is aiming to be safe by default?
> 
> It's sensible - that's how C works after all.

Arguably it is a bit more complicated in C. You would usually explicitly include a declaration in a header file to make symbols of a library visible to users. "Private" symbols would just not appear in the header file, and I think not including something in a header file is the default option. (Of course, there is no protection against other code making a declaration manually, but I think technically even in D you can access private symbols over their mangled name.)
May 02
On Thursday, 2 May 2024 at 11:45:57 UTC, Timon Gehr wrote:
>> It's sensible - that's how C works after all.
>
> Of course, there is no protection against other code making a declaration manually, but I think technically even in D you can access private symbols over their mangled name.

I think that would, or could fail to work because the compiler does not necessarily add the private symbol to the export table of an object file. The linker would then fail to find it.
May 02

On Thursday, 2 May 2024 at 08:05:32 UTC, NotYouAgain wrote:

>

I was of course referring to API's in the sense the 'safety' extends to more than just memory safety. I'm sure you would agree here.

In any case, the abstract notion of safety was the inherent topic for this discussion, not memory safety.

So referring back to the Subject: "Is public by default an unsafe default?"

No.

>

I'd have to say yes, it is, because the surface for accidents (and attacks) is bigger than what it would otherwise have been.

For attacks definitely not.

There is nothing that a systems level programming language can do to prevent a creative programmer from accessing the private parts of an API (we are not talking about web APIs). Just mirror the data definition with the private keyword removed, and cast the instance to the new definition. With D's introspection capabilities it is even easier than that.

So accessibility attributes have nothing to do with security, they are simply a means to manage binary compatibility between different releases of a library and as an aid to reason about code (assuming you have no one in your team doing tricks like the above).

Believing that accessibility attributes have any significance regarding security is dangerous.

-- Bastiaan.

May 02

On Thursday, 2 May 2024 at 17:22:25 UTC, Bastiaan Veelo wrote:

>

There is nothing that a systems level programming language can do to prevent a creative programmer from accessing the private parts of an API (we are not talking about web APIs). Just mirror the data definition with the private keyword removed, and cast the instance to the new definition. With D's introspection capabilities it is even easier than that.

Imho, it's more about protecting from sloppy misuse of api not intended to be public from the get go, and lazyiness in properly setting private to declarations on a module, not malicious reverse engineering.