SCW-Symbole
Held-Hintergrund ohne Trennlinie
Blog

Java-Fallstricke – Bitweise oder boolesche Operatoren

Alan Richardson
Veröffentlicht Feb 07, 2021
Zuletzt aktualisiert am 08. März 2026

Java-Fallstricke – Bitweise oder boolesche Operatoren

> „Java Gotcha“ – ein häufig auftretender Fehler, der leicht versehentlich implementiert werden kann.

Eine relativ einfache Java-Falle, in die man versehentlich tappen kann, ist die folgende: Verwendung eines Bit-Operators anstelle eines booleschen Vergleichsoperators.

Beispielsweise kann ein einfacher Eingabefehler dazu führen, dass „&“ geschrieben wird, obwohl Sie eigentlich „&&“ schreiben wollten.

Eine gängige Heuristik, die wir bei der Codeüberprüfung lernen, lautet wie folgt:

> „&“ oder „|“ in einer bedingten Anweisung ist wahrscheinlich nicht vorgesehen.

In diesem Blogbeitrag werden wir uns mit der Heuristik befassen und Möglichkeiten aufzeigen, wie dieses Codierungsproblem erkannt und gelöst werden kann.


Was ist das Problem? Die Operationen auf Bit-Ebene funktionieren korrekt mit Booleschen Werten.


Die Verwendung von Bitoperatoren mit Booleschen Werten ist völlig zulässig. Java meldet daher keinen Syntaxfehler.

Wenn ich einen JUnit-Test erstelle, um eine Wahrheitstabelle sowohl für Bitwise OR (|) als auch für Bitwise AND (&) zu untersuchen, werden wir sehen, dass die Ausgaben des Bitwise-Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnten wir denken, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.

ET-Wahrheitstabelle

Drei Spalten, eine mit a, eine mit b und die letzte mit (a^b)


@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}


Der Test ist erfolgreich, es handelt sich um vollkommen gültiges Java.


OR-Wahrheitstabelle


Drei Spalten, eine mit a, eine mit b und die letzte mit (a v b)


@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}


Dieser Test ist auch bestanden. Warum bevorzugen wir „&&“ und „||“?


Die Bilder der Wahrheitstabelle wurden mit Hilfe des Wahrheitstabellen-Tool von web.standfor.eduerstellt.


Problem: Kurzschlussbetrieb


Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen Operatoren (&, |) und booleschen Operatoren (&&, ||).

Ein boolescher Operator ist ein Kurzschlussoperator, der nur das auswertet, was er benötigt.

z. B.

si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}


Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitweise-Operator verwendet wurde:

  • des chiffons ! = null
  • args.length () > 23

Dadurch bleibt mein Code anfällig für eine NullPointerException, wenn args null ist, da wir immer die Überprüfung von args.length durchführen, selbst wenn args null ist, da beide booleschen Bedingungen ausgewertet werden müssen.


Bewertung von Kurzschlüssen durch Boolesche Operatoren


Wenn ein && verwendet wird, zum Beispiel

si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}


Sobald wir das wissen, gibt Args! = null den Wert False zurück, wenn die Auswertung des Bedingungsausdrucks beendet ist.

Wir müssen die rechte Seite nicht bewerten.

Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.


Aber das würde im Produktionscode niemals passieren.


Es handelt sich um einen Fehler, der relativ leicht zu begehen ist und von statischen Analysewerkzeugen nicht immer erkannt wird.

Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich öffentliche Beispiele für dieses Modell finden kann:

Dateityp: java, wenn „! = null &”
Diese Suche ermöglichte es, Android-Code im RootWindowContainer abzurufen
IsDocument = intention ! = null und Intent.isDocument ()


Dies ist die Art von Code, die eine Codeüberprüfung durchlaufen kann, da wir häufig Bitoperatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. In diesem Fall ist das Ergebnis jedoch dasselbe wie im obigen Beispiel für eine if-Anweisung. Wenn die Absicht null ist, wird eine NullPointerException ausgelöst.

Très souvent, nous nous en tirons avec cette construction car nous codons souvent de manière défensive et écrivons du code redondant. Le chèque pour ! = null peut être redondant dans la plupart des cas d'utilisation.

Es handelt sich um einen Fehler, den die Programmierer im Produktionscode gemacht haben.

