Pièges en Java : opérateurs bit à bit vs booléens
Pièges Java - Opérateurs bit à bit vs booléens
> « Piège Java » - un modèle d'erreur courant, facile à commettre par inadvertance.
Un piège Java assez simple dans lequel tomber par erreur est : utiliser un opérateur bit à bit au lieu d'un opérateur de comparaison booléen.
Par exemple, une simple faute de frappe peut conduire à écrire « & » alors que vous vouliez réellement écrire « && ».
Une règle heuristique courante lors de la revue de code est :
> « & » ou « | » utilisés dans une instruction conditionnelle ne sont probablement pas intentionnels.
Dans cet article, nous explorerons cette heuristique et identifierons des moyens de repérer et de corriger ce problème de codage.
Quel est le problème ? Les opérations bit à bit fonctionnent avec les booléens
L'utilisation d'opérateurs bit à bit avec des booléens est parfaitement valide, Java ne signalera donc aucune erreur de syntaxe.
Si je crée un test JUnit pour explorer une table de vérité pour le OU bit à bit (|) et le ET bit à bit (&), nous verrons que les résultats de l'opérateur bit à bit correspondent à la table de vérité. Étant donné cela, on pourrait penser que l'utilisation d'opérateurs bit à bit ne pose pas de problème.
Table de vérité ET

@Test
void bitwiseOperatorsAndTruthTable(){
Assertions.assertEquals(true, true & true);
Assertions.assertEquals(false, true & false);
Assertions.assertEquals(false, false & true);
Assertions.assertEquals(false, false & false);
}
Le test réussit, c'est du Java parfaitement valide.
Table de vérité OU

@Test
void bitwiseOperatorsOrTruthTable(){
Assertions.assertEquals(true, true | true);
Assertions.assertEquals(true, true | false);
Assertions.assertEquals(true, false | true);
Assertions.assertEquals(false, false | false);
}
Ce test réussit également, alors pourquoi préférons-nous « && » et « || » ?
Les images de tables de vérité ont été créées à l'aide de l'outil de table de vérité de web.standfor.edu.
Problème : Évaluation en court-circuit
Le véritable problème réside dans la différence de comportement entre les opérateurs bit à bit (&, |) et les opérateurs booléens (&&, ||).
Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce qui est strictement nécessaire.
ex.
if (args != null & args.length() > 23) {
System.out.println(args);
}
Dans le code ci-dessus, les deux conditions booléennes sont évaluées car l'opérateur bit à bit a été utilisé :
- args != null
- args.length() > 23
Cela expose mon code à une NullPointerException si args est nul, car nous effectuons systématiquement la vérification de args.length, même lorsque args est nul, puisque les deux conditions booléennes doivent être évaluées.
Évaluation en court-circuit des opérateurs booléens
Lorsqu'un && est utilisé, par ex.
if (args != null && args.length() > 23) {
System.out.println(args);
}
Dès que nous savons que args != null est faux, l'évaluation de l'expression conditionnelle s'arrête.
Il n'est pas nécessaire d'évaluer le membre de droite.
Quel que soit le résultat de la condition de droite, la valeur finale de l'expression booléenne sera fausse.
Mais cela n'arriverait jamais dans du code de production
C'est une erreur assez facile à commettre qui n'est pas toujours détectée par les outils d'analyse statique.
J'ai utilisé la requête Google Dork suivante pour voir si je pouvais trouver des exemples publics de ce modèle :
filetype:java if "!=null & "
Cette recherche a permis de trouver du code provenant d'Android dans RootWindowContainer
isDocument = intent != null & intent.isDocument()
C'est le genre de code qui pourrait passer une revue de code, car nous utilisons souvent des opérateurs bit à bit dans des instructions d'affectation pour masquer des valeurs. Mais dans ce cas précis, le résultat est identique à l'exemple d'instruction if ci-dessus. Si intent est nul, une NullPointerException sera levée.
Nous nous en sortons souvent avec cette construction car nous codons fréquemment de manière défensive et écrivons du code redondant. La vérification != null est probablement superflue dans la plupart des cas.
Il s'agit d'une erreur commise par des développeurs dans du code en production.
Je ne sais pas si les résultats de la recherche sont à jour, mais lorsque je l'ai effectuée, j'ai obtenu du code provenant de : Google, Amazon, Apache... et moi-même.
Une pull request récente sur l'un de mes projets open source visait précisément à corriger cette erreur.
if(type!=null & type.trim().length()>0){
acceptMediaTypeDefinitionsList.add(type.trim());
}
Comment détecter ce problème
Lorsque j'ai testé mon exemple de code avec plusieurs analyseurs statiques, aucun n'a détecté ce code autodestructeur caché.
En tant qu'équipe chez Secure Code Warrior, nous avons créé et examiné une recette Sensei assez simple capable de le détecter.
Comme les opérateurs bit à bit sont parfaitement valides et souvent utilisés dans les assignations, nous nous sommes concentrés sur le cas d'utilisation des instructions if et sur l'usage de l'opérateur bit à bit & pour identifier le code problématique.
search:
expression:
anyOf:
- in:
condition: {}
value:
caseSensitive: false
matches: ".* & .*"
Ceci utilise une expression régulière pour trouver " & " lorsqu'il est utilisé dans une condition, par exemple dans une instruction if.
Pour corriger cela, nous avons de nouveau eu recours aux expressions régulières. Cette fois, en utilisant la fonction sed dans le QuickFix pour remplacer globalement le & par && dans l'expression.
availableFixes:
- name: "Remplacer l'opérateur AND bit à bit par l'opérateur AND logique"
actions:
- rewrite:
to: "{{#sed}}s/&/&&/g,{{{ . }}}{{/sed}}"
Notes finales
Ceci couvre l'utilisation abusive la plus courante d'un opérateur bit à bit, c'est-à-dire lorsqu'un opérateur booléen était en réalité attendu.
Il existe d'autres situations où cela pourrait se produire, comme dans l'exemple d'assignation, mais lors de l'écriture de recettes, nous devons essayer d'éviter les faux positifs, sinon les recettes seront ignorées ou désactivées. Nous créons des recettes pour correspondre aux occurrences les plus fréquentes. À mesure que Sensei évolue, nous pourrions ajouter une précision supplémentaire à la fonctionnalité de recherche pour couvrir davantage de conditions de correspondance.
Sous sa forme actuelle, cette recette identifierait bon nombre des cas d'utilisation réels et, plus important encore, celui qui a été signalé dans mon projet.
NOTE : Plusieurs code warriors ont contribué à cet exemple et à la révision de la recette - Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Merci pour votre aide.
---
Vous pouvez installer Sensei depuis IntelliJ en utilisant "Preferences \ Plugins" (Mac) ou "Settings \ Plugins" (Windows), puis recherchez simplement "sensei secure code".
Nous disposons d'une grande quantité de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le dépôt `sensei-blog-examples` du compte GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Gouvernez le développement assisté par IA avant la mise en production
Évaluez les risques liés à l'IA, appliquez des politiques de codage sécurisé dès le commit et accélérez la livraison sécurisée tout au long de votre cycle de développement.
Explorer plus d'articles
Accédez à du contenu expert sur le codage sécurisé, la gouvernance de l'IA et la gestion des risques logiciels.
%252520%252520(3).avif)
Supercharged Security Awareness: How Tournaments are Inspiring Developers at Erste Group
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

