
Java : Points à considérer - Opérateurs bit à bit ou booléens
Java : Points à considérer - Opérateurs bit à bit ou booléens
« Java Gotcha » - un type d'erreur courant qui peut être facilement introduit par inadvertance.
Un piège Java assez simple dans lequel on peut tomber accidentellement est le suivant : utiliser un opérateur bit à bit au lieu d'un opérateur de comparaison booléen.
Par exemple, une simple erreur de saisie peut entraîner l'écriture de « & » alors que vous souhaitiez réellement écrire « && ».
Une approche courante que nous apprenons lors de la révision du code est la suivante :
L'utilisation de « & » ou « | » dans une instruction conditionnelle n'est probablement pas prévue.
Dans cet article de blog, nous allons examiner l'heuristique et déterminer les moyens d'identifier et de résoudre ce problème de codage.
Quel est le problème ? Les opérations au niveau du bit fonctionnent correctement avec les booléens.
L'utilisation d'opérateurs bit à bit avec des valeurs booléennes est tout à fait valide. Java ne signalera donc pas d'erreur de syntaxe.
Si je crée un test JUnit pour examiner une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous constaterons que les sorties de l'opérateur Bitwise correspondent à la table de vérité. Compte tenu de cela, nous pourrions penser que l'utilisation d'opérateurs Bitwise ne pose pas de problème.
Table de vérité ET

