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

Author
103
Download Count*
License
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>
Short Link: https://sg.run/RPRe