
Javaのエラー:ビット演算子とブール演算子の違い
Javaのエラー:ビット演算子とブール演算子の違い
「Javaの落とし穴」:誤って実装しやすい、よくあるエラーパターン。
Javaでうっかり陥りがちな単純な落とし穴は、ブール比較演算子の代わりにビット単位演算子を使用してしまうことです。
例えば、単純なタイプミスによって、本来「&&」と入力したかったのに「&」と入力してしまう可能性があります。
コードレビューで学ぶ一般的な発見手法は:
条件文で使用される「&」や「|」は、おそらく意図的なものではないでしょう。
このブログ記事では、ヒューリスティックを探求し、このコーディングの問題を特定し解決する方法を探ります。
問題は何ですか?ビット単位の演算はブール値で正常に動作します
ビット単位演算子をブール値に使用することは完全に有効であるため、Javaは構文エラーを通知しません。
ビット単位の論理和(|)とビット単位の論理積(&)の両方について真理値表を探索するJUnitテストを構築すると、ビット単位演算子の出力が真理値表と一致することがわかります。このことから、ビット単位演算子の使用は問題ではないと考えられるかもしれません。
Y 真実の表

@Test
void BitwiseOperatorsAndTruthTable () {
Assertions.assertEquals (verdadero, verdadero y verdadero);
Assertions.assertEquals (falso, verdadero y falso);
Assertions.assertEquals (falso, falso y verdadero);
Assertions.assertEquals (falso, falso y falso);
}
テストは通過します。これは完全に有効なJavaです。
真実の表