@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) ;
}
Le test est réussi, le code Java est parfaitement valide.
Table de vérité OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Ce test est également valide, pourquoi préférons-nous « && » et « || » ?
Les images de la table de vérité ont été créées à l'aide de l' outil de table de vérité à partir de web.standfor.edu.
Problème : Fonctionnement en court-circuit
Le véritable problème réside dans la différence de comportement entre les opérateurs bit à bit (&, |) et booléens (&&, ||).
Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.
par exemple
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
Dans le code ci-dessus, les deux conditions booléennes seront évaluées, car l'opérateur Bitwise a été utilisé :
- des chiffons ! = inefficace
- args.length () > 23
Cela rend mon code vulnérable à une NullPointerException si args est nul, car nous continuerons à vérifier args.length, même lorsque args est nul, car les deux conditions booléennes doivent être évaluées.
Évaluation des courts-circuits par les opérateurs booléens
Lorsqu'un && est utilisé, par exemple
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
Dès que nous aurons cette information, Args ! = null renvoie la valeur False lorsque l'évaluation de l'expression de condition s'arrête.
Il n'est pas nécessaire d'évaluer le côté droit.
Quel que soit le résultat de la condition du côté droit, la valeur finale de l'expression booléenne sera fausse.
Cependant, cela ne se produirait jamais dans le code de production.
Il s'agit d'une erreur relativement facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.
J'ai utilisé le Google Dork suivant afin de déterminer si je pouvais trouver des exemples publics de ce modèle :
Type de fichier : java si « ! = nul & »
Cette recherche a permis de récupérer du code d'Android dans le RootWindowContainer
IsDocument = intention ! = null et Intent.isDocument ()
Ce type de code peut être soumis à une revue de code, car nous utilisons fréquemment des opérateurs bit à bit dans les instructions d'affectation pour masquer les valeurs. Cependant, dans ce cas, le résultat est identique à celui de l'exemple d'instruction if ci-dessus. Si l'intention est nulle, une exception NullPointerException sera levée.
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 contrôle pour ! = null peut être redondant dans la plupart des cas d'utilisation.
Il s'agit d'une erreur commise par les programmeurs dans le code de production.
Je ne sais pas si les résultats de la recherche sont à jour, mais lorsque je l'ai exécutée, des résultats contenant du code provenant de Google, Amazon, Apache... et moi ont été renvoyés.
Une récente demande d'extraction sur l'un de mes projets open source visait précisément à corriger cette erreur.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
Comment le trouver
Lorsque j'ai examiné mon exemple de code dans plusieurs analyseurs statiques, aucun d'entre eux n'a détecté ce code d'autodestruction caché.
En tant qu'équipe de Secure Code Warrior, nous avons élaboré et révisé une recette Sensei simple qui pourrait répondre à ce problème.
Les opérateurs bit à bit étant parfaitement valides et fréquemment utilisés dans les affectations, nous nous sommes concentrés sur l'utilisation des instructions if et sur l'utilisation de Bitwise & pour identifier le code problématique.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Cela utilise une expression régulière pour correspondre à « & » lorsqu'elle est utilisée comme expression de condition, par exemple dans une instruction if.
Pour résoudre ce problème, nous avons de nouveau utilisé des expressions régulières. Cette fois, veuillez utiliser la fonction sed de QuickFix pour remplacer globalement le & dans l'expression par &&.
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}} »
Notes de fin
Cela couvre l'utilisation abusive la plus courante d'un opérateur Bitwise, c'est-à-dire lorsqu'un opérateur booléen était réellement prévu.
Dans d'autres situations, cela peut survenir, par exemple l'exemple d'affectation, mais lors de la rédaction de recettes, nous devons essayer d'éviter une identification faussement positive, sinon les recettes seront ignorées ou désactivées. Nous élaborons des recettes qui correspondent aux événements les plus courants. Au fur et à mesure de l'évolution de Sensei, nous pourrions ajouter une spécificité supplémentaire à la fonctionnalité de recherche afin de couvrir davantage de conditions correspondantes.
Dans sa forme actuelle, cette approche permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.
REMARQUE : Plusieurs experts en codage ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Nous vous remercions pour votre aide.
---
Vous pouvez installer Sensei IntelliJ en accédant à « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis en recherchant simplement «Sensei Code ».
Nous disposons d'une quantité importante de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel «sensei » du compte GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Pour en savoir plus sur Sensei
Dans cet article de blog, nous examinons une erreur courante de codage Java (l'utilisation d'un opérateur au niveau du bit au lieu d'un opérateur conditionnel), l'erreur à laquelle elle rend notre code vulnérable et la manière dont nous pouvons utiliser Sensei corriger et détecter le problème.
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.

Secure Code Warrior là pour aider votre organisation à sécuriser le code tout au long du cycle de développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable de la sécurité des applications, développeur, responsable de la sécurité informatique ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.
Veuillez réserver une démonstration.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.
Java : Points à considérer - Opérateurs bit à bit ou booléens
« Java Gotcha » - un type d'erreur courant qui peut être facilement introduit par inadvertance.
Un piège Java assez simple dans lequel on peut tomber accidentellement est le suivant : utiliser un opérateur bit à bit au lieu d'un opérateur de comparaison booléen.
Par exemple, une simple erreur de saisie peut entraîner l'écriture de « & » alors que vous souhaitiez réellement écrire « && ».
Une approche courante que nous apprenons lors de la révision du code est la suivante :
L'utilisation de « & » ou « | » dans une instruction conditionnelle n'est probablement pas prévue.
Dans cet article de blog, nous allons examiner l'heuristique et déterminer les moyens d'identifier et de résoudre ce problème de codage.
Quel est le problème ? Les opérations au niveau du bit fonctionnent correctement avec les booléens.
L'utilisation d'opérateurs bit à bit avec des valeurs booléennes est tout à fait valide. Java ne signalera donc pas d'erreur de syntaxe.
Si je crée un test JUnit pour examiner une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous constaterons que les sorties de l'opérateur Bitwise correspondent à la table de vérité. Compte tenu de cela, nous pourrions penser que l'utilisation d'opérateurs Bitwise ne pose pas de problème.
Table de vérité ET

@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) ;
}
Le test est réussi, le code Java est parfaitement valide.
Table de vérité OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Ce test est également valide, pourquoi préférons-nous « && » et « || » ?
Les images de la table de vérité ont été créées à l'aide de l' outil de table de vérité à partir de web.standfor.edu.
Problème : Fonctionnement en court-circuit
Le véritable problème réside dans la différence de comportement entre les opérateurs bit à bit (&, |) et booléens (&&, ||).
Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.
par exemple
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
Dans le code ci-dessus, les deux conditions booléennes seront évaluées, car l'opérateur Bitwise a été utilisé :
- des chiffons ! = inefficace
- args.length () > 23
Cela rend mon code vulnérable à une NullPointerException si args est nul, car nous continuerons à vérifier args.length, même lorsque args est nul, car les deux conditions booléennes doivent être évaluées.
Évaluation des courts-circuits par les opérateurs booléens
Lorsqu'un && est utilisé, par exemple
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
Dès que nous aurons cette information, Args ! = null renvoie la valeur False lorsque l'évaluation de l'expression de condition s'arrête.
Il n'est pas nécessaire d'évaluer le côté droit.
Quel que soit le résultat de la condition du côté droit, la valeur finale de l'expression booléenne sera fausse.
Cependant, cela ne se produirait jamais dans le code de production.
Il s'agit d'une erreur relativement facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.
J'ai utilisé le Google Dork suivant afin de déterminer si je pouvais trouver des exemples publics de ce modèle :
Type de fichier : java si « ! = nul & »
Cette recherche a permis de récupérer du code d'Android dans le RootWindowContainer
IsDocument = intention ! = null et Intent.isDocument ()
Ce type de code peut être soumis à une revue de code, car nous utilisons fréquemment des opérateurs bit à bit dans les instructions d'affectation pour masquer les valeurs. Cependant, dans ce cas, le résultat est identique à celui de l'exemple d'instruction if ci-dessus. Si l'intention est nulle, une exception NullPointerException sera levée.
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 contrôle pour ! = null peut être redondant dans la plupart des cas d'utilisation.
Il s'agit d'une erreur commise par les programmeurs dans le code de production.
Je ne sais pas si les résultats de la recherche sont à jour, mais lorsque je l'ai exécutée, des résultats contenant du code provenant de Google, Amazon, Apache... et moi ont été renvoyés.
Une récente demande d'extraction sur l'un de mes projets open source visait précisément à corriger cette erreur.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
Comment le trouver
Lorsque j'ai examiné mon exemple de code dans plusieurs analyseurs statiques, aucun d'entre eux n'a détecté ce code d'autodestruction caché.
En tant qu'équipe de Secure Code Warrior, nous avons élaboré et révisé une recette Sensei simple qui pourrait répondre à ce problème.
Les opérateurs bit à bit étant parfaitement valides et fréquemment utilisés dans les affectations, nous nous sommes concentrés sur l'utilisation des instructions if et sur l'utilisation de Bitwise & pour identifier le code problématique.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Cela utilise une expression régulière pour correspondre à « & » lorsqu'elle est utilisée comme expression de condition, par exemple dans une instruction if.
Pour résoudre ce problème, nous avons de nouveau utilisé des expressions régulières. Cette fois, veuillez utiliser la fonction sed de QuickFix pour remplacer globalement le & dans l'expression par &&.
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}} »
Notes de fin
Cela couvre l'utilisation abusive la plus courante d'un opérateur Bitwise, c'est-à-dire lorsqu'un opérateur booléen était réellement prévu.
Dans d'autres situations, cela peut survenir, par exemple l'exemple d'affectation, mais lors de la rédaction de recettes, nous devons essayer d'éviter une identification faussement positive, sinon les recettes seront ignorées ou désactivées. Nous élaborons des recettes qui correspondent aux événements les plus courants. Au fur et à mesure de l'évolution de Sensei, nous pourrions ajouter une spécificité supplémentaire à la fonctionnalité de recherche afin de couvrir davantage de conditions correspondantes.
Dans sa forme actuelle, cette approche permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.
REMARQUE : Plusieurs experts en codage ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Nous vous remercions pour votre aide.
---
Vous pouvez installer Sensei IntelliJ en accédant à « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis en recherchant simplement «Sensei Code ».
Nous disposons d'une quantité importante de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel «sensei » du compte GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Pour en savoir plus sur Sensei
Java : Points à considérer - Opérateurs bit à bit ou booléens
« Java Gotcha » - un type d'erreur courant qui peut être facilement introduit par inadvertance.
Un piège Java assez simple dans lequel on peut tomber accidentellement est le suivant : utiliser un opérateur bit à bit au lieu d'un opérateur de comparaison booléen.
Par exemple, une simple erreur de saisie peut entraîner l'écriture de « & » alors que vous souhaitiez réellement écrire « && ».
Une approche courante que nous apprenons lors de la révision du code est la suivante :
L'utilisation de « & » ou « | » dans une instruction conditionnelle n'est probablement pas prévue.
Dans cet article de blog, nous allons examiner l'heuristique et déterminer les moyens d'identifier et de résoudre ce problème de codage.
Quel est le problème ? Les opérations au niveau du bit fonctionnent correctement avec les booléens.
L'utilisation d'opérateurs bit à bit avec des valeurs booléennes est tout à fait valide. Java ne signalera donc pas d'erreur de syntaxe.
Si je crée un test JUnit pour examiner une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous constaterons que les sorties de l'opérateur Bitwise correspondent à la table de vérité. Compte tenu de cela, nous pourrions penser que l'utilisation d'opérateurs Bitwise ne pose pas de problème.
Table de vérité ET

