java.android.best-practice.network-security-config.nsc-pinning-without-backup

profile photo of semgrepsemgrep
Author
103
Download Count*

Your app uses TLS public key pinning without specifying a backup key. If you are forced to change TLS keys or CAs on short notice, not having a backup pin can lead to connectivity issues until you can push out an update. It is considered best practice to add at least one additional pin as a backup.

Run Locally

Run in CI

Defintion

rules:
  - id: nsc-pinning-without-backup
    languages:
      - generic
    message: Your app uses TLS public key pinning without specifying a backup key.
      If you are forced to change TLS keys or CAs on short notice, not having a
      backup pin can lead to connectivity issues until you can push out an
      update. It is considered best practice to add at least one additional pin
      as a backup.
    metadata:
      category: best-practice
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      technology:
        - android
      references:
        - https://developer.android.com/training/articles/security-config#CertificatePinning
        - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/
    patterns:
      - pattern: |
          <pin ...>...</pin>
      - pattern-not-inside: |
          <pin ...>...</pin>...<pin ...>...</pin>
      - pattern-inside: |
          <pin-set ...> ... ... </pin-set>
      - pattern-inside: |
          <domain-config ... > ... ... ... ... ... </domain-config>
      - pattern-not-inside: |
          <!-- ... -->
    severity: INFO
    paths:
      include:
        - "*.xml"

Examples

network-security-config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- ruleid: nsc-allows-plaintext-traffic -->
    <base-config cleartextTrafficPermitted="true">
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">localhost</domain>
        <trust-anchors>
            <!-- Trust a debug certificate in addition to the system certificates -->
            <certificates src="system" />
            <certificates src="@raw/debug_certificate" />
        </trust-anchors>
    </domain-config>

</network-security-config>

<network-security-config>
    <!-- ok: nsc-allows-plaintext-traffic -->
    <!-- <base-config cleartextTrafficPermitted="true"> -->
    <!-- ok: nsc-allows-plaintext-traffic -->
    <base-config cleartextTrafficPermitted="false">
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">localhost</domain>
        <trust-anchors>
            <!-- Trust a debug certificate in addition to the system certificates -->
            <certificates src="system" />
            <certificates src="@raw/debug_certificate" />
        </trust-anchors>
    </domain-config>

</network-security-config>

<network-security-config>
    <!-- ok: nsc-allows-plaintext-traffic -->
    <base-config cleartextTrafficPermitted="false">
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">localhost</domain>
        <trust-anchors>
            <!-- Trust a debug certificate in addition to the system certificates -->
            <certificates src="system" />
            <certificates src="@raw/debug_certificate" />
        </trust-anchors>
    </domain-config>
</network-security-config>

<network-security-config xmlns:tools="http://schemas.android.com/tools" tools:ignore="InsecureBaseConfiguration,AcceptsUserCertificates">
    <!-- ok: nsc-allows-plaintext-traffic -->
    <base-config cleartextTrafficPermitted="true">
            <!-- Trust system and user certificates -->
            <certificates src="system" />
            <!-- ok: nsc-allows-user-ca-certs -->
            <certificates src="user" />
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">localhost</domain>
        <trust-anchors>
            <!-- Trust a debug certificate in addition to the system certificates -->
            <certificates src="system" />
            <!-- ok: nsc-allows-user-ca-certs-for-domain -->
            <certificates src="user" />
            <certificates src="@raw/debug_certificate" />
        </trust-anchors>
    </domain-config>
</network-security-config>

<network-security-config xmlns:tools="http://schemas.android.com/tools" tools:ignore="InsecureBaseConfiguration">
    <!-- ok: nsc-allows-plaintext-traffic -->
    <base-config cleartextTrafficPermitted="true">
            <!-- Trust system and user certificates -->
            <certificates src="system" />
            <!-- ruleid: nsc-allows-user-ca-certs -->
            <certificates src="user" />
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">localhost</domain>
        <trust-anchors>
            <!-- Trust a debug certificate in addition to the system certificates -->
            <certificates src="system" />
            <!-- ruleid: nsc-allows-user-ca-certs-for-domain -->
            <certificates src="user" />
            <certificates src="@raw/debug_certificate" />
        </trust-anchors>
    </domain-config>
</network-security-config>

<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <!-- ok: nsc-pinning-without-expiration -->
        <pin-set expiration="2018-01-01">
            <!-- ruleid: nsc-pinning-without-backup -->
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
        </pin-set>
    </domain-config>
</network-security-config>

<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <!-- ok: nsc-pinning-without-expiration -->
        <pin-set expiration="2018-01-01">
            <!-- ok: nsc-pinning-without-backup -->
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
            <!-- backup pin -->
            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
        </pin-set>
    </domain-config>
</network-security-config>


<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <!-- ruleid: nsc-pinning-without-expiration -->
        <pin-set>
            <!-- ok: nsc-pinning-without-backup -->
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
            <!-- backup pin -->
            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
        </pin-set>
    </domain-config>
</network-security-config>