Java Gotchas - Bitweise vs. Boolesche Operatoren
Java Gotchas - Bitweise vs. Boolesche Operatoren
> "Java Gotcha" - ein häufiges Fehlermuster, das sich leicht versehentlich implementieren lässt.
Ein recht einfaches Java-Gotcha, in das man versehentlich hineinfallen kann, ist: die Verwendung eines Bitwise-Operators anstelle eines booleschen Vergleichsoperators.
z. B. kann ein einfacher Tippfehler dazu führen, dass Sie "&" schreiben, obwohl Sie eigentlich "&&" schreiben wollten.
Eine gängige Heuristik, die wir beim Überprüfen von Code lernen, ist:
> "&" oder "|" bei Verwendung in einer bedingten Anweisung ist wahrscheinlich nicht beabsichtigt.
In diesem Blog-Beitrag werden wir die Heuristik untersuchen und Wege aufzeigen, wie wir dieses Kodierungsproblem identifizieren und beheben können.
Wo liegt das Problem? Bitweise Operationen funktionieren gut mit Booleans
Die Verwendung von Bitwise-Operatoren mit Booleschen Operatoren ist durchaus zulässig, so dass Java keinen Syntaxfehler meldet.
Wenn ich einen JUnit-Test konstruiere, um eine Wahrheitstabelle sowohl für Bitweises ODER (|) als auch Bitweises UND (&) zu untersuchen, dann werden wir sehen, dass die Ausgaben des Bitweisen Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnte man meinen, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.
AND-Wahrheitstabelle

@Test
void bitwiseOperatorsAndTruthTable(){
Assertions.assertEquals(true, true & true);
Assertions.assertEquals(false, true & false);
Assertions.assertEquals(false, false & true);
Assertions.assertEquals(false, false & false);
}
Der Test ist bestanden, dies ist vollkommen gültiges Java.
OR-Wahrheitstabelle

