SV.SENSITIVE.DATA

このエラーは、機密情報が暗号化なしで保存または送信された場合に報告されます。

脆弱性とリスク

パスワードや社会保障番号などの機密データが暗号化されていない場合、攻撃者はそれを読んだり修正したりすることができます。

機密データを暗号化すると、攻撃者はデータを読み取ったり変更したりする前にデータを復号化する必要があります。

コード例

脆弱コード例 1

コピー
    package com.company;
    import java.io.IOException;
    import java.io.OutputStream;
    public class WriteInfo {
        public void write(OutputStream os, int ssn) throws IOException {
            os.write(ssn);
        }
    }

機密値がストリームに書き込まれると、Klocwork は欠陥を生成します。この例では、社会保障番号が機密値です。

修正コード例 1

コピー
    package com.company;
    import java.io.IOException;
    import java.io.OutputStream;
    public class WriteInfo {
        public void write(OutputStream os, int ssn) throws IOException {
            int encryptedSsn = encrypt(ssn);
            os.write(encryptedSsn);
        }
        private int encrypt(int value) {
           int encrypted;
           // ... do encryption
           return encrypted;
       }
   }

次の .jkb ファイルを適用します。これは、「encrypt()」メソッドが安全なデータを返すことを Klocwork 解析エンジンに通知します。

コピー
    package com.company;
    @Bind("SV.SENSITIVE.DATA")
    class Writer {
        @Check("return") private int encrypt(int value);
    }

この修正された例では、機密値 (社会保障番号) は書き込まれる前に暗号化されます。この修正された例では、Klocwork は欠陥を生成しません。

脆弱コード例 2

コピー
    package com.company;
    import java.io.IOException;
    import java.io.Writer;
    public class WriteInfo {
        public void write(Writer w, User user) throws IOException {
            String value = user.getPassword();
            w.write(value);
        }
        public static class User {
           public String getPassword() {
               return "pw";
           }
       }
   }

機密値が Writer オブジェクトに書き込まれると、Klocwork は欠陥を生成します。この例では、パスワードは「getPassword() 」メソッドから取得され、そして書き込まれます。

修正コード例 2

コピー
    package com.company;
    import java.io.IOException;
    import java.io.Writer;
    public class WriteInfo {
        public void write(Writer w, User user) throws IOException {
            String encryptedPassword = encrypt(user.getPassword());
            w.write(encryptedPassword);
        }
        private String encrypt(String value) {
           String encrypted;
           // ... do encryption
           return encrypted;
       }
       public static class User {
           public String getPassword() {
                return "pw";
           }
       }
   }

次の .jkb ファイルを適用します。これは、「encrypt()」メソッドには安全なデータが含まれていることを Klocwork 解析エンジンに通知します。

コピー
    package com.company;
    @Bind("SV.SENSITIVE.DATA")
    class Writer {
        @Check("return") private String encrypt(String value);
    }

この修正された例では、機密値は書き込まれる前に暗号化されます。また、変数名「encryptedPassword」は、コードがプレーンテキストのパスワードを保存してないことを明確に示すために使用されています。

構成可能なチェッカーでの脆弱コード例

このチェッカーは、dob、ssn、password などの機密データのデフォルトリストで構成されています。このリストは、すべてを含むものではなく、構成可能であることを意図しています。機密データは、.jkb ファイルの @CheckerParam 注釈を使用して構成できます。ユーザーがカスタム @CheckerParam オプションを指定すると、デフォルトの組み込み型の機密用語リストはもはや使用されなくなります。

この例では、ユーザーはソフトウェアのドメイン固有の知識を持ち、患者の「name」、「dob」、「address」は機密のデータタイプであることを確認しました。次の注釈を含む .jkb ファイルは、すでにプロジェクトの構成にロードされています。

コピー
    @CheckerParam("SV.SENSITIVE.DATA", "name,dob,address")

    package com.company;
    @Bind("SV.SENSITIVE.DATA")
    class Writer {
        @Check("return") public String encrypt(String value);
    }

上の .jkb ファイルは、dob、address、name が機密値であること、また、「encrypt()」メソッドが安全なデータを返すことを Klocwork 解析エンジンに通知します。

脆弱なコード例 3

コピー
    package com.company;
    import java.io.IOException;
    import java.io.Writer;
    public class WritePatient {
        public void writePatientInfo(Writer writer, Patient patient) throws IOException {
            StringBuilder sb = new StringBuilder();
            sb.append(patient.getName());
            sb.append(';');
            sb.append(patient.getDob());
            sb.append(';');
            sb.append(patient.getAddress());
            writer.write(sb.toString());
       }
       public static class Patient {
            public String getName() { return "John Doe"; }
            public String getDob() { return "1900-01-01"; }
            public String getAddress() { return "123 Main St., Cityville, NY 12345"; }
       }
   }

Klocwork は、暗号化されていない名前、暗号化されていない生年月日、暗号化されていない住所の 3 つの欠陥を上のコードで検出します。

修正コード例 3

コピー
    package com.company;
    import java.io.IOException;
    import java.io.Writer;
    public class WritePatient {
        public void writePatientInfo(Writer writer, Patient patient) throws IOException {
            StringBuilder sb = new StringBuilder();
            sb.append(encrypt(patient.getName()));
            sb.append(';');
            sb.append(encrypt(patient.getDob()));
            sb.append(';');
            sb.append(encrypt(patient.getAddress()));
            writer.write(sb.toString());
       }
       public String encrypt(String value) {
            String encrypted;
            // .. do encryption
            return encrypted;
       }
       public static class Patient {
            public String getName() { return "John Doe"; }
            public String getDob() { return "1900-01-01"; }
            public String getAddress() { return "123 Main St., Cityville, NY 12345"; }
       }
   }

関連チェッカー

拡張機能

このチェッカーは、.jkb ファイルの @CheckerParam と @Check オプションを使用して機密値を探すように調整できます。このチェッカーを調整してカスタムの機密値を追加すると、デフォルトは使用されなくなります。それらも含めたい場合は、それらをカスタム値とともに .jkb ファイルに再追加することができます。詳細については、Java 解析のチューニングを参照してください。

デフォルト機密値

デフォルトで使用される機密値は、dob、ssn、pin、password、password_buffer、pwd、pwd_buffer、pwdbuf、passwd です。