@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) ;
}
Le test est réussi, le code Java est parfaitement valide.
Table de vérité OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Ce test est également valide, pourquoi préférons-nous « && » et « || » ?
Les images de la table de vérité ont été créées à l'aide de l' outil de table de vérité à partir de web.standfor.edu.
Problème : Fonctionnement en court-circuit
Le véritable problème réside dans la différence de comportement entre les opérateurs bit à bit (&, |) et booléens (&&, ||).
Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.
par exemple
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
Dans le code ci-dessus, les deux conditions booléennes seront évaluées, car l'opérateur Bitwise a été utilisé :
- des chiffons ! = inefficace
- args.length () > 23
Cela rend mon code vulnérable à une NullPointerException si args est nul, car nous continuerons à vérifier args.length, même lorsque args est nul, car les deux conditions booléennes doivent être évaluées.
Évaluation des courts-circuits par les opérateurs booléens
Lorsqu'un && est utilisé, par exemple
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
Dès que nous aurons cette information, Args ! = null renvoie la valeur False lorsque l'évaluation de l'expression de condition s'arrête.
Il n'est pas nécessaire d'évaluer le côté droit.
Quel que soit le résultat de la condition du côté droit, la valeur finale de l'expression booléenne sera fausse.
Cependant, cela ne se produirait jamais dans le code de production.
Il s'agit d'une erreur relativement facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.
J'ai utilisé le Google Dork suivant afin de déterminer si je pouvais trouver des exemples publics de ce modèle :
Type de fichier : java si « ! = nul & »
Cette recherche a permis de récupérer du code d'Android dans le RootWindowContainer
IsDocument = intention ! = null et Intent.isDocument ()
Ce type de code peut être soumis à une revue de code, car nous utilisons fréquemment des opérateurs bit à bit dans les instructions d'affectation pour masquer les valeurs. Cependant, dans ce cas, le résultat est identique à celui de l'exemple d'instruction if ci-dessus. Si l'intention est nulle, une exception NullPointerException sera levée.
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 contrôle pour ! = null peut être redondant dans la plupart des cas d'utilisation.
Il s'agit d'une erreur commise par les programmeurs dans le code de production.
Je ne sais pas si les résultats de la recherche sont à jour, mais lorsque je l'ai exécutée, des résultats contenant du code provenant de Google, Amazon, Apache... et moi ont été renvoyés.
Une récente demande d'extraction sur l'un de mes projets open source visait précisément à corriger cette erreur.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
Comment le trouver
Lorsque j'ai examiné mon exemple de code dans plusieurs analyseurs statiques, aucun d'entre eux n'a détecté ce code d'autodestruction caché.
En tant qu'équipe de Secure Code Warrior, nous avons élaboré et révisé une recette Sensei simple qui pourrait répondre à ce problème.
Les opérateurs bit à bit étant parfaitement valides et fréquemment utilisés dans les affectations, nous nous sommes concentrés sur l'utilisation des instructions if et sur l'utilisation de Bitwise & pour identifier le code problématique.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Cela utilise une expression régulière pour correspondre à « & » lorsqu'elle est utilisée comme expression de condition, par exemple dans une instruction if.
Pour résoudre ce problème, nous avons de nouveau utilisé des expressions régulières. Cette fois, veuillez utiliser la fonction sed de QuickFix pour remplacer globalement le & dans l'expression par &&.
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}} »
Notes de fin
Cela couvre l'utilisation abusive la plus courante d'un opérateur Bitwise, c'est-à-dire lorsqu'un opérateur booléen était réellement prévu.
Dans d'autres situations, cela peut survenir, par exemple l'exemple d'affectation, mais lors de la rédaction de recettes, nous devons essayer d'éviter une identification faussement positive, sinon les recettes seront ignorées ou désactivées. Nous élaborons des recettes qui correspondent aux événements les plus courants. Au fur et à mesure de l'évolution de Sensei, nous pourrions ajouter une spécificité supplémentaire à la fonctionnalité de recherche afin de couvrir davantage de conditions correspondantes.
Dans sa forme actuelle, cette approche permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.
REMARQUE : Plusieurs experts en codage ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Nous vous remercions pour votre aide.
---
Vous pouvez installer Sensei IntelliJ en accédant à « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis en recherchant simplement «Sensei Code ».
Nous disposons d'une quantité importante de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel «sensei » du compte GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Pour en savoir plus sur Sensei

