News Log4Shell: Sicherheitslücke in log4j für Java hält die IT-Welt in Atem

Geht weiter… https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046
2.15.0 war nicht ausreichend und dieser spezielle Vektor ist durch noFormatMsgLookup auch nicht abgedeckt. Dürfte aber echt eine Ausnahme sein, wird aber z.B. von logstash genutzt. Die JNDI Klassen aus dem JAR zu entfernen gilt nach wie vor als 100% safe.
Wenn ich es richtig interpretiere (es ist schon spät), ist es hier aber „nur“ ein DoS und kein RCE und hat auch nur einen 3.7er CVSS Score.
 
  • Gefällt mir
Reaktionen: Piktogramm und Pankrat
foo_1337 schrieb:
Geht weiter… https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046
2.15.0 war nicht ausreichend und dieser spezielle Vektor ist durch noFormatMsgLookup auch nicht abgedeckt. Dürfte aber echt eine Ausnahme sein, wird aber z.B. von logstash genutzt. Die JNDI Klassen aus dem JAR zu entfernen gilt nach wie vor als 100% safe.
Wenn ich es richtig interpretiere (es ist schon spät), ist es hier aber „nur“ ein DoS und kein RCE und hat auch nur einen 3.7er CVSS Score.

Elastic hat darauf reagiert:

[Update Dec 14th] Log4j 2.16.0 has been released to address CVE-2021-45046. Logstash is not impacted by the vulnerability disclosed in CVE-2021-45046 because Logstash does not ship with logging layouts that can be exploited to trigger JNDI lookups through Thread Context references.

Ansonsten klingt das aber schon ein wenig danach:
When running on JDKs older than 8u191 and 11.0.1, an attacker is able to inject and execute a remote Java class. On recent JDKs the attack is limited to DoS - causing data ingestion to temporarily stop - and information leakage, but no remote code execution attack vectors are known.


Affected Versions:
Logstash versions 5.0.0+ up to and including 7.16.0 contain a vulnerable version of Log4j. The severity depends on the JDK used as stated above.


Docker images below version 6.4.3 include a JDK older than 8u191, which means they are open to Remote Code Execution. Images 6.4.3+ don't have known RCE attacks but are still susceptible to Denial of Service and information leaks.

Mit 7.16.1 hat Elastic überall den Holzhammer rausgeholt und sowohl noFormatMsgLookup als default konfiguriert, als auch JNDI-Klasse aus dem log4j-JAR entfernt.
 
ComputerJunge schrieb:
Das würde ich nur machen, wenn es keine(n) gäbe (*). Warum das Rad zum x-ten Male erfinden - das ist doch Sinn und Zweck von Frameworks und Libraries.
Stimmt schon, ich sehe das im Großen und Ganzen auch so. Wobei ich aktuell oft eher "Grundlagen" programmiere/entwickel aus Spaß und um neue Gedankengänge nachzuvollziehen.

Nur einen Logger schleppe ich quasi seit 15 Jahren mit mir, passe den immer etwas an, aber er macht genau das, was er soll, mit relativ wenigen Zeilen Code. Ich habe da aktuell 2 Interfaces und 5 Klasse mit ca. 1000 Zeilen Code inklusive Kommentare. Der reine Code kommt vielleicht auf 200 Zeilen und die kann man noch halbwegs formal auf Fehlerfreiheit, aber auch auf Sicherheit abklopfen.

Das Problem von Frameworks/Bibliotheken ist, dass man manchmal mit Kanonen auf Spatzen schießt und unnötige Komplexität schafft, die am Ende auch wieder Fehler und Lücken produzieren kann.

Genauso stimmt es aber auch, dass man nicht x-mal genau das Gleiche schreiben muss und es eigentlich genug gute Bibliotheken und Frameworks gibt. Das Problem nur an den meisten heute "gut" gepflegten Bibliotheken und Frameworks ist, dass sie so fett und komplex sind, dass sie zwar gut erprobt sind, aber man teilweise den ganzen Ballast mit sich schleppt.

ModellbahnerTT schrieb:
JAVA ist bereits öfter durch Sicherheitslücken aufgefallen.
Genauso wie viele anderen Sprachen, die nicht direkt kompiliert werden, sondern durch einen "Interpreter" ausgeführt werden - ja, ich weiß, dass es die Java Virtual Maschine ist, aber an der Stelle ist es einfacher für die Erklärung!

Egal ob jetzt Java, PHP, Phyton, JavaScript, Perl und Co: All diesen Sprachen gemein ist, dass im hinter Grund ein Interpreter läuft, der dann das eigentliche Programm ausführt. Bei Java wird ein Precompiler genutzt um den Bytecode für die JVM zu erstellen, die JVM ist dann der JIT (Just-In-Time-Compiler). JavaScript und andere Skriptsprachen ist halt ein Lexer und Preparser davor.