Ich weiß nicht, ob die Suchergebnisse aktuell sind, aber als ich die Suche durchgeführt habe, wurden Ergebnisse mit Code von Google, Amazon, Apache ... und mir zurückgegeben.

Eine kürzlich gestellte Anfrage zur Extraktion in einem meiner Open-Source-Projekte bezog sich genau auf die Korrektur dieses Fehlers.

si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}


Wie finde ich es?


Als ich mein Codebeispiel in einigen statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode erkannt.

Als Team von Secure Code Warrior haben wir ein Sensei einfaches Sensei erstellt und überarbeitet, das dieses Problem lösen könnte.

Da Bitwise-Operatoren vollkommen gültig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf die Verwendung von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.

recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »


Es verwendet einen regulären Ausdruck, um „&“ zu finden, wenn es als Bedingungsausdruck verwendet wird, z. B. in einer if-Anweisung.

Um dieses Problem zu lösen, haben wir uns erneut auf reguläre Ausdrücke gestützt. Verwenden Sie diesmal die sed-Funktion von QuickFix, um das & im Ausdruck global durch && zu ersetzen.

Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »


Endnoten

Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator vorgesehen war.

In anderen Situationen kann dies vorkommen, beispielsweise bei der Zuordnung, aber beim Verfassen von Rezepten müssen wir versuchen, eine falsch positive Identifizierung zu vermeiden, da die Rezepte sonst ignoriert oder deaktiviert werden. Wir entwickeln Rezepte, die den häufigsten Ereignissen entsprechen. Im Zuge der Weiterentwicklung von Sensei könnten wir die Suchfunktion um eine zusätzliche Spezifikation erweitern, um mehr entsprechende Bedingungen abzudecken.

In seiner aktuellen Form würde dieses Rezept es ermöglichen, zahlreiche aktuelle Anwendungsfälle zu identifizieren, darunter vor allem den in meinem Projekt genannten.

HINWEIS: Viele Code-Experten haben zu diesem Beispiel und dieser Rezeptkritik beigetragen: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für eure Hilfe.


---


Sie können Sensei IntelliJ installieren, indem Sie „Einstellungen \ Plugins” (Mac) oder „Einstellungen \ Plugins” (Windows) aufrufen und dann einfach nachSensei Code” suchen.

Wir haben viel Quellcode und Rezepte für diese Blog-Artikel (einschließlich dieses Artikels) im Repositorysensei des GitHub-Kontos von Secure Code Warrior.

https://github.com/securecodewarrior/sensei-blog-examples

Mehr über Sensei erfahren


Ressource anzeigen
Ressource anzeigen

In diesem Blogbeitrag untersuchen wir einen häufigen Java-Codierungsfehler (Verwendung eines Bit-Operators anstelle eines bedingten Operators), den Fehler, für den unser Code dadurch anfällig wird, und wie wir Sensei einsetzen können, Sensei das Problem zu beheben und zu erkennen.

Möchten Sie mehr erfahren?

Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

mehr erfahren

Secure Code Warrior Ihr Unternehmen dabei, den Code während des gesamten Softwareentwicklungszyklus zu sichern und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie für die Anwendungssicherheit verantwortlich sind, Entwickler, IT-Sicherheitsbeauftragter oder in einer anderen Funktion im Bereich Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Demo buchen
Teilen auf:
LinkedIn-MarkenSozialx Logo
Autor
Alan Richardson
Veröffentlicht Feb 07, 2021

Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Teilen auf:
LinkedIn-MarkenSozialx Logo

Java-Fallstricke – Bitweise oder boolesche Operatoren

> „Java Gotcha“ – ein häufig auftretender Fehler, der leicht versehentlich implementiert werden kann.

Eine relativ einfache Java-Falle, in die man versehentlich tappen kann, ist die folgende: Verwendung eines Bit-Operators anstelle eines booleschen Vergleichsoperators.

Beispielsweise kann ein einfacher Eingabefehler dazu führen, dass „&“ geschrieben wird, obwohl Sie eigentlich „&&“ schreiben wollten.

Eine gängige Heuristik, die wir bei der Codeüberprüfung lernen, lautet wie folgt:

> „&“ oder „|“ in einer bedingten Anweisung ist wahrscheinlich nicht vorgesehen.

