SCW图标
英雄背景无分隔线
博客

Java Gotchas - Opérateurs bitwise ou booléens

艾伦-理查德森
2021 年 2 月 7 日 发布
最后更新于 2026年3月8日

Java Gotchas - Opérateurs bitwise ou booléens

> « Java Gotcha » - un modèle d'erreur courant facile à implémenter accidentellement.

Un piège Java assez simple dans lequel 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 vouliez vraiment écrire « && ».

Une heuristique courante que nous apprenons lors de la révision du code est la suivante :

> « & » ou « | » utilisé dans une instruction conditionnelle n'est probablement pas prévu.

Dans cet article de blog, nous allons explorer l'heuristique et identifier 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 bitwise avec des booléens est parfaitement valide. Java ne signalera donc pas d'erreur de syntaxe.

Si je construis un test JUnit pour explorer une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous verrons 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 n'est pas un problème.

ET Truth Table

有三栏是a,一栏是b,最后一栏是(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) ;
}


Le test est réussi, c'est du Java parfaitement valide.


OR真值表


三列是a,一列是b,最后一列是(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) ;
}


Ce test passe également, pourquoi préférons-nous « &&'et « ||' ?


Les images de la table de vérité ont été créées à l'aide du outil de table de vérité à partir de web.standfor.edu.


Problème : Fonctionnement en court-circuit


Le véritable problème est la différence de comportement entre les opérateurs bitwise (&, |) et booléens (&&, ||).

Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.

p. ex.

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 ! = nul
  • args.length () > 23

Cela laisse mon code ouvert à une NullPointerException si args est nul car nous effectuerons toujours la vérification de 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 saurons ça, Args ! = null donne la valeur False lorsque l'évaluation de l'expression de condition s'arrête.

Nous n'avons pas besoin 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.


Mais cela n'arriverait jamais dans le code de production


Il s'agit d'une erreur assez facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.

J'ai utilisé le Google Dork suivant pour voir 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 ()


C'est le type de code qui peut passer une revue de code car nous utilisons souvent des opérateurs bitwise dans les instructions d'affectation pour masquer les valeurs. Mais dans ce cas, le résultat est le même que dans 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 chèque 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 étaient renvoyés.

Un récent demande d'extraction sur l'un de mes projets open source était de corriger exactement cette erreur.

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


Comment le trouver


Lorsque j'ai vérifié mon exemple de code dans quelques 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 créé et révisé une recette Sensei assez simple qui pourrait répondre à ce problème.

Les opérateurs Bitwise étant parfaitement valides et souvent utilisés dans les affectations, nous nous sommes concentrés sur le cas d'utilisation des instructions if et sur l'utilisation de Bitwise & pour trouver 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 nous sommes à nouveau appuyés sur des expressions régulières. Cette fois, utilisez la fonction sed du 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 pour couvrir davantage de conditions correspondantes.

Dans sa forme actuelle, cette recette permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.

REMARQUE : De nombreux experts du code ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Merci pour ton aide.


---


Vous pouvez installer Sensei depuis IntelliJ en utilisant « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis recherchez simplement « Sensei Secure Code »

Nous avons beaucoup de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel « sensei-blog-examples » du compte GitHub de Secure Code Warrior.

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

En savoir plus sur Sensei


显示资源
显示资源

Dans cet article de blog, nous examinons une erreur de codage Java courante (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 pour 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 在整个软件开发周期中保障代码安全,并营造将网络安全置于首位的企业文化。无论您是应用安全负责人、开发人员、信息安全主管,还是其他任何参与安全工作的人员,我们都能协助您的组织降低不安全代码带来的风险。

预约演示
分享到:
领英品牌社交x 标志
作者
艾伦-理查德森
2021年2月7日出版

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.

分享到:
领英品牌社交x 标志

Java Gotchas - Opérateurs bitwise ou booléens

> « Java Gotcha » - un modèle d'erreur courant facile à implémenter accidentellement.

Un piège Java assez simple dans lequel 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 vouliez vraiment écrire « && ».

Une heuristique courante que nous apprenons lors de la révision du code est la suivante :

> « & » ou « | » utilisé dans une instruction conditionnelle n'est probablement pas prévu.

Dans cet article de blog, nous allons explorer l'heuristique et identifier 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 bitwise avec des booléens est parfaitement valide. Java ne signalera donc pas d'erreur de syntaxe.

Si je construis un test JUnit pour explorer une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous verrons 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 n'est pas un problème.

ET Truth Table

有三栏是a,一栏是b,最后一栏是(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) ;
}


Le test est réussi, c'est du Java parfaitement valide.


OR真值表


三列是a,一列是b,最后一列是(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) ;
}


Ce test passe également, pourquoi préférons-nous « &&'et « ||' ?


Les images de la table de vérité ont été créées à l'aide du outil de table de vérité à partir de web.standfor.edu.


Problème : Fonctionnement en court-circuit


Le véritable problème est la différence de comportement entre les opérateurs bitwise (&, |) et booléens (&&, ||).

Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.