@Test
void bitwiseOperatorsOrTruthTable(){
Assertions.assertEquals(true, true | true);
Assertions.assertEquals(true, true | false);
Assertions.assertEquals(true, false | true);
Assertions.assertEquals(false, false | false);
}
Auch dieser Test besteht, warum bevorzugen wir "&&'und "||'?
Wahrheitstabellenbilder wurden mit dem Wahrheitstabellen-Werkzeug von web.standfor.edu.
Problem: Kurzschlussbetrieb
Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen (&, |) und booleschen (&&, ||) Operatoren.
Ein boolescher Operator ist ein Kurzschlussoperator und wertet nur so viel aus, wie er muss.
z.B.
if (args != null & args.length() > 23) {
System.out.println(args);
}
Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitwise-Operator verwendet wurde:
- args != null
- args.length() > 23
Das lässt meinen Code offen für eine NullPointerException, wenn args null ist, weil wir immer die Prüfung für args.length durchführen, auch wenn args null ist, weil beide booleschen Bedingungen ausgewertet werden müssen.
Boolesche Operatoren Kurzschlussauswertung
Wenn ein && verwendet wird, z. B.
if (args != null && args.length() > 23) {
System.out.println(args);
}
Sobald wir wissen, dass args != null zu false ausgewertet wird, stoppt die Auswertung des Bedingungsausdrucks.
Die rechte Seite brauchen wir nicht auszuwerten.
Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.
Aber das würde im Produktionscode nie passieren
Dies ist ein ziemlich leicht zu begehender Fehler, der nicht immer von statischen Analysetools erkannt wird.
Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich irgendwelche öffentlichen Beispiele für dieses Muster finden kann:
filetype:java if "!=null & "
Diese Suche brachte etwas Code von Android im RootWindowContainer
isDocument = intent != null & intent.isDocument()
Dies ist die Art von Code, die eine Codeprüfung bestehen könnte, weil wir oft Bitwise-Operatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. Aber in diesem Fall ist das Ergebnis das gleiche wie im obigen Beispiel der if-Anweisung. Wenn intent jemals null ist, dann wird eine NullPointerException geworfen.
Sehr oft kommen wir mit diesem Konstrukt davon, weil wir oft defensiv codieren und redundanten Code schreiben. Die Prüfung auf != null mag in den meisten Anwendungsfällen durchaus redundant sein.
Dies ist ein Fehler, der von Programmierern im Produktionscode gemacht wird.
Ich weiß nicht, wie aktuell die Ergebnisse für die Suche sind, aber als ich die Suche ausgeführt habe, gab es Ergebnisse zurück mit Code von: Google, Amazon, Apache... und mir.
Eine kürzliche Pull-Anfrage in einem meiner Open-Source-Projekte sollte genau diesen Fehler beheben.
if(type!=null & type.trim().length()>0){
acceptMediaTypeDefinitionsList.add(type.trim());
}
Wie Sie das finden
Als ich meinen Beispielcode in ein paar statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode gefunden.
Als Team auf Secure Code Warrior haben wir ein recht einfaches Sensei Rezept erstellt und überprüft, das dies auffangen kann.
Da Bitwise-Operatoren durchaus zulässig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf den Anwendungsfall von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.
search:
expression:
anyOf:
- in:
condition: {}
value:
caseSensitive: false
matches: ".* & .*"
Hier wird ein regulärer Ausdruck verwendet, um mit " & " übereinzustimmen, wenn er als Bedingungsausdruck verwendet wird. z. B. in einer if-Anweisung.
Um das zu beheben, haben wir wieder auf reguläre Ausdrücke zurückgegriffen. Diesmal mit der sed-Funktion im QuickFix, um das & im Ausdruck global durch && zu ersetzen.
availableFixes:
- name: "Replace bitwise AND operator to logical AND operator"
actions:
- rewrite:
to: "{{#sed}}s/&/&&/g,{{{ . }}}{{/sed}}"
Ende Anmerkungen
Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator beabsichtigt war.
Es gibt andere Situationen, in denen dies auftreten könnte, z. B. das Zuordnungsbeispiel, aber beim Schreiben von Rezepten müssen wir versuchen, eine falsch-positive Identifizierung zu vermeiden, sonst werden Rezepte ignoriert oder ausgeschaltet. Wir erstellen Rezepte, die den häufigsten Vorkommnissen entsprechen. Wenn sich Sensei weiterentwickelt, werden wir möglicherweise zusätzliche Spezifität in die Suchfunktion einbauen, um mehr passende Bedingungen abzudecken.
In seiner aktuellen Form würde dieses Rezept viele der Live-Anwendungsfälle identifizieren, und vor allem den, der in meinem Projekt berichtet wurde.
HINWEIS: Eine ganze Reihe von Code-Kriegern hat zu diesem Beispiel und der Rezeptüberprüfung beigetragen - Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für Ihre Hilfe.
---
Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.
Wir haben eine Menge Quellcode und Rezepte für diese Blog-Beiträge (einschließlich dieses Beitrags) im `sensei-blog-examples`-Repository im Secure Code Warrior GitHub-Konto.
https://github.com/securecodewarrior/sensei-blog-examples


In diesem Blogbeitrag werfen wir einen Blick auf einen häufigen Java-Codierungsfehler (die Verwendung eines bitweisen Operators anstelle eines bedingten Operators), den Fehler, für den unser Code dadurch anfällig ist, und wie wir Sensei verwenden können, um das Problem zu beheben und zu erkennen.
Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Demo buchenAlan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.