In diesem Blogbeitrag werden wir uns mit der Heuristik befassen und Möglichkeiten aufzeigen, wie dieses Codierungsproblem erkannt und gelöst werden kann.


Was ist das Problem? Die Operationen auf Bit-Ebene funktionieren korrekt mit Booleschen Werten.


Die Verwendung von Bitoperatoren mit Booleschen Werten ist völlig zulässig. Java meldet daher keinen Syntaxfehler.

Wenn ich einen JUnit-Test erstelle, um eine Wahrheitstabelle sowohl für Bitwise OR (|) als auch für Bitwise AND (&) zu untersuchen, werden wir sehen, dass die Ausgaben des Bitwise-Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnten wir denken, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.

ET-Wahrheitstabelle

Drei Spalten, eine mit a, eine mit b und die letzte mit (a^b)


@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}


Der Test ist erfolgreich, es handelt sich um vollkommen gültiges Java.


OR-Wahrheitstabelle


Drei Spalten, eine mit a, eine mit b und die letzte mit (a v b)


@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}


Dieser Test ist auch bestanden. Warum bevorzugen wir „&&“ und „||“?


Die Bilder der Wahrheitstabelle wurden mit Hilfe des Wahrheitstabellen-Tool von web.standfor.eduerstellt.


Problem: Kurzschlussbetrieb


Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen Operatoren (&, |) und booleschen Operatoren (&&, ||).

Ein boolescher Operator ist ein Kurzschlussoperator, der nur das auswertet, was er benötigt.

z. B.

si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}


Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitweise-Operator verwendet wurde:

  • des chiffons ! = null
  • args.length () > 23

Dadurch bleibt mein Code anfällig für eine NullPointerException, wenn args null ist, da wir immer die Überprüfung von args.length durchführen, selbst wenn args null ist, da beide booleschen Bedingungen ausgewertet werden müssen.


Bewertung von Kurzschlüssen durch Boolesche Operatoren


Wenn ein && verwendet wird, zum Beispiel

si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}


Sobald wir das wissen, gibt Args! = null den Wert False zurück, wenn die Auswertung des Bedingungsausdrucks beendet ist.

Wir müssen die rechte Seite nicht bewerten.

Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.


Aber das würde im Produktionscode niemals passieren.


Es handelt sich um einen Fehler, der relativ leicht zu begehen ist und von statischen Analysewerkzeugen nicht immer erkannt wird.

Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich öffentliche Beispiele für dieses Modell finden kann:

Dateityp: java, wenn „! = null &”
Diese Suche ermöglichte es, Android-Code im RootWindowContainer abzurufen
IsDocument = intention ! = null und Intent.isDocument ()


Dies ist die Art von Code, die eine Codeüberprüfung durchlaufen kann, da wir häufig Bitoperatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. In diesem Fall ist das Ergebnis jedoch dasselbe wie im obigen Beispiel für eine if-Anweisung. Wenn die Absicht null ist, wird eine NullPointerException ausgelöst.

Très souvent, nous nous en tirons avec cette construction car nous codons souvent de manière défensive et écrivons du code redondant. Le chèque pour ! = null peut être redondant dans la plupart des cas d'utilisation.

Es handelt sich um einen Fehler, den die Programmierer im Produktionscode gemacht haben.

Ich weiß nicht, ob die Suchergebnisse aktuell sind, aber als ich die Suche durchgeführt habe, wurden Ergebnisse mit Code von Google, Amazon, Apache ... und mir zurückgegeben.

Eine kürzlich gestellte Anfrage zur Extraktion in einem meiner Open-Source-Projekte bezog sich genau auf die Korrektur dieses Fehlers.

si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}


Wie finde ich es?


Als ich mein Codebeispiel in einigen statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode erkannt.

Als Team von Secure Code Warrior haben wir ein Sensei einfaches Sensei erstellt und überarbeitet, das dieses Problem lösen könnte.

Da Bitwise-Operatoren vollkommen gültig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf die Verwendung von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.

recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »


Es verwendet einen regulären Ausdruck, um „&“ zu finden, wenn es als Bedingungsausdruck verwendet wird, z. B. in einer if-Anweisung.

