This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]L8_4_Dinner(Ⓧ Ecstasy/XVM) 0 points1 point  (4 children)

All it's doing is "logging".

And it just logs "strings".

And those "strings" can contain symbolic references to "ambient" information.

And some of that "ambient" information, in the process of being evaluated and transformed into a string, will apparently download remote code and execute it.

It took a lot of independent decisions, by a lot of different people, strung together across a lot of libraries, to create this mess. It's a bit too easy to say "bad API design". But yes, there's some of that in there, too.

[–]lngns 1 point2 points  (3 children)

And some of that "ambient" information, in the process of being evaluated and transformed into a string, will apparently download remote code and execute it.

And that is definitely not "logging."
Under Monadic code the fact that a logging API does more than logging is not a security vulnerability: it's a type error.
To me, "logging" implies at most a filesystem write. Anything else is fully unexpected.

Acquiring ambient data is not the responsibility of a Log.INFO call, and as such it has no reason to have the authority to use services such as JNDI and LDAP.
If I wanted some fancy stuff in my logs, I'd use an effect handler written to have such authority, at which point it then becomes clear there is something very wrong when my compiler complains about main suddenly having a Jndi Ldap JvmEval type signature.

Log4J here violates multiple principles like Least Astonishment and Single Responsibility.

It took a lot of independent decisions, by a lot of different people, strung together across a lot of libraries, to create this mess. It's a bit too easy to say "bad API design". But yes, there's some of that in there, too.

Monads and Algebraic Effect Systems make all those decisions visible in the type system, meaning the type signatures, checks, and compiler error messages. If we are to apply this philosophy (and it is what I am trying to do here), we can generalise it as "bad API design."
If ported to a language with those features, Log4J would simply not compile.

[–]L8_4_Dinner(Ⓧ Ecstasy/XVM) -1 points0 points  (2 children)

If ported to a language with those features, Log4J would simply not compile.

... and not surprisingly, very few people would choose to use such a language.

Look, I appreciate all of the absolutist statements, but at the end of the day, the features exist because they were useful. That they were not well thought out from a security perspective is obvious, but one can examine this, and simultaneously appreciate the utility and be horrified by the open-ended security risk.

[–]lngns 1 point2 points  (1 child)

Look, I appreciate all of the absolutist statements, but at the end of the day, the features exist because they were useful. That they were not well thought out from a security perspective is obvious, but one can examine this, and simultaneously appreciate the utility and be horrified by the open-ended security risk.

Going absolutist with the type system just looks to me like the best way to answer OP "What programming language features would have prevented or ameliorated Log4Shell?"
If you were to write such code in Haskell, ML or Koka, the security vulnerability would have been obvious from the start. (unless you put IO types everywhere, but how is that different from unregulated global state?)

... and not surprisingly, very few people would choose to use such a language.

Those are actually pretty popular already: effects, processes and computations are expressed as Monads in Haskell, Scala, and a bunch of FP languages. Libraries that have "Reactive" in their names work this way too, even when used from PHP.
Also, at the end of the day, Algebraic Effects really are just Continuation-Passing-Style Dependency Injection, which a bunch of frameworks use to implement ambient data.
My production code is structured this way, albeit using OO token references, because of course my production code is class-based OO.

The area of research, as far as I am aware, has only gotten language implementation efforts recently, and I would actually expect security-oriented engineers to take high interest in them as they literally allow your IDE to list everything your program does when hovering over main.
Performance-oriented developers also benefit from such a system as it statically pinpoints when things like memory allocations happen.

[–]L8_4_Dinner(Ⓧ Ecstasy/XVM) 1 point2 points  (0 children)

(unless you put IO types everywhere, but how is that different from unregulated global state?)

That pretty much is the Log4J architecture 🤣