Java Gotchas - Bitweise vs. Boolesche Operatoren
> "Java Gotcha" - ein häufiges Fehlermuster, das sich leicht versehentlich implementieren lässt.
Ein recht einfaches Java-Gotcha, in das man versehentlich hineinfallen kann, ist: die Verwendung eines Bitwise-Operators anstelle eines booleschen Vergleichsoperators.
z. B. kann ein einfacher Tippfehler dazu führen, dass Sie "&" schreiben, obwohl Sie eigentlich "&&" schreiben wollten.
Eine gängige Heuristik, die wir beim Überprüfen von Code lernen, ist:
> "&" oder "|" bei Verwendung in einer bedingten Anweisung ist wahrscheinlich nicht beabsichtigt.
In diesem Blog-Beitrag werden wir die Heuristik untersuchen und Wege aufzeigen, wie wir dieses Kodierungsproblem identifizieren und beheben können.
Wo liegt das Problem? Bitweise Operationen funktionieren gut mit Booleans
Die Verwendung von Bitwise-Operatoren mit Booleschen Operatoren ist durchaus zulässig, so dass Java keinen Syntaxfehler meldet.
Wenn ich einen JUnit-Test konstruiere, um eine Wahrheitstabelle sowohl für Bitweises ODER (|) als auch Bitweises UND (&) zu untersuchen, dann werden wir sehen, dass die Ausgaben des Bitweisen Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnte man meinen, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.
AND-Wahrheitstabelle

@Test
void bitwiseOperatorsAndTruthTable(){
Assertions.assertEquals(true, true & true);
Assertions.assertEquals(false, true & false);
Assertions.assertEquals(false, false & true);
Assertions.assertEquals(false, false & false);
}
Der Test ist bestanden, dies ist vollkommen gültiges Java.
OR-Wahrheitstabelle

@Test
void bitwiseOperatorsOrTruthTable(){
Assertions.assertEquals(true, true | true);
Assertions.assertEquals(true, true | false);
Assertions.assertEquals(true, false | true);
Assertions.assertEquals(false, false | false);
}
Auch dieser Test besteht, warum bevorzugen wir "&&'und "||'?
Wahrheitstabellenbilder wurden mit dem Wahrheitstabellen-Werkzeug von web.standfor.edu.
Problem: Kurzschlussbetrieb
Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen (&, |) und booleschen (&&, ||) Operatoren.
Ein boolescher Operator ist ein Kurzschlussoperator und wertet nur so viel aus, wie er muss.
z.B.
if (args != null & args.length() > 23) {
System.out.println(args);
}
Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitwise-Operator verwendet wurde:
- args != null
- args.length() > 23
Das lässt meinen Code offen für eine NullPointerException, wenn args null ist, weil wir immer die Prüfung für args.length durchführen, auch wenn args null ist, weil beide booleschen Bedingungen ausgewertet werden müssen.
Boolesche Operatoren Kurzschlussauswertung
Wenn ein && verwendet wird, z. B.
if (args != null && args.length() > 23) {
System.out.println(args);
}
Sobald wir wissen, dass args != null zu false ausgewertet wird, stoppt die Auswertung des Bedingungsausdrucks.
Die rechte Seite brauchen wir nicht auszuwerten.
Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.
Aber das würde im Produktionscode nie passieren
Dies ist ein ziemlich leicht zu begehender Fehler, der nicht immer von statischen Analysetools erkannt wird.
Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich irgendwelche öffentlichen Beispiele für dieses Muster finden kann:
filetype:java if "!=null & "
Diese Suche brachte etwas Code von Android im RootWindowContainer
isDocument = intent != null & intent.isDocument()
Dies ist die Art von Code, die eine Codeprüfung bestehen könnte, weil wir oft Bitwise-Operatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. Aber in diesem Fall ist das Ergebnis das gleiche wie im obigen Beispiel der if-Anweisung. Wenn intent jemals null ist, dann wird eine NullPointerException geworfen.
Sehr oft kommen wir mit diesem Konstrukt davon, weil wir oft defensiv codieren und redundanten Code schreiben. Die Prüfung auf != null mag in den meisten Anwendungsfällen durchaus redundant sein.
Dies ist ein Fehler, der von Programmierern im Produktionscode gemacht wird.
Ich weiß nicht, wie aktuell die Ergebnisse für die Suche sind, aber als ich die Suche ausgeführt habe, gab es Ergebnisse zurück mit Code von: Google, Amazon, Apache... und mir.
Eine kürzliche Pull-Anfrage in einem meiner Open-Source-Projekte sollte genau diesen Fehler beheben.
if(type!=null & type.trim().length()>0){
acceptMediaTypeDefinitionsList.add(type.trim());
}
Wie Sie das finden
Als ich meinen Beispielcode in ein paar statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode gefunden.
Als Team auf Secure Code Warrior haben wir ein recht einfaches Sensei Rezept erstellt und überprüft, das dies auffangen kann.
Da Bitwise-Operatoren durchaus zulässig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf den Anwendungsfall von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.
search:
expression:
anyOf:
- in:
condition: {}
value:
caseSensitive: false
matches: ".* & .*"
Hier wird ein regulärer Ausdruck verwendet, um mit " & " übereinzustimmen, wenn er als Bedingungsausdruck verwendet wird. z. B. in einer if-Anweisung.
Um das zu beheben, haben wir wieder auf reguläre Ausdrücke zurückgegriffen. Diesmal mit der sed-Funktion im QuickFix, um das & im Ausdruck global durch && zu ersetzen.
availableFixes:
- name: "Replace bitwise AND operator to logical AND operator"
actions:
- rewrite:
to: "{{#sed}}s/&/&&/g,{{{ . }}}{{/sed}}"
Ende Anmerkungen
Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator beabsichtigt war.
Es gibt andere Situationen, in denen dies auftreten könnte, z. B. das Zuordnungsbeispiel, aber beim Schreiben von Rezepten müssen wir versuchen, eine falsch-positive Identifizierung zu vermeiden, sonst werden Rezepte ignoriert oder ausgeschaltet. Wir erstellen Rezepte, die den häufigsten Vorkommnissen entsprechen. Wenn sich Sensei weiterentwickelt, werden wir möglicherweise zusätzliche Spezifität in die Suchfunktion einbauen, um mehr passende Bedingungen abzudecken.
In seiner aktuellen Form würde dieses Rezept viele der Live-Anwendungsfälle identifizieren, und vor allem den, der in meinem Projekt berichtet wurde.
HINWEIS: Eine ganze Reihe von Code-Kriegern hat zu diesem Beispiel und der Rezeptüberprüfung beigetragen - Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für Ihre Hilfe.
---
Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.
Wir haben eine Menge Quellcode und Rezepte für diese Blog-Beiträge (einschließlich dieses Beitrags) im `sensei-blog-examples`-Repository im Secure Code Warrior GitHub-Konto.
https://github.com/securecodewarrior/sensei-blog-examples