Um dieses Problem zu lösen, haben wir uns erneut auf reguläre Ausdrücke gestützt. Verwenden Sie diesmal die sed-Funktion von QuickFix, um das & im Ausdruck global durch && zu ersetzen.

Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »


Endnoten

Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator vorgesehen war.

In anderen Situationen kann dies vorkommen, beispielsweise bei der Zuordnung, aber beim Verfassen von Rezepten müssen wir versuchen, eine falsch positive Identifizierung zu vermeiden, da die Rezepte sonst ignoriert oder deaktiviert werden. Wir entwickeln Rezepte, die den häufigsten Ereignissen entsprechen. Im Zuge der Weiterentwicklung von Sensei könnten wir die Suchfunktion um eine zusätzliche Spezifikation erweitern, um mehr entsprechende Bedingungen abzudecken.

In seiner aktuellen Form würde dieses Rezept es ermöglichen, zahlreiche aktuelle Anwendungsfälle zu identifizieren, darunter vor allem den in meinem Projekt genannten.

HINWEIS: Viele Code-Experten haben zu diesem Beispiel und dieser Rezeptkritik beigetragen: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für eure Hilfe.


---


Sie können Sensei IntelliJ installieren, indem Sie „Einstellungen \ Plugins” (Mac) oder „Einstellungen \ Plugins” (Windows) aufrufen und dann einfach nachSensei Code” suchen.

Wir haben viel Quellcode und Rezepte für diese Blog-Artikel (einschließlich dieses Artikels) im Repositorysensei des GitHub-Kontos von Secure Code Warrior.

https://github.com/securecodewarrior/sensei-blog-examples

Mehr über Sensei erfahren


Ressource anzeigen
Ressource anzeigen

Füllen Sie das untenstehende Formular aus, um den Bericht herunterzuladen.

Wir möchten Ihre Einwilligung einholen, um Ihnen Informationen zu unseren Produkten und/oder zu Themen im Zusammenhang mit sicherer Verschlüsselung zuzusenden. Wir werden Ihre personenbezogenen Daten stets mit größter Sorgfalt behandeln und niemals zu Marketingzwecken an andere Unternehmen verkaufen.

Einreichen
scw Erfolgssymbol
scw-Fehlersymbol
Um das Formular zu senden, aktivieren Sie bitte die „Analytics“-Cookies. Sie können diese nach Abschluss des Vorgangs wieder deaktivieren.

Java-Fallstricke – Bitweise oder boolesche Operatoren

> „Java Gotcha“ – ein häufig auftretender Fehler, der leicht versehentlich implementiert werden kann.

Eine relativ einfache Java-Falle, in die man versehentlich tappen kann, ist die folgende: Verwendung eines Bit-Operators anstelle eines booleschen Vergleichsoperators.

Beispielsweise kann ein einfacher Eingabefehler dazu führen, dass „&“ geschrieben wird, obwohl Sie eigentlich „&&“ schreiben wollten.

Eine gängige Heuristik, die wir bei der Codeüberprüfung lernen, lautet wie folgt:

> „&“ oder „|“ in einer bedingten Anweisung ist wahrscheinlich nicht vorgesehen.

In diesem Blogbeitrag werden wir uns mit der Heuristik befassen und Möglichkeiten aufzeigen, wie dieses Codierungsproblem erkannt und gelöst werden kann.


Was ist das Problem? Die Operationen auf Bit-Ebene funktionieren korrekt mit Booleschen Werten.


Die Verwendung von Bitoperatoren mit Booleschen Werten ist völlig zulässig. Java meldet daher keinen Syntaxfehler.

Wenn ich einen JUnit-Test erstelle, um eine Wahrheitstabelle sowohl für Bitwise OR (|) als auch für Bitwise AND (&) zu untersuchen, werden wir sehen, dass die Ausgaben des Bitwise-Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnten wir denken, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.

ET-Wahrheitstabelle

Drei Spalten, eine mit a, eine mit b und die letzte mit (a^b)


@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}


Der Test ist erfolgreich, es handelt sich um vollkommen gültiges Java.


OR-Wahrheitstabelle


Drei Spalten, eine mit a, eine mit b und die letzte mit (a v b)


@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}


Dieser Test ist auch bestanden. Warum bevorzugen wir „&&“ und „||“?


Die Bilder der Wahrheitstabelle wurden mit Hilfe des Wahrheitstabellen-Tool von web.standfor.eduerstellt.