Veuillez cliquer sur le lien ci-dessous et télécharger le PDF de cette ressource.
Secure Code Warrior là pour aider votre organisation à sécuriser le code tout au long du cycle de développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable de la sécurité des applications, développeur, responsable de la sécurité informatique ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.
Veuillez consulter le rapportVeuillez réserver une démonstration.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.
Java : Points à considérer - Opérateurs bit à bit ou booléens
« Java Gotcha » - un type d'erreur courant qui peut être facilement introduit par inadvertance.
Un piège Java assez simple dans lequel on peut tomber accidentellement est le suivant : utiliser un opérateur bit à bit au lieu d'un opérateur de comparaison booléen.
Par exemple, une simple erreur de saisie peut entraîner l'écriture de « & » alors que vous souhaitiez réellement écrire « && ».
Une approche courante que nous apprenons lors de la révision du code est la suivante :
L'utilisation de « & » ou « | » dans une instruction conditionnelle n'est probablement pas prévue.
Dans cet article de blog, nous allons examiner l'heuristique et déterminer les moyens d'identifier et de résoudre ce problème de codage.
Quel est le problème ? Les opérations au niveau du bit fonctionnent correctement avec les booléens.
L'utilisation d'opérateurs bit à bit avec des valeurs booléennes est tout à fait valide. Java ne signalera donc pas d'erreur de syntaxe.
Si je crée un test JUnit pour examiner une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous constaterons que les sorties de l'opérateur Bitwise correspondent à la table de vérité. Compte tenu de cela, nous pourrions penser que l'utilisation d'opérateurs Bitwise ne pose pas de problème.
Table de vérité ET