@Test
anular BitwiseOperatorSorTruthTable () {
Assertions.assertEquals (verdadero, verdadero | verdadero);
Assertions.assertEquals (verdadero, verdadero | falso);
Assertions.assertEquals (verdadero, falso | verdadero);
Assertions.assertEquals (falso, falso | falso);
}
このテストも通るのに、なぜ「&&」や「||」を好むのか?
真理値表の画像は 真理値表ツールを使用して作成されました を使用して作成されました web.standfor.eduを使用して作成されました。
問題:短絡動作
真の問題は、ビット単位演算子(&, |)と論理演算子(&&, ||)の挙動の違いにある。
ブール演算子はショートサーキット演算子であり、必要な部分のみを評価する。
例えば
si (args! = nulo & args.length () > 23) {
System.out.println (argumentos);
}
上記のコードでは、ビット単位演算子が使用されているため、両方のブール条件が評価されます。
- argumentos! = なし
- args.length() > 23
これにより、argsがnullの場合にNullPointerExceptionが発生する可能性があります。なぜなら、argsがnullであってもargs.lengthの検証は常に実行されるためです。両方のブール条件を評価する必要があるからです。
ブール演算子の短絡評価
&&を使用する場合、例えば
si (args! = nulo && args.length () > 23) {
System.out.println (argumentos);
}
引数が null であると判明した時点で、条件式の評価は偽として評価され、条件式の評価は停止する。
右側を評価する必要はありません。
右辺の条件の結果がどうであれ、ブール式の最終的な値は偽となる。
しかし、これは本番環境のコードでは決して起こらない
これは非常に起こりやすいエラーであり、静的解析ツールが常にこれを検出するとは限りません。
このパターンに関する公開例を見つけられるかどうか確認するため、以下のGoogle Dorkを使用しました:
ファイルタイプ: java かつ 「! =null &」
この検索は RootWindowContainer 内の Android コードを返しました
isDocument = intent! = null & intent.isDocument()
これはコードレビューを通過する可能性のあるコードです。値をマスクするために代入文でビット演算子を頻繁に使用するためです。しかしこの場合、結果は前のif文の例と同じです。意図がnullの場合、NullPointerExceptionが発生します。
この構文でうまくいくことが多いのは、防御的なコーディングを行い冗長なコードを書く傾向があるためです。`!= null` のチェックは、ほとんどのユースケースで冗長になり得ます。
これは開発者が本番環境のコードで犯したエラーです。
検索結果がどれほど最新のものかは分かりませんが、実行した際にはGoogle、Amazon、Apache...そして私のコードを含む結果が表示されました。
私のオープンソースプロジェクトの一つで最近提出されたプルリクエストは、まさにこのエラーを修正するものでした。
si (escriba! =nulo y escribe.trim () .length () >0) {
Aceptar MediaTypeDefinitionsList.add (type.trim ());
}
これをどのように見つけるか
いくつかの静的解析ツールでサンプルコードを確認したところ、いずれもこの隠された自己破壊コードを検出できなかった。
Secure Code Warrior、この疑問にSensei を作成・検証しました。
ビット演算子は完全に有効であり、代入文で頻繁に使用されるため、問題のあるコードを見つけるには、if文のユースケースとビット演算子&の使用に焦点を当てます。
buscar:
expresión:
Cualquiera de:
- en:
condición: {}
valor:
Sensible a mayúsculas y minúsculas: falso
coincidencias: «.* & . *»
これは正規表現を使用して、条件式(例:if文内)として使用される「&」に一致させます。
この問題を解決するため、再び正規表現に頼りました。今回はQuickFixのsed機能を使用し、式中の&を&&に一括置換しました。
Correcciones disponibles:
- nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
acciones:
- reescribir:
a: «{{#sed}} s/&/&&/g, {{{.}}} {{/sed}}»
最終的な注記
これはビット演算子の最も一般的な誤用、つまり実際にはブール演算子を使用する意図があった場合に該当します。
これ以外の状況でも同様の問題が発生する可能性があります。例えばタスクの例が挙げられますが、レシピを作成する際には偽陽性の特定を避けるよう努める必要があります。さもなければ、レシピが無視されたり無効化されたりするからです。レシピは最も一般的な発生パターンに一致するよう設計されています。Sensei につれ、検索機能にさらなる特異性を追加し、より多くの条件に一致させる可能性は十分にあります。
現在の形で、このレシピは多くの現在のユースケースを特定し、最も重要なのは、私のプロジェクトで報告されたユースケースを特定するでしょう。
注記: このレシピの例と改訂には、少数のコード戦士たちが貢献しました: Charlie Eriksen、Matthieu Calie、Robin Claerhaut、Brysen Ackx、Nathan Desmet、Downey Robersscheuten。ご協力に感謝します。
---
Sensei 「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)経由でSensei インストールし、その後「código seguro desenseiを検索してください。
Secure Code Warriorにある`sensei`リポジトリには、これらのブログ記事(この記事を含む)のソースコードやレシピが多数用意されています。
https://github.com/securecodewarrior/sensei-blog-examples
このブログ記事では、Javaにおけるよくあるコーディングミス(条件演算子の代わりにビット単位演算子を使用すること)を分析します。このミスがコードを脆弱にする理由と、Sensei 問題をSensei 解説します。
アラン・リチャードソンは、20年以上にわたり、開発者として、またテスターからテスト責任者まで、あらゆるレベルのテストに携わってきたプロフェッショナルなIT経験を持っています。アラン・リチャードソンは、Secure Code Warrior のデベロッパーリレーションズの責任者として、チームと直接連携し、高品質で安全なコードの開発を促進しています。また、「Dear Evil Tester」や「Java For Testers」など4冊の著書があります。また、テクニカルWebテストやSelenium WebDriver with Javaを学ぶためのオンライントレーニングcourses を作成しています。アランは、SeleniumSimplified.com、EvilTester.com、JavaForTesters.com、CompendiumDev.co.ukに執筆やトレーニングビデオを掲載している。

Secure Code Warrior ソフトウェア開発ライフサイクル全体を通じてコードを保護し、サイバーセキュリティを最優先事項とする文化を構築するために、貴組織をSecure Code Warrior 。AppSec管理者、開発者、CISO、セキュリティ関連担当者など、あらゆる立場の方々に対し、不安全なコードに関連するリスクを軽減するお手伝いをいたします。
デモを予約するアラン・リチャードソンは、20年以上にわたり、開発者として、またテスターからテスト責任者まで、あらゆるレベルのテストに携わってきたプロフェッショナルなIT経験を持っています。アラン・リチャードソンは、Secure Code Warrior のデベロッパーリレーションズの責任者として、チームと直接連携し、高品質で安全なコードの開発を促進しています。また、「Dear Evil Tester」や「Java For Testers」など4冊の著書があります。また、テクニカルWebテストやSelenium WebDriver with Javaを学ぶためのオンライントレーニングcourses を作成しています。アランは、SeleniumSimplified.com、EvilTester.com、JavaForTesters.com、CompendiumDev.co.ukに執筆やトレーニングビデオを掲載している。
Javaのエラー:ビット演算子とブール演算子の違い
「Javaの落とし穴」:誤って実装しやすい、よくあるエラーパターン。
Javaでうっかり陥りがちな単純な落とし穴は、ブール比較演算子の代わりにビット単位演算子を使用してしまうことです。
例えば、単純なタイプミスによって、本来「&&」と入力したかったのに「&」と入力してしまう可能性があります。
コードレビューで学ぶ一般的な発見手法は:
条件文で使用される「&」や「|」は、おそらく意図的なものではないでしょう。
このブログ記事では、ヒューリスティックを探求し、このコーディングの問題を特定し解決する方法を探ります。
問題は何ですか?ビット単位の演算はブール値で正常に動作します
ビット単位演算子をブール値に使用することは完全に有効であるため、Javaは構文エラーを通知しません。
ビット単位の論理和(|)とビット単位の論理積(&)の両方について真理値表を探索するJUnitテストを構築すると、ビット単位演算子の出力が真理値表と一致することがわかります。このことから、ビット単位演算子の使用は問題ではないと考えられるかもしれません。
Y 真実の表

@Test
void BitwiseOperatorsAndTruthTable () {
Assertions.assertEquals (verdadero, verdadero y verdadero);
Assertions.assertEquals (falso, verdadero y falso);
Assertions.assertEquals (falso, falso y verdadero);
Assertions.assertEquals (falso, falso y falso);
}
テストは通過します。これは完全に有効なJavaです。
真実の表

@Test
anular BitwiseOperatorSorTruthTable () {
Assertions.assertEquals (verdadero, verdadero | verdadero);
Assertions.assertEquals (verdadero, verdadero | falso);
Assertions.assertEquals (verdadero, falso | verdadero);
Assertions.assertEquals (falso, falso | falso);
}
このテストも通るのに、なぜ「&&」や「||」を好むのか?
真理値表の画像は 真理値表ツールを使用して作成されました を使用して作成されました web.standfor.eduを使用して作成されました。
問題:短絡動作
真の問題は、ビット単位演算子(&, |)と論理演算子(&&, ||)の挙動の違いにある。
ブール演算子はショートサーキット演算子であり、必要な部分のみを評価する。
例えば
si (args! = nulo & args.length () > 23) {
System.out.println (argumentos);
}
上記のコードでは、ビット単位演算子が使用されているため、両方のブール条件が評価されます。
- argumentos! = なし
- args.length() > 23
これにより、argsがnullの場合にNullPointerExceptionが発生する可能性があります。なぜなら、argsがnullであってもargs.lengthの検証は常に実行されるためです。両方のブール条件を評価する必要があるからです。
ブール演算子の短絡評価
&&を使用する場合、例えば
si (args! = nulo && args.length () > 23) {
System.out.println (argumentos);
}
引数が null であると判明した時点で、条件式の評価は偽として評価され、条件式の評価は停止する。
右側を評価する必要はありません。
右辺の条件の結果がどうであれ、ブール式の最終的な値は偽となる。
しかし、これは本番環境のコードでは決して起こらない
これは非常に起こりやすいエラーであり、静的解析ツールが常にこれを検出するとは限りません。
このパターンに関する公開例を見つけられるかどうか確認するため、以下のGoogle Dorkを使用しました:
ファイルタイプ: java かつ 「! =null &」
この検索は RootWindowContainer 内の Android コードを返しました
isDocument = intent! = null & intent.isDocument()
これはコードレビューを通過する可能性のあるコードです。値をマスクするために代入文でビット演算子を頻繁に使用するためです。しかしこの場合、結果は前のif文の例と同じです。意図がnullの場合、NullPointerExceptionが発生します。
この構文でうまくいくことが多いのは、防御的なコーディングを行い冗長なコードを書く傾向があるためです。`!= null` のチェックは、ほとんどのユースケースで冗長になり得ます。
これは開発者が本番環境のコードで犯したエラーです。
検索結果がどれほど最新のものかは分かりませんが、実行した際にはGoogle、Amazon、Apache...そして私のコードを含む結果が表示されました。
私のオープンソースプロジェクトの一つで最近提出されたプルリクエストは、まさにこのエラーを修正するものでした。
si (escriba! =nulo y escribe.trim () .length () >0) {
Aceptar MediaTypeDefinitionsList.add (type.trim ());
}
これをどのように見つけるか
いくつかの静的解析ツールでサンプルコードを確認したところ、いずれもこの隠された自己破壊コードを検出できなかった。
Secure Code Warrior、この疑問にSensei を作成・検証しました。
ビット演算子は完全に有効であり、代入文で頻繁に使用されるため、問題のあるコードを見つけるには、if文のユースケースとビット演算子&の使用に焦点を当てます。
buscar:
expresión:
Cualquiera de:
- en:
condición: {}
valor:
Sensible a mayúsculas y minúsculas: falso
coincidencias: «.* & . *»
これは正規表現を使用して、条件式(例:if文内)として使用される「&」に一致させます。
この問題を解決するため、再び正規表現に頼りました。今回はQuickFixのsed機能を使用し、式中の&を&&に一括置換しました。
Correcciones disponibles:
- nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
acciones:
- reescribir:
a: «{{#sed}} s/&/&&/g, {{{.}}} {{/sed}}»
最終的な注記
これはビット演算子の最も一般的な誤用、つまり実際にはブール演算子を使用する意図があった場合に該当します。
これ以外の状況でも同様の問題が発生する可能性があります。例えばタスクの例が挙げられますが、レシピを作成する際には偽陽性の特定を避けるよう努める必要があります。さもなければ、レシピが無視されたり無効化されたりするからです。レシピは最も一般的な発生パターンに一致するよう設計されています。Sensei につれ、検索機能にさらなる特異性を追加し、より多くの条件に一致させる可能性は十分にあります。
現在の形で、このレシピは多くの現在のユースケースを特定し、最も重要なのは、私のプロジェクトで報告されたユースケースを特定するでしょう。
注記: このレシピの例と改訂には、少数のコード戦士たちが貢献しました: Charlie Eriksen、Matthieu Calie、Robin Claerhaut、Brysen Ackx、Nathan Desmet、Downey Robersscheuten。ご協力に感謝します。
---
Sensei 「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)経由でSensei インストールし、その後「código seguro desenseiを検索してください。
Secure Code Warriorにある`sensei`リポジトリには、これらのブログ記事(この記事を含む)のソースコードやレシピが多数用意されています。
https://github.com/securecodewarrior/sensei-blog-examples
Javaのエラー:ビット演算子とブール演算子の違い
「Javaの落とし穴」:誤って実装しやすい、よくあるエラーパターン。
Javaでうっかり陥りがちな単純な落とし穴は、ブール比較演算子の代わりにビット単位演算子を使用してしまうことです。
例えば、単純なタイプミスによって、本来「&&」と入力したかったのに「&」と入力してしまう可能性があります。
コードレビューで学ぶ一般的な発見手法は:
条件文で使用される「&」や「|」は、おそらく意図的なものではないでしょう。
このブログ記事では、ヒューリスティックを探求し、このコーディングの問題を特定し解決する方法を探ります。
問題は何ですか?ビット単位の演算はブール値で正常に動作します
ビット単位演算子をブール値に使用することは完全に有効であるため、Javaは構文エラーを通知しません。
ビット単位の論理和(|)とビット単位の論理積(&)の両方について真理値表を探索するJUnitテストを構築すると、ビット単位演算子の出力が真理値表と一致することがわかります。このことから、ビット単位演算子の使用は問題ではないと考えられるかもしれません。
Y 真実の表

@Test
void BitwiseOperatorsAndTruthTable () {
Assertions.assertEquals (verdadero, verdadero y verdadero);
Assertions.assertEquals (falso, verdadero y falso);
Assertions.assertEquals (falso, falso y verdadero);
Assertions.assertEquals (falso, falso y falso);
}
テストは通過します。これは完全に有効なJavaです。
真実の表

@Test
anular BitwiseOperatorSorTruthTable () {
Assertions.assertEquals (verdadero, verdadero | verdadero);
Assertions.assertEquals (verdadero, verdadero | falso);
Assertions.assertEquals (verdadero, falso | verdadero);
Assertions.assertEquals (falso, falso | falso);
}
このテストも通るのに、なぜ「&&」や「||」を好むのか?
真理値表の画像は 真理値表ツールを使用して作成されました を使用して作成されました web.standfor.eduを使用して作成されました。
問題:短絡動作
真の問題は、ビット単位演算子(&, |)と論理演算子(&&, ||)の挙動の違いにある。
ブール演算子はショートサーキット演算子であり、必要な部分のみを評価する。
例えば
si (args! = nulo & args.length () > 23) {
System.out.println (argumentos);
}
上記のコードでは、ビット単位演算子が使用されているため、両方のブール条件が評価されます。
- argumentos! = なし
- args.length() > 23
これにより、argsがnullの場合にNullPointerExceptionが発生する可能性があります。なぜなら、argsがnullであってもargs.lengthの検証は常に実行されるためです。両方のブール条件を評価する必要があるからです。
ブール演算子の短絡評価
&&を使用する場合、例えば
si (args! = nulo && args.length () > 23) {
System.out.println (argumentos);
}
引数が null であると判明した時点で、条件式の評価は偽として評価され、条件式の評価は停止する。
右側を評価する必要はありません。
右辺の条件の結果がどうであれ、ブール式の最終的な値は偽となる。
しかし、これは本番環境のコードでは決して起こらない
これは非常に起こりやすいエラーであり、静的解析ツールが常にこれを検出するとは限りません。
このパターンに関する公開例を見つけられるかどうか確認するため、以下のGoogle Dorkを使用しました:
ファイルタイプ: java かつ 「! =null &」
この検索は RootWindowContainer 内の Android コードを返しました
isDocument = intent! = null & intent.isDocument()
これはコードレビューを通過する可能性のあるコードです。値をマスクするために代入文でビット演算子を頻繁に使用するためです。しかしこの場合、結果は前のif文の例と同じです。意図がnullの場合、NullPointerExceptionが発生します。
この構文でうまくいくことが多いのは、防御的なコーディングを行い冗長なコードを書く傾向があるためです。`!= null` のチェックは、ほとんどのユースケースで冗長になり得ます。
これは開発者が本番環境のコードで犯したエラーです。
検索結果がどれほど最新のものかは分かりませんが、実行した際にはGoogle、Amazon、Apache...そして私のコードを含む結果が表示されました。
私のオープンソースプロジェクトの一つで最近提出されたプルリクエストは、まさにこのエラーを修正するものでした。
si (escriba! =nulo y escribe.trim () .length () >0) {
Aceptar MediaTypeDefinitionsList.add (type.trim ());
}
これをどのように見つけるか
いくつかの静的解析ツールでサンプルコードを確認したところ、いずれもこの隠された自己破壊コードを検出できなかった。
Secure Code Warrior、この疑問にSensei を作成・検証しました。
ビット演算子は完全に有効であり、代入文で頻繁に使用されるため、問題のあるコードを見つけるには、if文のユースケースとビット演算子&の使用に焦点を当てます。
buscar:
expresión:
Cualquiera de:
- en:
condición: {}
valor:
Sensible a mayúsculas y minúsculas: falso
coincidencias: «.* & . *»
これは正規表現を使用して、条件式(例:if文内)として使用される「&」に一致させます。
この問題を解決するため、再び正規表現に頼りました。今回はQuickFixのsed機能を使用し、式中の&を&&に一括置換しました。
Correcciones disponibles:
- nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
acciones:
- reescribir:
a: «{{#sed}} s/&/&&/g, {{{.}}} {{/sed}}»
最終的な注記
これはビット演算子の最も一般的な誤用、つまり実際にはブール演算子を使用する意図があった場合に該当します。
これ以外の状況でも同様の問題が発生する可能性があります。例えばタスクの例が挙げられますが、レシピを作成する際には偽陽性の特定を避けるよう努める必要があります。さもなければ、レシピが無視されたり無効化されたりするからです。レシピは最も一般的な発生パターンに一致するよう設計されています。Sensei につれ、検索機能にさらなる特異性を追加し、より多くの条件に一致させる可能性は十分にあります。
現在の形で、このレシピは多くの現在のユースケースを特定し、最も重要なのは、私のプロジェクトで報告されたユースケースを特定するでしょう。
注記: このレシピの例と改訂には、少数のコード戦士たちが貢献しました: Charlie Eriksen、Matthieu Calie、Robin Claerhaut、Brysen Ackx、Nathan Desmet、Downey Robersscheuten。ご協力に感謝します。
---
Sensei 「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)経由でSensei インストールし、その後「código seguro desenseiを検索してください。
Secure Code Warriorにある`sensei`リポジトリには、これらのブログ記事(この記事を含む)のソースコードやレシピが多数用意されています。
https://github.com/securecodewarrior/sensei-blog-examples

以下のリンクをクリックして、このリソースのPDFをダウンロードしてください。
Secure Code Warrior ソフトウェア開発ライフサイクル全体を通じてコードを保護し、サイバーセキュリティを最優先事項とする文化を構築するために、貴組織をSecure Code Warrior 。AppSec管理者、開発者、CISO、セキュリティ関連担当者など、あらゆる立場の方々に対し、不安全なコードに関連するリスクを軽減するお手伝いをいたします。
報告書を見るデモを予約するアラン・リチャードソンは、20年以上にわたり、開発者として、またテスターからテスト責任者まで、あらゆるレベルのテストに携わってきたプロフェッショナルなIT経験を持っています。アラン・リチャードソンは、Secure Code Warrior のデベロッパーリレーションズの責任者として、チームと直接連携し、高品質で安全なコードの開発を促進しています。また、「Dear Evil Tester」や「Java For Testers」など4冊の著書があります。また、テクニカルWebテストやSelenium WebDriver with Javaを学ぶためのオンライントレーニングcourses を作成しています。アランは、SeleniumSimplified.com、EvilTester.com、JavaForTesters.com、CompendiumDev.co.ukに執筆やトレーニングビデオを掲載している。
Javaのエラー:ビット演算子とブール演算子の違い
「Javaの落とし穴」:誤って実装しやすい、よくあるエラーパターン。
Javaでうっかり陥りがちな単純な落とし穴は、ブール比較演算子の代わりにビット単位演算子を使用してしまうことです。
例えば、単純なタイプミスによって、本来「&&」と入力したかったのに「&」と入力してしまう可能性があります。
コードレビューで学ぶ一般的な発見手法は:
条件文で使用される「&」や「|」は、おそらく意図的なものではないでしょう。
このブログ記事では、ヒューリスティックを探求し、このコーディングの問題を特定し解決する方法を探ります。
問題は何ですか?ビット単位の演算はブール値で正常に動作します
ビット単位演算子をブール値に使用することは完全に有効であるため、Javaは構文エラーを通知しません。
ビット単位の論理和(|)とビット単位の論理積(&)の両方について真理値表を探索するJUnitテストを構築すると、ビット単位演算子の出力が真理値表と一致することがわかります。このことから、ビット単位演算子の使用は問題ではないと考えられるかもしれません。
Y 真実の表

@Test
void BitwiseOperatorsAndTruthTable () {
Assertions.assertEquals (verdadero, verdadero y verdadero);
Assertions.assertEquals (falso, verdadero y falso);
Assertions.assertEquals (falso, falso y verdadero);
Assertions.assertEquals (falso, falso y falso);
}
テストは通過します。これは完全に有効なJavaです。
真実の表

@Test
anular BitwiseOperatorSorTruthTable () {
Assertions.assertEquals (verdadero, verdadero | verdadero);
Assertions.assertEquals (verdadero, verdadero | falso);
Assertions.assertEquals (verdadero, falso | verdadero);
Assertions.assertEquals (falso, falso | falso);
}
このテストも通るのに、なぜ「&&」や「||」を好むのか?
真理値表の画像は 真理値表ツールを使用して作成されました を使用して作成されました web.standfor.eduを使用して作成されました。
問題:短絡動作
真の問題は、ビット単位演算子(&, |)と論理演算子(&&, ||)の挙動の違いにある。
ブール演算子はショートサーキット演算子であり、必要な部分のみを評価する。
例えば
si (args! = nulo & args.length () > 23) {
System.out.println (argumentos);
}
上記のコードでは、ビット単位演算子が使用されているため、両方のブール条件が評価されます。
- argumentos! = なし
- args.length() > 23
これにより、argsがnullの場合にNullPointerExceptionが発生する可能性があります。なぜなら、argsがnullであってもargs.lengthの検証は常に実行されるためです。両方のブール条件を評価する必要があるからです。
ブール演算子の短絡評価
&&を使用する場合、例えば
si (args! = nulo && args.length () > 23) {
System.out.println (argumentos);
}
引数が null であると判明した時点で、条件式の評価は偽として評価され、条件式の評価は停止する。
右側を評価する必要はありません。
右辺の条件の結果がどうであれ、ブール式の最終的な値は偽となる。
しかし、これは本番環境のコードでは決して起こらない
これは非常に起こりやすいエラーであり、静的解析ツールが常にこれを検出するとは限りません。
このパターンに関する公開例を見つけられるかどうか確認するため、以下のGoogle Dorkを使用しました:
ファイルタイプ: java かつ 「! =null &」
この検索は RootWindowContainer 内の Android コードを返しました
isDocument = intent! = null & intent.isDocument()
これはコードレビューを通過する可能性のあるコードです。値をマスクするために代入文でビット演算子を頻繁に使用するためです。しかしこの場合、結果は前のif文の例と同じです。意図がnullの場合、NullPointerExceptionが発生します。
この構文でうまくいくことが多いのは、防御的なコーディングを行い冗長なコードを書く傾向があるためです。`!= null` のチェックは、ほとんどのユースケースで冗長になり得ます。
これは開発者が本番環境のコードで犯したエラーです。
検索結果がどれほど最新のものかは分かりませんが、実行した際にはGoogle、Amazon、Apache...そして私のコードを含む結果が表示されました。
私のオープンソースプロジェクトの一つで最近提出されたプルリクエストは、まさにこのエラーを修正するものでした。
si (escriba! =nulo y escribe.trim () .length () >0) {
Aceptar MediaTypeDefinitionsList.add (type.trim ());
}
これをどのように見つけるか
いくつかの静的解析ツールでサンプルコードを確認したところ、いずれもこの隠された自己破壊コードを検出できなかった。
Secure Code Warrior、この疑問にSensei を作成・検証しました。
ビット演算子は完全に有効であり、代入文で頻繁に使用されるため、問題のあるコードを見つけるには、if文のユースケースとビット演算子&の使用に焦点を当てます。
buscar:
expresión:
Cualquiera de:
- en:
condición: {}
valor:
Sensible a mayúsculas y minúsculas: falso
coincidencias: «.* & . *»
これは正規表現を使用して、条件式(例:if文内)として使用される「&」に一致させます。
この問題を解決するため、再び正規表現に頼りました。今回はQuickFixのsed機能を使用し、式中の&を&&に一括置換しました。
Correcciones disponibles:
- nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
acciones:
- reescribir:
a: «{{#sed}} s/&/&&/g, {{{.}}} {{/sed}}»
最終的な注記
これはビット演算子の最も一般的な誤用、つまり実際にはブール演算子を使用する意図があった場合に該当します。
これ以外の状況でも同様の問題が発生する可能性があります。例えばタスクの例が挙げられますが、レシピを作成する際には偽陽性の特定を避けるよう努める必要があります。さもなければ、レシピが無視されたり無効化されたりするからです。レシピは最も一般的な発生パターンに一致するよう設計されています。Sensei につれ、検索機能にさらなる特異性を追加し、より多くの条件に一致させる可能性は十分にあります。
現在の形で、このレシピは多くの現在のユースケースを特定し、最も重要なのは、私のプロジェクトで報告されたユースケースを特定するでしょう。
注記: このレシピの例と改訂には、少数のコード戦士たちが貢献しました: Charlie Eriksen、Matthieu Calie、Robin Claerhaut、Brysen Ackx、Nathan Desmet、Downey Robersscheuten。ご協力に感謝します。
---
Sensei 「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)経由でSensei インストールし、その後「código seguro desenseiを検索してください。
Secure Code Warriorにある`sensei`リポジトリには、これらのブログ記事(この記事を含む)のソースコードやレシピが多数用意されています。
https://github.com/securecodewarrior/sensei-blog-examples
目次
アラン・リチャードソンは、20年以上にわたり、開発者として、またテスターからテスト責任者まで、あらゆるレベルのテストに携わってきたプロフェッショナルなIT経験を持っています。アラン・リチャードソンは、Secure Code Warrior のデベロッパーリレーションズの責任者として、チームと直接連携し、高品質で安全なコードの開発を促進しています。また、「Dear Evil Tester」や「Java For Testers」など4冊の著書があります。また、テクニカルWebテストやSelenium WebDriver with Javaを学ぶためのオンライントレーニングcourses を作成しています。アランは、SeleniumSimplified.com、EvilTester.com、JavaForTesters.com、CompendiumDev.co.ukに執筆やトレーニングビデオを掲載している。

Secure Code Warrior ソフトウェア開発ライフサイクル全体を通じてコードを保護し、サイバーセキュリティを最優先事項とする文化を構築するために、貴組織をSecure Code Warrior 。AppSec管理者、開発者、CISO、セキュリティ関連担当者など、あらゆる立場の方々に対し、不安全なコードに関連するリスクを軽減するお手伝いをいたします。
デモを予約するダウンロード



%20(1).avif)
.avif)