Problem: Kurzschlussbetrieb


Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen Operatoren (&, |) und booleschen Operatoren (&&, ||).

Ein boolescher Operator ist ein Kurzschlussoperator, der nur das auswertet, was er benötigt.

z. B.

si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}


Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitweise-Operator verwendet wurde:

  • des chiffons ! = null
  • args.length () > 23

Dadurch bleibt mein Code anfällig für eine NullPointerException, wenn args null ist, da wir immer die Überprüfung von args.length durchführen, selbst wenn args null ist, da beide booleschen Bedingungen ausgewertet werden müssen.


Bewertung von Kurzschlüssen durch Boolesche Operatoren


Wenn ein && verwendet wird, zum Beispiel

si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}


Sobald wir das wissen, gibt Args! = null den Wert False zurück, wenn die Auswertung des Bedingungsausdrucks beendet ist.

Wir müssen die rechte Seite nicht bewerten.

Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.


Aber das würde im Produktionscode niemals passieren.


Es handelt sich um einen Fehler, der relativ leicht zu begehen ist und von statischen Analysewerkzeugen nicht immer erkannt wird.

Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich öffentliche Beispiele für dieses Modell finden kann:

Dateityp: java, wenn „! = null &”
Diese Suche ermöglichte es, Android-Code im RootWindowContainer abzurufen
IsDocument = intention ! = null und Intent.isDocument ()


Dies ist die Art von Code, die eine Codeüberprüfung durchlaufen kann, da wir häufig Bitoperatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. In diesem Fall ist das Ergebnis jedoch dasselbe wie im obigen Beispiel für eine if-Anweisung. Wenn die Absicht null ist, wird eine NullPointerException ausgelöst.

Très souvent, nous nous en tirons avec cette construction car nous codons souvent de manière défensive et écrivons du code redondant. Le chèque pour ! = null peut être redondant dans la plupart des cas d'utilisation.

Es handelt sich um einen Fehler, den die Programmierer im Produktionscode gemacht haben.

Ich weiß nicht, ob die Suchergebnisse aktuell sind, aber als ich die Suche durchgeführt habe, wurden Ergebnisse mit Code von Google, Amazon, Apache ... und mir zurückgegeben.

Eine kürzlich gestellte Anfrage zur Extraktion in einem meiner Open-Source-Projekte bezog sich genau auf die Korrektur dieses Fehlers.

si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}


Wie finde ich es?


Als ich mein Codebeispiel in einigen statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode erkannt.

Als Team von Secure Code Warrior haben wir ein Sensei einfaches Sensei erstellt und überarbeitet, das dieses Problem lösen könnte.

Da Bitwise-Operatoren vollkommen gültig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf die Verwendung von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.

recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »


Es verwendet einen regulären Ausdruck, um „&“ zu finden, wenn es als Bedingungsausdruck verwendet wird, z. B. in einer if-Anweisung.

Um dieses Problem zu lösen, haben wir uns erneut auf reguläre Ausdrücke gestützt. Verwenden Sie diesmal die sed-Funktion von QuickFix, um das & im Ausdruck global durch && zu ersetzen.

Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »


Endnoten

Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator vorgesehen war.

In anderen Situationen kann dies vorkommen, beispielsweise bei der Zuordnung, aber beim Verfassen von Rezepten müssen wir versuchen, eine falsch positive Identifizierung zu vermeiden, da die Rezepte sonst ignoriert oder deaktiviert werden. Wir entwickeln Rezepte, die den häufigsten Ereignissen entsprechen. Im Zuge der Weiterentwicklung von Sensei könnten wir die Suchfunktion um eine zusätzliche Spezifikation erweitern, um mehr entsprechende Bedingungen abzudecken.

In seiner aktuellen Form würde dieses Rezept es ermöglichen, zahlreiche aktuelle Anwendungsfälle zu identifizieren, darunter vor allem den in meinem Projekt genannten.

HINWEIS: Viele Code-Experten haben zu diesem Beispiel und dieser Rezeptkritik beigetragen: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für eure Hilfe.


---


Sie können Sensei IntelliJ installieren, indem Sie „Einstellungen \ Plugins” (Mac) oder „Einstellungen \ Plugins” (Windows) aufrufen und dann einfach nachSensei Code” suchen.