Java Gotchas - Bitweise vs. Boolesche Operatoren
> "Java Gotcha" - ein häufiges Fehlermuster, das sich leicht versehentlich implementieren lässt.
Ein recht einfaches Java-Gotcha, in das man versehentlich hineinfallen kann, ist: die Verwendung eines Bitwise-Operators anstelle eines booleschen Vergleichsoperators.
z. B. kann ein einfacher Tippfehler dazu führen, dass Sie "&" schreiben, obwohl Sie eigentlich "&&" schreiben wollten.
Eine gängige Heuristik, die wir beim Überprüfen von Code lernen, ist:
> "&" oder "|" bei Verwendung in einer bedingten Anweisung ist wahrscheinlich nicht beabsichtigt.
In diesem Blog-Beitrag werden wir die Heuristik untersuchen und Wege aufzeigen, wie wir dieses Kodierungsproblem identifizieren und beheben können.
Wo liegt das Problem? Bitweise Operationen funktionieren gut mit Booleans
Die Verwendung von Bitwise-Operatoren mit Booleschen Operatoren ist durchaus zulässig, so dass Java keinen Syntaxfehler meldet.
Wenn ich einen JUnit-Test konstruiere, um eine Wahrheitstabelle sowohl für Bitweises ODER (|) als auch Bitweises UND (&) zu untersuchen, dann werden wir sehen, dass die Ausgaben des Bitweisen Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnte man meinen, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.
AND-Wahrheitstabelle

@Test
void bitwiseOperatorsAndTruthTable(){
Assertions.assertEquals(true, true & true);
Assertions.assertEquals(false, true & false);
Assertions.assertEquals(false, false & true);
Assertions.assertEquals(false, false & false);
}
Der Test ist bestanden, dies ist vollkommen gültiges Java.
OR-Wahrheitstabelle