Security as culture: How Blue Prism cultivates world-class secure developers
Learn how Blue Prism, the global leader in intelligent automation for the enterprise, used Secure Code Warrior's agile learning platform to create a security-first culture with their developers, achieve their business goals, and ship secure code at speed

Une culture de la sécurité : comment Sage a bâti son programme de champions
Découvrez comment Sage a renforcé sa sécurité grâce à une approche flexible axée sur les relations humaines, formant plus de 200 champions de la sécurité et obtenant une réduction mesurable des risques.

Mois de la sensibilisation à la cybersécurité 2026 : comprendre la sécurité de l'IA est essentiel à la défense de l'entreprise
Nous avons atteint un point où la plupart des grandes entreprises d'IA ont publiquement appelé à un ralentissement mondial du développement de l'IA afin de permettre aux garde-fous de sécurité de rattraper leur retard. Pourtant, la réalité est que de graves problèmes de sécurité se sont déjà concrétisés. Cela place d'innombrables responsables de la sécurité et équipes de direction dans une situation d'urgence, alors que les coûts financiers et les risques liés à la mise en œuvre de l'IA ne cessent de s'accumuler.

Levier 8 : Valoriser votre programme
Un programme de codage sécurisé a besoin de plus qu'un contenu de qualité pour réussir. Le levier 8 montre comment l'image de marque transforme la participation en une expérience convoitée, axée sur le statut.
.avif)
Chaque employé est désormais en première ligne de la cybersécurité IA
Le paysage technologique des entreprises évolue à une vitesse que peu avaient anticipée avant qu'il ne soit trop tard. Nous avons officiellement franchi le cap du code écrit par l'humain et de l'assistance basique par copilote pour entrer dans l'ère du cycle de vie de développement agentique (ADLC). Si les agents IA autonomes promettent une efficacité sans précédent dans de multiples fonctions, ils apportent également une toute nouvelle catégorie de risques en matière de sécurité et de réglementation.
Sécurisez le développement piloté par l'IA avant le déploiement
Identifiez les risques de développement, appliquez vos politiques et prévenez les vulnérabilités tout au long du cycle de vie de vos logiciels.