p. ex.

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 ! = nul
  • args.length () > 23

Cela laisse mon code ouvert à une NullPointerException si args est nul car nous effectuerons toujours la vérification de 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 saurons ça, Args ! = null donne la valeur False lorsque l'évaluation de l'expression de condition s'arrête.

Nous n'avons pas besoin 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.


Mais cela n'arriverait jamais dans le code de production


Il s'agit d'une erreur assez facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.

J'ai utilisé le Google Dork suivant pour voir 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 ()


C'est le type de code qui peut passer une revue de code car nous utilisons souvent des opérateurs bitwise dans les instructions d'affectation pour masquer les valeurs. Mais dans ce cas, le résultat est le même que dans 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 chèque 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 étaient renvoyés.

Un récent demande d'extraction sur l'un de mes projets open source était de corriger exactement cette erreur.

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


Comment le trouver


Lorsque j'ai vérifié mon exemple de code dans quelques 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 créé et révisé une recette Sensei assez simple qui pourrait répondre à ce problème.

Les opérateurs Bitwise étant parfaitement valides et souvent utilisés dans les affectations, nous nous sommes concentrés sur le cas d'utilisation des instructions if et sur l'utilisation de Bitwise & pour trouver 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 nous sommes à nouveau appuyés sur des expressions régulières. Cette fois, utilisez la fonction sed du 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 pour couvrir davantage de conditions correspondantes.

Dans sa forme actuelle, cette recette permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.

REMARQUE : De nombreux experts du code ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Merci pour ton aide.


---


Vous pouvez installer Sensei depuis IntelliJ en utilisant « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis recherchez simplement « Sensei Secure Code »

Nous avons beaucoup de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel « sensei-blog-examples » du compte GitHub de Secure Code Warrior.

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

En savoir plus sur Sensei


显示资源
显示资源

请填写以下表格以下载报告

我们希望获得您的授权,以便向您发送有关我们产品和/或安全编码相关主题的信息。我们将始终以最高标准谨慎处理您的个人数据,绝不会将其出售给其他企业用于营销目的。

提交
scw 成功图标
SCW 错误图标
要提交表单,请启用「Analytics」Cookie。完成操作后,请随时将其重新禁用。

Java Gotchas - Opérateurs bitwise ou booléens

> « Java Gotcha » - un modèle d'erreur courant facile à implémenter accidentellement.

Un piège Java assez simple dans lequel 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 vouliez vraiment écrire « && ».

Une heuristique courante que nous apprenons lors de la révision du code est la suivante :

> « & » ou « | » utilisé dans une instruction conditionnelle n'est probablement pas prévu.

Dans cet article de blog, nous allons explorer l'heuristique et identifier 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 bitwise avec des booléens est parfaitement valide. Java ne signalera donc pas d'erreur de syntaxe.

Si je construis un test JUnit pour explorer une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous verrons 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 n'est pas un problème.

ET Truth Table

有三栏是a,一栏是b,最后一栏是(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) ;
}


Le test est réussi, c'est du Java parfaitement valide.


OR真值表


三列是a,一列是b,最后一列是(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) ;
}


Ce test passe également, pourquoi préférons-nous « &&'et « ||' ?


Les images de la table de vérité ont été créées à l'aide du outil de table de vérité à partir de web.standfor.edu.


Problème : Fonctionnement en court-circuit


Le véritable problème est la différence de comportement entre les opérateurs bitwise (&, |) et booléens (&&, ||).

Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.

p. ex.

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 ! = nul
  • args.length () > 23

Cela laisse mon code ouvert à une NullPointerException si args est nul car nous effectuerons toujours la vérification de 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 saurons ça, Args ! = null donne la valeur False lorsque l'évaluation de l'expression de condition s'arrête.

Nous n'avons pas besoin 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.


Mais cela n'arriverait jamais dans le code de production


Il s'agit d'une erreur assez facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.

J'ai utilisé le Google Dork suivant pour voir 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 ()


C'est le type de code qui peut passer une revue de code car nous utilisons souvent des opérateurs bitwise dans les instructions d'affectation pour masquer les valeurs. Mais dans ce cas, le résultat est le même que dans 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 chèque 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 étaient renvoyés.

Un récent demande d'extraction sur l'un de mes projets open source était de corriger exactement cette erreur.

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


Comment le trouver


Lorsque j'ai vérifié mon exemple de code dans quelques 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 créé et révisé une recette Sensei assez simple qui pourrait répondre à ce problème.

Les opérateurs Bitwise étant parfaitement valides et souvent utilisés dans les affectations, nous nous sommes concentrés sur le cas d'utilisation des instructions if et sur l'utilisation de Bitwise & pour trouver 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 nous sommes à nouveau appuyés sur des expressions régulières. Cette fois, utilisez la fonction sed du 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 pour couvrir davantage de conditions correspondantes.

Dans sa forme actuelle, cette recette permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.

REMARQUE : De nombreux experts du code ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Merci pour ton aide.


---