Und natürlich finden sich da auch Fehler, nur gleichzeitig darf man nicht vergessen, dass eine JVM, eine V8, SpiderMonkey, ZendEngine und Co gleichzeitig auch viele Fehler verhindern, die man als Entwickler so machen kann, gerade was das Memory-Managment angeht.

In C, C++ muss man zum Beispiel bis heute sehr genau darauf achten, wie man programmiert, da man sonst schneller ein Buffer-Overflow erzeugt, als einem lieb ist. Die ganzen Zeiger-Sachen sind alles andere als wirklich gut gelöst. Deswegen hat Rust ja zum Beispiel sehr klare Regeln im Compiler, was Referenzen, Variabel weitergab usw. angeht, damit so etwas nicht passiert.

Also: Ja, die JVM hat ihre Probleme, gleichzeitig verhindert sie aber auch viele Probleme.

foo_1337 schrieb:
Und es gab garantiert mehr f*ckups wegen miesem C/C++ code als welche aufgrund von Lücken in der JVM. Vieles was du in C oder C++ komplett vergeigen könntest, erlaubt Java erst gar nicht.
Deswegen schaue ich mir aktuell Rust an. Macht Spaß und der ganze Fuckup ist weg, außer man will ihn.

Man muss halt mit der Zeit einsehen: Fehler und Sicherheitslücken wird es immer geben und es wird keine perfekte Programmiersprache geben und auch kein perfektes Programm. Sobald man einen PC startet, kann es eine potentielle Lücke geben und deswegen gibt es mehrere Ebenen im Sicherheitskonzept.
 
  • Gefällt mir
Reaktionen: TechFunk, ComputerJunge und Snowi
DevPandi schrieb:
Das Problem von Frameworks/Bibliotheken ist, dass man manchmal mit Kanonen auf Spatzen schießt und unnötige Komplexität schafft, die am Ende auch wieder Fehler und Lücken produzieren kann.
So ist es leider, und oft genug wird auch nicht verglichen, sondern man nimmt irgendwas, was man ggf. schon kennt, oder was einfach einzubauen ist, aber 100k Zeilen mehr hat als das, was man braucht. Zudem sollte man auch immer im Kopf halten: Wie gut / schlecht kann ich diese Abhängigkeiten updaten? Denn im Idealfall sollte man das oft tun, damit man direkt jeden Patch mitnimmt, den es gibt. Sonst passiert das, was ich jetzt bei vielen mitkriege: "Wir sind nicht verwundbar, wir nutzen Log4J in Version 1.X". Super, dafür hast du aber eine andere CVE Sicherheitslücke mit in deiner 1er Version, weshalb jetzt trotzdem alle patchen müssen. Und jetzt muss man direkt prüfen, ob überhaupt noch alle alten Features drin sind, oder wie man das Problem sonst löst, wenn man nicht einfach patchen kann.
Sowas kann immer passieren, und deshalb sollte man da tierisch aufpassen, was man sich als Abhängigkeit reinholt. Das kann alles Sinn machen, und ich will da nichts schlecht reden, aber man braucht keine 5MB Library, wenn man letztlich nur 2-3 Funktionen nutzt, die man in ein paar Stunden auch selbst implementieren kann.

Wo Libraries praktisch immer Sinn machen, ist alles was mit Crypto und Passwortverwaltung angeht. Da gibt es so viele Fehler, die man machen kann, dass man lieber den Code von Leuten nimmt, die sich damit besser auskennen. Aber auch da gilt natürlich: Kann schief gehen, siehe Heartbleed & Co.
 
Das ist ok bei Hobbyprojekten. Ansonsten sollte man immer auf Industriestandards setzen und nicht irgend ein Problem lösen, dass andere schon 1000x gemacht haben. Logging gehört dazu.
Man sollte sich bei jedem Softwareprojekt verinnerlichen:
"Maximize the amount of code not written"
 
  • Gefällt mir
Reaktionen: mental.dIseASe
Zuletzt bearbeitet:
kodix schrieb:
log4j ist btw. maximal ein de-facto Standard und bei weitem kein Industriestandard. Logging ist ein File-Appender 10-Zeiler, das kann jedes Kind. Warum man dafür ein Framework benötigt, habe ich noch nie verstanden.
Um es mit deien Worten zu formulieren: Logging ist eben nicht nur ein File Appender. Nur weil dein Anspruch so niedrig ist, heißt das nicht, dass das generell so gilt.
Kleiner Hinweis hierzu:
https://github.com/openssh/openssh-portable/blob/master/log.c
und der dazugehörige header: https://github.com/openssh/openssh-portable/blob/master/log.h
Und hier wird auch noch bsd syslog von extern miteingebunden.
Das ist der Logging Code von OpenSSH. Also keine komplexen Logs, die geschrieben werden. Und eine "App", deren Code generell als sehr gut gilt.