@Test
void bitwiseOperatorsOrTruthTable(){
Assertions.assertEquals(true, true | true);
Assertions.assertEquals(true, true | false);
Assertions.assertEquals(true, false | true);
Assertions.assertEquals(false, false | false);
}
Auch dieser Test besteht, warum bevorzugen wir "&&'und "||'?
Wahrheitstabellenbilder wurden mit dem Wahrheitstabellen-Werkzeug von web.standfor.edu.
Problem: Kurzschlussbetrieb
Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen (&, |) und booleschen (&&, ||) Operatoren.
Ein boolescher Operator ist ein Kurzschlussoperator und wertet nur so viel aus, wie er muss.
z.B.
if (args != null & args.length() > 23) {
System.out.println(args);
}
Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitwise-Operator verwendet wurde:
- args != null
- args.length() > 23
Das lässt meinen Code offen für eine NullPointerException, wenn args null ist, weil wir immer die Prüfung für args.length durchführen, auch wenn args null ist, weil beide booleschen Bedingungen ausgewertet werden müssen.
Boolesche Operatoren Kurzschlussauswertung
Wenn ein && verwendet wird, z. B.
if (args != null && args.length() > 23) {
System.out.println(args);
}
Sobald wir wissen, dass args != null zu false ausgewertet wird, stoppt die Auswertung des Bedingungsausdrucks.
Die rechte Seite brauchen wir nicht auszuwerten.
Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.
Aber das würde im Produktionscode nie passieren
Dies ist ein ziemlich leicht zu begehender Fehler, der nicht immer von statischen Analysetools erkannt wird.
Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich irgendwelche öffentlichen Beispiele für dieses Muster finden kann:
filetype:java if "!=null & "
Diese Suche brachte etwas Code von Android im RootWindowContainer
isDocument = intent != null & intent.isDocument()
Dies ist die Art von Code, die eine Codeprüfung bestehen könnte, weil wir oft Bitwise-Operatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. Aber in diesem Fall ist das Ergebnis das gleiche wie im obigen Beispiel der if-Anweisung. Wenn intent jemals null ist, dann wird eine NullPointerException geworfen.
Sehr oft kommen wir mit diesem Konstrukt davon, weil wir oft defensiv codieren und redundanten Code schreiben. Die Prüfung auf != null mag in den meisten Anwendungsfällen durchaus redundant sein.
Dies ist ein Fehler, der von Programmierern im Produktionscode gemacht wird.
Ich weiß nicht, wie aktuell die Ergebnisse für die Suche sind, aber als ich die Suche ausgeführt habe, gab es Ergebnisse zurück mit Code von: Google, Amazon, Apache... und mir.
Eine kürzliche Pull-Anfrage in einem meiner Open-Source-Projekte sollte genau diesen Fehler beheben.
if(type!=null & type.trim().length()>0){
acceptMediaTypeDefinitionsList.add(type.trim());
}
Wie Sie das finden
Als ich meinen Beispielcode in ein paar statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode gefunden.
Als Team auf Secure Code Warrior haben wir ein recht einfaches Sensei Rezept erstellt und überprüft, das dies auffangen kann.
Da Bitwise-Operatoren durchaus zulässig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf den Anwendungsfall von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.
search:
expression:
anyOf:
- in:
condition: {}
value:
caseSensitive: false
matches: ".* & .*"
Hier wird ein regulärer Ausdruck verwendet, um mit " & " übereinzustimmen, wenn er als Bedingungsausdruck verwendet wird. z. B. in einer if-Anweisung.
Um das zu beheben, haben wir wieder auf reguläre Ausdrücke zurückgegriffen. Diesmal mit der sed-Funktion im QuickFix, um das & im Ausdruck global durch && zu ersetzen.
availableFixes:
- name: "Replace bitwise AND operator to logical AND operator"
actions:
- rewrite:
to: "{{#sed}}s/&/&&/g,{{{ . }}}{{/sed}}"
Ende Anmerkungen
Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator beabsichtigt war.
Es gibt andere Situationen, in denen dies auftreten könnte, z. B. das Zuordnungsbeispiel, aber beim Schreiben von Rezepten müssen wir versuchen, eine falsch-positive Identifizierung zu vermeiden, sonst werden Rezepte ignoriert oder ausgeschaltet. Wir erstellen Rezepte, die den häufigsten Vorkommnissen entsprechen. Wenn sich Sensei weiterentwickelt, werden wir möglicherweise zusätzliche Spezifität in die Suchfunktion einbauen, um mehr passende Bedingungen abzudecken.
In seiner aktuellen Form würde dieses Rezept viele der Live-Anwendungsfälle identifizieren, und vor allem den, der in meinem Projekt berichtet wurde.
HINWEIS: Eine ganze Reihe von Code-Kriegern hat zu diesem Beispiel und der Rezeptüberprüfung beigetragen - Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für Ihre Hilfe.
---
Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.
Wir haben eine Menge Quellcode und Rezepte für diese Blog-Beiträge (einschließlich dieses Beitrags) im `sensei-blog-examples`-Repository im Secure Code Warrior GitHub-Konto.
https://github.com/securecodewarrior/sensei-blog-examples