@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) ;
}
Le test est réussi, le code Java est parfaitement valide.
Table de vérité OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Ce test est également valide, pourquoi préférons-nous « && » et « || » ?
Les images de la table de vérité ont été créées à l'aide de l' outil de table de vérité à partir de web.standfor.edu.
Problème : Fonctionnement en court-circuit
Le véritable problème réside dans la différence de comportement entre les opérateurs bit à bit (&, |) et booléens (&&, ||).
Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.
par exemple
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
Dans le code ci-dessus, les deux conditions booléennes seront évaluées, car l'opérateur Bitwise a été utilisé :
- des chiffons ! = inefficace
- args.length () > 23
Cela rend mon code vulnérable à une NullPointerException si args est nul, car nous continuerons à vérifier args.length, même lorsque args est nul, car les deux conditions booléennes doivent être évaluées.
Évaluation des courts-circuits par les opérateurs booléens
Lorsqu'un && est utilisé, par exemple
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
Dès que nous aurons cette information, Args ! = null renvoie la valeur False lorsque l'évaluation de l'expression de condition s'arrête.
Il n'est pas nécessaire d'évaluer le côté droit.
Quel que soit le résultat de la condition du côté droit, la valeur finale de l'expression booléenne sera fausse.
Cependant, cela ne se produirait jamais dans le code de production.
Il s'agit d'une erreur relativement facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.
J'ai utilisé le Google Dork suivant afin de déterminer si je pouvais trouver des exemples publics de ce modèle :
Type de fichier : java si « ! = nul & »
Cette recherche a permis de récupérer du code d'Android dans le RootWindowContainer
IsDocument = intention ! = null et Intent.isDocument ()
Ce type de code peut être soumis à une revue de code, car nous utilisons fréquemment des opérateurs bit à bit dans les instructions d'affectation pour masquer les valeurs. Cependant, dans ce cas, le résultat est identique à celui de l'exemple d'instruction if ci-dessus. Si l'intention est nulle, une exception NullPointerException sera levée.
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 contrôle pour ! = null peut être redondant dans la plupart des cas d'utilisation.
Il s'agit d'une erreur commise par les programmeurs dans le code de production.
Je ne sais pas si les résultats de la recherche sont à jour, mais lorsque je l'ai exécutée, des résultats contenant du code provenant de Google, Amazon, Apache... et moi ont été renvoyés.
Une récente demande d'extraction sur l'un de mes projets open source visait précisément à corriger cette erreur.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
Comment le trouver
Lorsque j'ai examiné mon exemple de code dans plusieurs analyseurs statiques, aucun d'entre eux n'a détecté ce code d'autodestruction caché.
En tant qu'équipe de Secure Code Warrior, nous avons élaboré et révisé une recette Sensei simple qui pourrait répondre à ce problème.
Les opérateurs bit à bit étant parfaitement valides et fréquemment utilisés dans les affectations, nous nous sommes concentrés sur l'utilisation des instructions if et sur l'utilisation de Bitwise & pour identifier le code problématique.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Cela utilise une expression régulière pour correspondre à « & » lorsqu'elle est utilisée comme expression de condition, par exemple dans une instruction if.
Pour résoudre ce problème, nous avons de nouveau utilisé des expressions régulières. Cette fois, veuillez utiliser la fonction sed de QuickFix pour remplacer globalement le & dans l'expression par &&.
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}} »
Notes de fin
Cela couvre l'utilisation abusive la plus courante d'un opérateur Bitwise, c'est-à-dire lorsqu'un opérateur booléen était réellement prévu.
Dans d'autres situations, cela peut survenir, par exemple l'exemple d'affectation, mais lors de la rédaction de recettes, nous devons essayer d'éviter une identification faussement positive, sinon les recettes seront ignorées ou désactivées. Nous élaborons des recettes qui correspondent aux événements les plus courants. Au fur et à mesure de l'évolution de Sensei, nous pourrions ajouter une spécificité supplémentaire à la fonctionnalité de recherche afin de couvrir davantage de conditions correspondantes.
Dans sa forme actuelle, cette approche permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.
REMARQUE : Plusieurs experts en codage ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Nous vous remercions pour votre aide.
---
Vous pouvez installer Sensei IntelliJ en accédant à « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis en recherchant simplement «Sensei Code ».
Nous disposons d'une quantité importante de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel «sensei » du compte GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Pour en savoir plus sur Sensei
Table des matières
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.