Klar, irgendwas nach stdout/stderr rotzen und das dann in 2 verschiedene Files schreiben kann jeder. Aber das ist in der Regel nicht das was man unter Logging versteht.
 
Ich würde an der Stelle auch sagen, dass Logging kein einfacher 10zeiler ist, weil du ja meist mindestens nach Produktionslogging und Verboselogging unterscheiden willst. Produktion für den produktiven Betrieb, wie der Name sagt, und Verbose nur fürs Debuggen. Prinzipiell stimme ich aber dennoch zu, dass man oft kein Logging-Framework wie Log4J braucht, ein deutlich kleineres würde meist schon reichen. Java hat doch bestimmt auch eine eigene Implementation, warum nutzt man die nicht einfach, wenn man keine höheren Ansprüche hat? Oder gibt es da nix?
 
Ich bin sicher kein Experte aber ich glaube der Muster Weg wäre eigentlich http://www.slf4j.org/manual.html#swapping zu nutzen wenn man mehr als nur einfaches Logging benötigt.
So kann dann die Hauptsoftware selbst entscheiden ob und was zum Logging genutzt werden soll.
Und das nicht einfach irgendwo als harte Abhängigkeit einbinden.
 
kodix schrieb:
Da steht am Ende:
Aber so ist es. Weniger Code ist besserer Code. Am besten so wenig Code, dass man ihn zur Gänze und mit all seinen Interaktionen verstehen kann. Und auch den Code, der notwendig ist, um den eigenen Code zu betreiben.

Der Rest ist sehr voreingenommen und nicht Ernst zu nehmen und ohne Bezug zu jeglicher Realitaet.

Logging ist ein File-Appender 10-Zeiler, das kann jedes Kind. Warum man dafür ein Framework benötigt, habe ich noch nie verstanden.
Aha. Der Code lauft in irgend einem Pod im Kubernetes-Cluster. Und wie landen deine Logs in Elastic/Kibana? Was, wenn du im JSON-Format loggen willst? Wie macht du Log-Analysen? Mit tail und grep ueber 50 Logfiles?
Haettest du gesagt, Logging macht man nach stdout und stderr und saugt das dann mit Filebeat auf, dann haett ich es ja noch gegessen, aber File-Logging ins Dateisystem ist was aus dem letzen Jahrtausend. Das macht man nicht.
 
  • Gefällt mir
Reaktionen: foo_1337 und nospherato
SheepShaver schrieb:
Das ist ok bei Hobbyprojekten. Ansonsten sollte man immer auf Industriestandards setzen und nicht irgend ein Problem lösen, dass andere schon 1000x gemacht haben.
Grundsätzlich ja. Wenn jemand ohne Ahnung von der Materie einfach mal OpenSSL nachprogrammiert, dann ist die Gefahr groß, dass er Mist baut. Und ja, logging ist nicht nur File-Appending. Die Frage ist aber, in welchen Fällen ein Logger mit dem Umfang von log4j nötig ist. In den meisten Fällen reicht wahrscheinlich doch etwas deutlich einfacheres, auch wenn es ein bisschen mehr tun soll, als Strings nach stderr zu schicken.
SheepShaver schrieb:
Der Rest ist sehr voreingenommen und nicht Ernst zu nehmen und ohne Bezug zu jeglicher Realitaet.
Der Text ist ein bisschen zynisch und polemisch geschrieben, inhaltlich sollte man sich aber schon damit auseinandersetzen, denke ich. Log4j bringt eine Komplexität mit, die die meisten, die es verwenden, scheinbar nicht mal ansatzweise überblicken. Die leichtfertige Einbindung von externem Code in eigene Projekte, teilweise erst zur Laufzeit, ist fehleranfällig und die nötigen Schnittstellen sind teilweise eben gefährlich, wenn sie nicht mit Bedacht verwendet werden. Da hat er meiner Meinung nach vollkommen recht und da muss man sich auch ehrlich Fragen, ob nicht schon das Design von JNDI problematisch ist. Natürlich ist es polemisch zu behaupten, einfach JSON nach stderr ballern täte es auch und log4j wäre überflüssig.
 
SheepShaver schrieb:
Der Code lauft in irgend einem Pod im Kubernetes-Cluster

Mein Beileid ;) Nein, ernsthaft: Mein Beitrag war in der Tat etwas polemisch und ja klar, einfach auf stderr ballern ist nicht die Lösung. Vieles sollte man in der Tat nicht selbst entwickeln, habe ich auch so gelernt. Der Ansatz der letzten Jahre vor Allem bei Java geht allerdings deutlich in die falsche Richtung und genau das wird im heise Artikel sehr treffend angesprochen.
 
