But the issue here was not the command line. It was not handling the interface properly. Somebody wrote a 5 minute hack to handle security functionality and probably didn't even read the application source to look for proper use, much less version checking. The same thing happens with APIs.
And null terminated strings have worked for 40 years, that doesn't have anything to do with this.
Unless you've got a password type and a regular string type, how's the compiler to know you've swapped the password with a config string?
Joel on Software wrote an interesting article that's related to this, oddly about Hungarian notation.
His point was that *lwistrp = "foo" tells you meaningless stuff (lwip and str) about your data. That's what the compiler is supposed to track. But 'u_pw' and 's_pw' (unsafe/safe) for pre and post-processed user-input tells you something meaningful the compiler has a harder time tracking. (Not impossible with taint-tracking, but ...)
The relevance is that types tend to be based on the implementation details instead of the higher-level facts. For this sort of function to be actually safe, not just compiler-safe, it would need higher-level types and to be compiled into your language (not called via an opaque FFI) to check them.
It's not THAT bad. That's why everybody is still using it. But there are many better options, since the CLI, eg. people have created distributable libraries, and network APIs. Yet, changing APIs will break any of them.
A library, with an exposed pubic API that a compiler will, y'know, refuse to compile against when the expected arguments to a call you depend on are completely changed?
Depending on blind CLI calls that silently fail is about the least safe option possible.
The right thing IMHO would be to use pipes & stdin/stdout/stderr, but with a well-defined machine interface.
What you need is a kernel that exposes programs as a file system like plan9
Powershell?
- Request-reply -- Acknowledge stuff. Especially when it's security relevant
- For security relevant stuff, don't just silently fail or fall back to some idiot default. Eg. say a command message for setting a password doesn't contain the password field -- then fail the request, don't assume an empty password.
(Ie. be liberal about what you accept but not too liberal)
It isn't difficult to be strict so being liberal is just asking for trouble uselessly.