Secure Code Warrior là pour aider votre organisation à sécuriser le code tout au long du cycle de développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable de la sécurité des applications, développeur, responsable de la sécurité informatique ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.
Veuillez réserver une démonstration.TéléchargerRessources pour vous aider à démarrer
Thèmes et contenus de formation sur le code sécurisé
Notre contenu de pointe évolue constamment pour s'adapter à l'évolution constante du paysage du développement de logiciels tout en tenant compte de votre rôle. Des sujets couvrant tout, de l'IA à l'injection XQuery, proposés pour une variété de postes, allant des architectes aux ingénieurs en passant par les chefs de produit et l'assurance qualité. Découvrez un aperçu de ce que notre catalogue de contenu a à offrir par sujet et par rôle.
La Chambre de commerce établit la norme en matière de sécurité à grande échelle axée sur les développeurs
La Chambre de commerce néerlandaise explique comment elle a intégré le codage sécurisé dans le développement quotidien grâce à des certifications basées sur les rôles, à l'évaluation comparative du Trust Score et à une culture de responsabilité partagée en matière de sécurité.
Modélisation des menaces avec l'IA : transformer chaque développeur en modélisateur de menaces
Vous repartirez mieux équipé pour aider les développeurs à combiner les idées et les techniques de modélisation des menaces avec les outils d'IA qu'ils utilisent déjà pour renforcer la sécurité, améliorer la collaboration et créer des logiciels plus résilients dès le départ.
Ressources pour vous aider à démarrer
Cybermon est de retour : les missions Beat the Boss sont désormais disponibles sur demande.
Cybermon 2025 : Vaincre le Boss est désormais accessible toute l'année dans SCW. Mettez en œuvre des défis de sécurité avancés liés à l'IA et au LLM afin de renforcer le développement sécurisé de l'IA à grande échelle.
Explication de la loi sur la cyber-résilience : implications pour le développement de logiciels sécurisés dès leur conception
Découvrez les exigences de la loi européenne sur la cyber-résilience (CRA), à qui elle s'applique et comment les équipes d'ingénieurs peuvent se préparer grâce à des pratiques de sécurité dès la conception, à la prévention des vulnérabilités et au renforcement des capacités des développeurs.
Facilitateur 1 : Critères de réussite clairement définis et mesurables
Enabler 1 inaugure notre série en 10 parties intitulée « Enablers of Success » en démontrant comment associer le codage sécurisé à des résultats commerciaux tels que la réduction des risques et la rapidité afin d'assurer la maturité à long terme des programmes.




%20(1).avif)
.avif)