Naja, doch, da stimme ich ihm zu. Lieber nach stdout/stderr ballern als stumpf in ein File (außer das file ist /dev/std(out|err) ;) ). Letzteres hilft in der Regel niemandem. Stderr/stdout kann ich im Container/k8s kontext sehr gut einsammeln/weiterverarbeiten. Wenn du in einem Container in ein File loggst, hast du komplett verloren. In jeglicher hinsicht.
 
  • Gefällt mir
Reaktionen: cmi777 und Pankrat
Hm, mit mit der Materie leider kaum vertraut, aber sollte man als Privatnutzer sein Verhalten jetzt ändern (aka manche Programme eher meiden) oder geht es hauptsächlich um Server?
 
Hier kriegt man mal so eine Art kleine Vorführung.
Das scheint ja für Leute, die sich damit auskennen ziemlich einfach zu sein.
Naja, immerhin sinds erstmal duck "nur" die Server.
 
SheepShaver schrieb:
[...] aber File-Logging ins Dateisystem ist was aus dem letzen Jahrtausend. Das macht man nicht.
Prinzipiell hast du mit deinen Aussagen nicht unrecht, aber dass man das nicht macht, halte ich auch für extrem Realitätsfern. Die meisten Anwendungen loggen noch immer ins Dateisystem, das kann ich dir mit großer Zuversicht sagen, weil ich diverse Enterpriseanwendungen betreue(n) muss, und die loggen alle ins Dateisystem. Von da werden die Logs dann meist aufgesammelt und in Datenbanken geschoben, was du auch schreibst, aber das passiert bei uns völlig unabhängig von der Anwendung die die logs schreibt, weil die das alles nicht können.
Klar, wenn man jetzt ein neues Projekt anfängt, dann mag das absolut stimmen. Aber die meisten Anwendungen in der IT sind Bestandsanwendungen, und da loggt quasi alles stumpf ins Dateisystem. Dass das blöd ist, weiß ich - und viele andere. Denn wie gesagt, die Logs werden bei uns auch eingesammelt und zentral gespeichert. Aber das macht in den meisten Fällen noch nicht die Anwendung selbst, sondern eine andere, davon unabhängige Anwendung.
 
  • Gefällt mir
Reaktionen: mental.dIseASe, ComputerJunge und Piktogramm
SheepShaver schrieb:
Aha. Der Code lauft in irgend einem Pod im Kubernetes-Cluster. Und wie landen deine Logs in Elastic/Kibana? Was, wenn du im JSON-Format loggen willst? Wie macht du Log-Analysen? Mit tail und grep ueber 50 Logfiles?
Haettest du gesagt, Logging macht man nach stdout und stderr und saugt das dann mit Filebeat auf, dann haett ich es ja noch gegessen, aber File-Logging ins Dateisystem ist was aus dem letzen Jahrtausend. Das macht man nicht.
Ich mag solche Konstrukte auch ungemein! Schön komplex, zig hunderte, unbekannte Abhängigkeiten und wenn davon kritische Komponenten das zeitliche segnen gibt es gar keine Logs mehr, denn "plain and simple" ist aus dem letztem Jahrtausend. Das Monitoring läuft dann meist genauso bzw. genauso nicht und damit dauert es dann auch gern mal etwas, bis es auffällt.
Ich mag das wirklich, denn gibt es nichts was mit grep beackert werden kann, lassen sich mehr Stunden abrechnen.

Ernsthaft, ich würde empfehlen, dass alles was komplexer ist als "log to file" als (sinnvolle) Ergänzung gesehen wird.
 
SheepShaver schrieb:
Haettest du gesagt, Logging macht man nach stdout und stderr und saugt das dann mit Filebeat auf, dann haett ich es ja noch gegessen, aber File-Logging ins Dateisystem ist was aus dem letzen Jahrtausend. Das macht man nicht.
Sag das man den Zig tausend Anwendungen und Kunden.
Ergänzung ()

Snowi schrieb:
Prinzipiell hast du mit deinen Aussagen nicht unrecht, aber dass man das nicht macht, halte ich auch für extrem Realitätsfern. Die meisten Anwendungen loggen noch immer ins Dateisystem, das kann ich dir mit großer Zuversicht sagen, weil ich diverse Enterpriseanwendungen betreue(n) muss, und die loggen alle ins Dateisystem.
Eben. Und gewachsene Strukturen kann man nicht einfach mal so abbrechen und neu machen, weil da ein Ratteschwanz an weiteren Anwendungen und Zeugs hängt.
 
  • Gefällt mir
Reaktionen: mental.dIseASe und Snowi
Zurück
Oben