Wir haben viel Quellcode und Rezepte für diese Blog-Artikel (einschließlich dieses Artikels) im Repositorysensei des GitHub-Kontos von Secure Code Warrior.

https://github.com/securecodewarrior/sensei-blog-examples

Mehr über Sensei erfahren


Webinar anzeigen
Beginnen Sie
mehr erfahren

Klicken Sie auf den untenstehenden Link und laden Sie das PDF dieser Ressource herunter.

Secure Code Warrior Ihr Unternehmen dabei, den Code während des gesamten Softwareentwicklungszyklus zu sichern und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie für die Anwendungssicherheit verantwortlich sind, Entwickler, IT-Sicherheitsbeauftragter oder in einer anderen Funktion im Bereich Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Bericht anzeigenDemo buchen
PDF herunterladen
Ressource anzeigen
Teilen auf:
LinkedIn-MarkenSozialx Logo
Möchten Sie mehr erfahren?

Teilen auf:
LinkedIn-MarkenSozialx Logo
Autor
Alan Richardson
Veröffentlicht Feb 07, 2021

Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Teilen auf:
LinkedIn-MarkenSozialx Logo

Java-Fallstricke – Bitweise oder boolesche Operatoren

> „Java Gotcha“ – ein häufig auftretender Fehler, der leicht versehentlich implementiert werden kann.

Eine relativ einfache Java-Falle, in die man versehentlich tappen kann, ist die folgende: Verwendung eines Bit-Operators anstelle eines booleschen Vergleichsoperators.

Beispielsweise kann ein einfacher Eingabefehler dazu führen, dass „&“ geschrieben wird, obwohl Sie eigentlich „&&“ schreiben wollten.

Eine gängige Heuristik, die wir bei der Codeüberprüfung lernen, lautet wie folgt:

> „&“ oder „|“ in einer bedingten Anweisung ist wahrscheinlich nicht vorgesehen.

In diesem Blogbeitrag werden wir uns mit der Heuristik befassen und Möglichkeiten aufzeigen, wie dieses Codierungsproblem erkannt und gelöst werden kann.


Was ist das Problem? Die Operationen auf Bit-Ebene funktionieren korrekt mit Booleschen Werten.


Die Verwendung von Bitoperatoren mit Booleschen Werten ist völlig zulässig. Java meldet daher keinen Syntaxfehler.

Wenn ich einen JUnit-Test erstelle, um eine Wahrheitstabelle sowohl für Bitwise OR (|) als auch für Bitwise AND (&) zu untersuchen, werden wir sehen, dass die Ausgaben des Bitwise-Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnten wir denken, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.

ET-Wahrheitstabelle

Drei Spalten, eine mit a, eine mit b und die letzte mit (a^b)


@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}


Der Test ist erfolgreich, es handelt sich um vollkommen gültiges Java.


OR-Wahrheitstabelle


Drei Spalten, eine mit a, eine mit b und die letzte mit (a v b)


@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}


Dieser Test ist auch bestanden. Warum bevorzugen wir „&&“ und „||“?


Die Bilder der Wahrheitstabelle wurden mit Hilfe des Wahrheitstabellen-Tool von web.standfor.eduerstellt.


Problem: Kurzschlussbetrieb


Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen Operatoren (&, |) und booleschen Operatoren (&&, ||).

Ein boolescher Operator ist ein Kurzschlussoperator, der nur das auswertet, was er benötigt.

z. B.

si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}


Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitweise-Operator verwendet wurde:

  • des chiffons ! = null
  • args.length () > 23

Dadurch bleibt mein Code anfällig für eine NullPointerException, wenn args null ist, da wir immer die Überprüfung von args.length durchführen, selbst wenn args null ist, da beide booleschen Bedingungen ausgewertet werden müssen.


Bewertung von Kurzschlüssen durch Boolesche Operatoren


Wenn ein && verwendet wird, zum Beispiel

si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}


Sobald wir das wissen, gibt Args! = null den Wert False zurück, wenn die Auswertung des Bedingungsausdrucks beendet ist.

Wir müssen die rechte Seite nicht bewerten.

Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.


Aber das würde im Produktionscode niemals passieren.


