Is private really private?

I always thought privacy/encapsulation was more about upholding invariants and/or abstraction barriers than literally hiding the contained data from all possible inspection. Like, the capacity field of a Vec is private because letting the user modify it in an uncontrolled fashion would break the invariants that Vec's api is supposed to uphold.

6 Likes

The only way to access "private" data is by scraping data, so clearly items in rust that say they are private are really and truly private.

if there are zero language supported means to access private data, then that is as private as it can possibly get (no other language could even pretend to guarantee more without cripling it's ability to write programs at all).

1 Like

Pointer2Void,

As a few others have pointed out, your goal is unattainable in the vast majority of programming languages. However, it seems that you might have some simple, low-level misunderstanding underlying your question. So I'm going to try to address the topic from a few angles - I hope you find it helpful.

I'll use API in the same way you used it - to refer to the interface of a native library. But note that it does also refer to, for example, web APIs, which are very different, and I'll talk about that.

So in Rust is private really and truly private? In other words, is a private member, not running in some debug mode, absolutely inaccessible from the "outside" (for lack of a better term)?

It sounds to me like you're concerned with system security. Like, actual security - as in you REALLY want to keep your users out of your implementation, like there's a secret key in there or something. The concept of "privacy" in APIs has absolutely nothing to do with security. There are almost no systems languages that guarantee any kind of security between multiple components of a single process program. There are sandboxed languages that live in single processes (e.g. JavaScript in a single threaded browser), but this is very different.

It's true if someone gets complete access to a box then I can't stop them from memory surfing but as an API writing that's the sys admins concern :smile:

I don't really understand what you mean by this. Remember - the users of your API are the ones who are executing the code. That means they are the sysadmin. There's no such thing as security of data you're working with on an untrusted machine. And if you're executing the code on a machine you trust, there is no way for you to securely run user-written code natively.

I can't really stop them from scraping memory but that's a system access concern not an API concern.

Users scraping memory is neither a system access concern nor an API concern, regardless of whether they're doing it from inside or outside of the process. It's the API user's concern. If they are scraping memory to access the internals of an API, they can't do anything worse than shoot themselves in the foot. Unless you store sensitive/secure/confidential data in private fields.

Strong? Work? :confused:
Assuming @Amanieu is correct all I have to do is create an unsafe code block and then I have C++ with a strange new syntax.

The point of using a language like Rust is that it's easier for application and library developers to write code without shooting themselves in the foot accidentally. In Rust, you're not allowed to shoot yourself in the foot without typing unsafe. Then you get to do whatever you want, and only the author of the unsafe code is at fault.

Finally, as tomaka said:

The only way to make some memory "private" is to put it in a separate process.

If you're really concerned about the security of some implementation of your API, you need the other kind of API - for example, a web API. This is a two system model:

  • Your server, which hosts only YOUR code, and exposes a small interface through which it allows certain queries and operations to be performed on its internal state (e.g., create user, change password, send message). API users can never see any of the internals of this - it's on an entirely separate system.
  • Their client, which hosts only THEIR code, and accesses your code through the API that you've defined.

This is the only way to achieve security. If you're careful about limiting access via sandboxing, these could even be two processes on the same system. But they have to be separate programs.

If you aren't actually concerned about security, then it sounds like you just don't trust your API users to write good code. In this case, I recommend you just let it go and let them unsafely shoot themselves in the foot however they want to. :stuck_out_tongue:

P.S.

There are languages for which you can have data that is truly private from other code. In JavaScript, for example:

/// Increments an internal counter and returns the next unique ID
var getNextID = (function() {
    var lastID = 0;
    return function() {
        lastID++;
        return lastID;
    };
})();

There's no way for other code to modify lastID, BUT: the users running the code can ALWAYS find a way to get at it - it's easy with a JavaScript debugger.

16 Likes

The only way to make some memory "private" is to put it in a separate process.

Actually, you need to be on a separate machine. You can read data in other processes if you really try.

4 Likes

In addition to other comments, I'd like to add a word of caution w r t automatically deriving Debug - the default will just output all fields. The API user could then just run format!("{:?}", object) and parse the result, without having to resort to unsafe memory reads.

3 Likes

I know this is an old thread, but I just wanted to point out that this isn't merely wrong, but dangerously wrong. "Privacy" may simply be misnamed, because its purpose is not and has never been related to security. Several posts above point out the technical details of why "private" data can't be assumed to be inaccessible to motivated attackers, but I think it's important to be as blunt as possible that "privacy" as a language construct does not and cannot accomplish the stated goals here.

3 Likes

A hard "yes" to the question of "are access modifiers formally binding?" would require accesses to pass through an out-of-process deputy, and likely that each private field - or at least each independent collection of private fields - live in its own process. And, even then, debugging tools like gdb and the underlying debug APIs would be able to access them "inappropriately."

Memory is memory, at least on modern architectures. If a value is present in a given process' memory, that process has unfettered access to the value. Formalisms around memory access - access modifiers, lifetimes, const correctness, and so on - are all cooperative protocols: programs that abide by the protocol gain extra guarantees; programs that break the protocol do not.

2 Likes

If you want local memory security, you need something like Intel SGX.

1 Like