Klicken Sie auf den unten stehenden Link und laden Sie die PDF-Datei dieser Ressource herunter.
Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Bericht ansehenDemo buchenAlan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.
Java Gotchas - Bitweise vs. Boolesche Operatoren
> "Java Gotcha" - ein häufiges Fehlermuster, das sich leicht versehentlich implementieren lässt.
Ein recht einfaches Java-Gotcha, in das man versehentlich hineinfallen kann, ist: die Verwendung eines Bitwise-Operators anstelle eines booleschen Vergleichsoperators.
z. B. kann ein einfacher Tippfehler dazu führen, dass Sie "&" schreiben, obwohl Sie eigentlich "&&" schreiben wollten.
Eine gängige Heuristik, die wir beim Überprüfen von Code lernen, ist:
> "&" oder "|" bei Verwendung in einer bedingten Anweisung ist wahrscheinlich nicht beabsichtigt.
In diesem Blog-Beitrag werden wir die Heuristik untersuchen und Wege aufzeigen, wie wir dieses Kodierungsproblem identifizieren und beheben können.
Wo liegt das Problem? Bitweise Operationen funktionieren gut mit Booleans
Die Verwendung von Bitwise-Operatoren mit Booleschen Operatoren ist durchaus zulässig, so dass Java keinen Syntaxfehler meldet.
Wenn ich einen JUnit-Test konstruiere, um eine Wahrheitstabelle sowohl für Bitweises ODER (|) als auch Bitweises UND (&) zu untersuchen, dann werden wir sehen, dass die Ausgaben des Bitweisen Operators mit der Wahrheitstabelle übereinstimmen. Angesichts dessen könnte man meinen, dass die Verwendung von Bitwise-Operatoren kein Problem darstellt.
AND-Wahrheitstabelle

@Test
void bitwiseOperatorsAndTruthTable(){
Assertions.assertEquals(true, true & true);
Assertions.assertEquals(false, true & false);
Assertions.assertEquals(false, false & true);
Assertions.assertEquals(false, false & false);
}
Der Test ist bestanden, dies ist vollkommen gültiges Java.
OR-Wahrheitstabelle