Es handelt sich um einen Fehler, der relativ leicht zu begehen ist und von statischen Analysewerkzeugen nicht immer erkannt wird.

Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich öffentliche Beispiele für dieses Modell finden kann:

Dateityp: java, wenn „! = null &”
Diese Suche ermöglichte es, Android-Code im RootWindowContainer abzurufen
IsDocument = intention ! = null und Intent.isDocument ()


Dies ist die Art von Code, die eine Codeüberprüfung durchlaufen kann, da wir häufig Bitoperatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. In diesem Fall ist das Ergebnis jedoch dasselbe wie im obigen Beispiel für eine if-Anweisung. Wenn die Absicht null ist, wird eine NullPointerException ausgelöst.

Très souvent, nous nous en tirons avec cette construction car nous codons souvent de manière défensive et écrivons du code redondant. Le chèque pour ! = null peut être redondant dans la plupart des cas d'utilisation.

Es handelt sich um einen Fehler, den die Programmierer im Produktionscode gemacht haben.

Ich weiß nicht, ob die Suchergebnisse aktuell sind, aber als ich die Suche durchgeführt habe, wurden Ergebnisse mit Code von Google, Amazon, Apache ... und mir zurückgegeben.

Eine kürzlich gestellte Anfrage zur Extraktion in einem meiner Open-Source-Projekte bezog sich genau auf die Korrektur dieses Fehlers.

si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}


Wie finde ich es?


Als ich mein Codebeispiel in einigen statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode erkannt.

Als Team von Secure Code Warrior haben wir ein Sensei einfaches Sensei erstellt und überarbeitet, das dieses Problem lösen könnte.

Da Bitwise-Operatoren vollkommen gültig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf die Verwendung von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.

recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »


Es verwendet einen regulären Ausdruck, um „&“ zu finden, wenn es als Bedingungsausdruck verwendet wird, z. B. in einer if-Anweisung.

Um dieses Problem zu lösen, haben wir uns erneut auf reguläre Ausdrücke gestützt. Verwenden Sie diesmal die sed-Funktion von QuickFix, um das & im Ausdruck global durch && zu ersetzen.

Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »


Endnoten

Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator vorgesehen war.

In anderen Situationen kann dies vorkommen, beispielsweise bei der Zuordnung, aber beim Verfassen von Rezepten müssen wir versuchen, eine falsch positive Identifizierung zu vermeiden, da die Rezepte sonst ignoriert oder deaktiviert werden. Wir entwickeln Rezepte, die den häufigsten Ereignissen entsprechen. Im Zuge der Weiterentwicklung von Sensei könnten wir die Suchfunktion um eine zusätzliche Spezifikation erweitern, um mehr entsprechende Bedingungen abzudecken.

In seiner aktuellen Form würde dieses Rezept es ermöglichen, zahlreiche aktuelle Anwendungsfälle zu identifizieren, darunter vor allem den in meinem Projekt genannten.

HINWEIS: Viele Code-Experten haben zu diesem Beispiel und dieser Rezeptkritik beigetragen: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für eure Hilfe.


---


Sie können Sensei IntelliJ installieren, indem Sie „Einstellungen \ Plugins” (Mac) oder „Einstellungen \ Plugins” (Windows) aufrufen und dann einfach nachSensei Code” suchen.

Wir haben viel Quellcode und Rezepte für diese Blog-Artikel (einschließlich dieses Artikels) im Repositorysensei des GitHub-Kontos von Secure Code Warrior.

https://github.com/securecodewarrior/sensei-blog-examples

Mehr über Sensei erfahren


Inhaltsverzeichnis

PDF herunterladen
Ressource anzeigen
Möchten Sie mehr erfahren?

Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

mehr erfahren

Secure Code Warrior Ihr Unternehmen dabei, den Code während des gesamten Softwareentwicklungszyklus zu sichern und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie für die Anwendungssicherheit verantwortlich sind, Entwickler, IT-Sicherheitsbeauftragter oder in einer anderen Funktion im Bereich Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Demo buchenHerunterladen
Teilen auf:
LinkedIn-MarkenSozialx Logo
Ressourcenzentrum

Ressourcen, die Ihnen den Einstieg erleichtern

Weitere Beiträge
Ressourcenzentrum

Ressourcen, die Ihnen den Einstieg erleichtern

Weitere Beiträge