Vous pouvez installer Sensei depuis IntelliJ en utilisant « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis recherchez simplement « Sensei Secure Code »

Nous avons beaucoup de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel « sensei-blog-examples » du compte GitHub de Secure Code Warrior.

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

En savoir plus sur Sensei


查看网络研讨会
开始
了解更多

点击下方链接,下载此资源的PDF文件。

Secure Code Warrior 在整个软件开发周期中保障代码安全,并营造将网络安全置于首位的企业文化。无论您是应用安全负责人、开发人员、信息安全主管,还是其他任何参与安全工作的人员,我们都能协助您的组织降低不安全代码带来的风险。

显示报告预约演示
下载PDF文件
显示资源
分享到:
领英品牌社交x 标志
您想了解更多吗?

分享到:
领英品牌社交x 标志
作者
艾伦-理查德森
2021年2月7日出版

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.

分享到:
领英品牌社交x 标志

Java Gotchas - Opérateurs bitwise ou booléens

> « Java Gotcha » - un modèle d'erreur courant facile à implémenter accidentellement.

Un piège Java assez simple dans lequel 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 vouliez vraiment écrire « && ».

Une heuristique courante que nous apprenons lors de la révision du code est la suivante :

> « & » ou « | » utilisé dans une instruction conditionnelle n'est probablement pas prévu.

Dans cet article de blog, nous allons explorer l'heuristique et identifier 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 bitwise avec des booléens est parfaitement valide. Java ne signalera donc pas d'erreur de syntaxe.

Si je construis un test JUnit pour explorer une table de vérité à la fois pour Bitwise OR (|) et Bitwise AND (&), nous verrons 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 n'est pas un problème.

ET Truth Table

有三栏是a,一栏是b,最后一栏是(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) ;
}


Le test est réussi, c'est du Java parfaitement valide.


OR真值表


三列是a,一列是b,最后一列是(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) ;
}


Ce test passe également, pourquoi préférons-nous « &&'et « ||' ?


Les images de la table de vérité ont été créées à l'aide du outil de table de vérité à partir de web.standfor.edu.


Problème : Fonctionnement en court-circuit


Le véritable problème est la différence de comportement entre les opérateurs bitwise (&, |) et booléens (&&, ||).

Un opérateur booléen est un opérateur de court-circuit qui n'évalue que ce dont il a besoin.

p. ex.

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 ! = nul
  • args.length () > 23

Cela laisse mon code ouvert à une NullPointerException si args est nul car nous effectuerons toujours la vérification de 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 saurons ça, Args ! = null donne la valeur False lorsque l'évaluation de l'expression de condition s'arrête.

Nous n'avons pas besoin 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.


Mais cela n'arriverait jamais dans le code de production


Il s'agit d'une erreur assez facile à commettre et qui n'est pas toujours détectée par les outils d'analyse statique.

J'ai utilisé le Google Dork suivant pour voir 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 ()


C'est le type de code qui peut passer une revue de code car nous utilisons souvent des opérateurs bitwise dans les instructions d'affectation pour masquer les valeurs. Mais dans ce cas, le résultat est le même que dans 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 chèque 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 étaient renvoyés.

Un récent demande d'extraction sur l'un de mes projets open source était de corriger exactement cette erreur.

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


Comment le trouver


Lorsque j'ai vérifié mon exemple de code dans quelques 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 créé et révisé une recette Sensei assez simple qui pourrait répondre à ce problème.

Les opérateurs Bitwise étant parfaitement valides et souvent utilisés dans les affectations, nous nous sommes concentrés sur le cas d'utilisation des instructions if et sur l'utilisation de Bitwise & pour trouver 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 nous sommes à nouveau appuyés sur des expressions régulières. Cette fois, utilisez la fonction sed du 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 pour couvrir davantage de conditions correspondantes.

Dans sa forme actuelle, cette recette permettrait d'identifier de nombreux cas d'utilisation actuels, et le plus important, celui qui a été signalé dans mon projet.

REMARQUE : De nombreux experts du code ont contribué à cet exemple et à cette critique de recette : Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Merci pour ton aide.


---


Vous pouvez installer Sensei depuis IntelliJ en utilisant « Préférences \ Plugins » (Mac) ou « Paramètres \ Plugins » (Windows), puis recherchez simplement « Sensei Secure Code »

Nous avons beaucoup de code source et de recettes pour ces articles de blog (y compris celui-ci) dans le référentiel « sensei-blog-examples » du compte GitHub de Secure Code Warrior.

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

En savoir plus sur Sensei


目录

下载PDF文件
显示资源
您想了解更多吗?

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 在整个软件开发周期中保障代码安全,并营造将网络安全置于首位的企业文化。无论您是应用安全负责人、开发人员、信息安全主管,还是其他任何参与安全工作的人员,我们都能协助您的组织降低不安全代码带来的风险。

预约演示下载
分享到:
领英品牌社交x 标志
资源中心

帮助您入门的资源

更多帖子
资源中心

帮助您入门的资源

更多帖子