@Test
void bitwiseOperatorsOrTruthTable(){
Assertions.assertEquals(true, true | true);
Assertions.assertEquals(true, true | false);
Assertions.assertEquals(true, false | true);
Assertions.assertEquals(false, false | false);
}
Auch dieser Test besteht, warum bevorzugen wir "&&'und "||'?
Wahrheitstabellenbilder wurden mit dem Wahrheitstabellen-Werkzeug von web.standfor.edu.
Problem: Kurzschlussbetrieb
Das eigentliche Problem ist der Unterschied im Verhalten zwischen bitweisen (&, |) und booleschen (&&, ||) Operatoren.
Ein boolescher Operator ist ein Kurzschlussoperator und wertet nur so viel aus, wie er muss.
z.B.
if (args != null & args.length() > 23) {
System.out.println(args);
}
Im obigen Code werden beide booleschen Bedingungen ausgewertet, da der Bitwise-Operator verwendet wurde:
- args != null
- args.length() > 23
Das lässt meinen Code offen für eine NullPointerException, wenn args null ist, weil wir immer die Prüfung für args.length durchführen, auch wenn args null ist, weil beide booleschen Bedingungen ausgewertet werden müssen.
Boolesche Operatoren Kurzschlussauswertung
Wenn ein && verwendet wird, z. B.
if (args != null && args.length() > 23) {
System.out.println(args);
}
Sobald wir wissen, dass args != null zu false ausgewertet wird, stoppt die Auswertung des Bedingungsausdrucks.
Die rechte Seite brauchen wir nicht auszuwerten.
Unabhängig vom Ergebnis der Bedingung auf der rechten Seite ist der Endwert des booleschen Ausdrucks falsch.
Aber das würde im Produktionscode nie passieren
Dies ist ein ziemlich leicht zu begehender Fehler, der nicht immer von statischen Analysetools erkannt wird.
Ich habe den folgenden Google Dork verwendet, um zu sehen, ob ich irgendwelche öffentlichen Beispiele für dieses Muster finden kann:
filetype:java if "!=null & "
Diese Suche brachte etwas Code von Android im RootWindowContainer
isDocument = intent != null & intent.isDocument()
Dies ist die Art von Code, die eine Codeprüfung bestehen könnte, weil wir oft Bitwise-Operatoren in Zuweisungsanweisungen verwenden, um Werte zu maskieren. Aber in diesem Fall ist das Ergebnis das gleiche wie im obigen Beispiel der if-Anweisung. Wenn intent jemals null ist, dann wird eine NullPointerException geworfen.
Sehr oft kommen wir mit diesem Konstrukt davon, weil wir oft defensiv codieren und redundanten Code schreiben. Die Prüfung auf != null mag in den meisten Anwendungsfällen durchaus redundant sein.
Dies ist ein Fehler, der von Programmierern im Produktionscode gemacht wird.
Ich weiß nicht, wie aktuell die Ergebnisse für die Suche sind, aber als ich die Suche ausgeführt habe, gab es Ergebnisse zurück mit Code von: Google, Amazon, Apache... und mir.
Eine kürzliche Pull-Anfrage in einem meiner Open-Source-Projekte sollte genau diesen Fehler beheben.
if(type!=null & type.trim().length()>0){
acceptMediaTypeDefinitionsList.add(type.trim());
}
Wie Sie das finden
Als ich meinen Beispielcode in ein paar statischen Analysatoren überprüft habe, hat keiner von ihnen diesen versteckten Selbstzerstörungscode gefunden.
Als Team auf Secure Code Warrior haben wir ein recht einfaches Sensei Rezept erstellt und überprüft, das dies auffangen kann.
Da Bitwise-Operatoren durchaus zulässig sind und häufig in Zuweisungen verwendet werden, haben wir uns auf den Anwendungsfall von if-Anweisungen und die Verwendung von Bitwise & konzentriert, um den problematischen Code zu finden.
search:
expression:
anyOf:
- in:
condition: {}
value:
caseSensitive: false
matches: ".* & .*"
Hier wird ein regulärer Ausdruck verwendet, um mit " & " übereinzustimmen, wenn er als Bedingungsausdruck verwendet wird. z. B. in einer if-Anweisung.
Um das zu beheben, haben wir wieder auf reguläre Ausdrücke zurückgegriffen. Diesmal mit der sed-Funktion im QuickFix, um das & im Ausdruck global durch && zu ersetzen.
availableFixes:
- name: "Replace bitwise AND operator to logical AND operator"
actions:
- rewrite:
to: "{{#sed}}s/&/&&/g,{{{ . }}}{{/sed}}"
Ende Anmerkungen
Dies deckt den häufigsten Missbrauch eines Bitwise-Operators ab, d. h. wenn eigentlich ein boolescher Operator beabsichtigt war.
Es gibt andere Situationen, in denen dies auftreten könnte, z. B. das Zuordnungsbeispiel, aber beim Schreiben von Rezepten müssen wir versuchen, eine falsch-positive Identifizierung zu vermeiden, sonst werden Rezepte ignoriert oder ausgeschaltet. Wir erstellen Rezepte, die den häufigsten Vorkommnissen entsprechen. Wenn sich Sensei weiterentwickelt, werden wir möglicherweise zusätzliche Spezifität in die Suchfunktion einbauen, um mehr passende Bedingungen abzudecken.
In seiner aktuellen Form würde dieses Rezept viele der Live-Anwendungsfälle identifizieren, und vor allem den, der in meinem Projekt berichtet wurde.
HINWEIS: Eine ganze Reihe von Code-Kriegern hat zu diesem Beispiel und der Rezeptüberprüfung beigetragen - Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Vielen Dank für Ihre Hilfe.
---
Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.
Wir haben eine Menge Quellcode und Rezepte für diese Blog-Beiträge (einschließlich dieses Beitrags) im `sensei-blog-examples`-Repository im Secure Code Warrior GitHub-Konto.
https://github.com/securecodewarrior/sensei-blog-examples
Inhaltsübersicht
Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Demo buchenHerunterladenRessourcen für den Einstieg
Professionelle Dienstleistungen - Beschleunigen Sie mit Fachwissen
Das PSS-Team (Program Strategy Services) von Secure Code Warriorunterstützt Sie beim Aufbau, der Verbesserung und der Optimierung Ihres Programms für sichere Codierung. Ganz gleich, ob Sie neu anfangen oder Ihren Ansatz verfeinern möchten, unsere Experten bieten Ihnen maßgeschneiderte Beratung.
Themen und Inhalte der Schulung zu sicherem Code
Unsere branchenführenden Inhalte werden ständig weiterentwickelt, um sie an die sich ständig verändernde Softwareentwicklungslandschaft anzupassen und Ihre Rolle zu berücksichtigen. Die Themen reichen von KI bis XQuery Injection und werden für eine Vielzahl von Rollen angeboten, von Architekten und Ingenieuren bis hin zu Produktmanagern und QA. Verschaffen Sie sich einen kleinen Überblick über die Inhalte, die unser Katalog nach Thema und Rolle bietet.
Quests: Branchenführendes Lernen, damit die Entwickler immer einen Schritt voraus sind und Risiken minimiert werden.
Quests ist eine learning platform , die Entwicklern hilft, Software-Sicherheitsrisiken zu verringern, indem sie ihre Fähigkeiten zur sicheren Programmierung verbessern. Mit kuratierten Lernpfaden, praktischen Herausforderungen und interaktiven Aktivitäten befähigt sie Entwickler, Schwachstellen zu erkennen und zu vermeiden.
Ressourcen für den Einstieg
Wird Vibe Coding Ihre Codebasis in eine Verbindungsparty verwandeln?
Vibe Coding ist wie eine College-Verbindungsparty, und AI ist das Herzstück aller Festivitäten, das Fass. Es macht eine Menge Spaß, sich auszutoben, kreativ zu werden und zu sehen, wohin die eigene Fantasie einen führen kann, aber nach ein paar Bierfässern ist das Trinken (oder die Verwendung von KI) in Maßen zweifellos die sicherere langfristige Lösung.
Das Jahrzehnt der Defenders: Secure Code Warrior Zehnte Runde
Secure Code WarriorDas Gründungsteam von SCW ist zusammengeblieben und hat das Schiff ein ganzes Jahrzehnt lang durch alle Lektionen, Triumphe und Rückschläge gesteuert. Wir vergrößern uns und sind bereit für unser nächstes Kapitel, SCW 2.0, als führendes Unternehmen im Risikomanagement für Entwickler.