forked from mirrors/kingfisher
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Mick Grove <mick.grove@mongodb.com>
264 lines
No EOL
7.1 KiB
YAML
264 lines
No EOL
7.1 KiB
YAML
rules:
|
|
- name: Plaid Client ID (helper)
|
|
id: kingfisher.plaid.1
|
|
visible: false
|
|
pattern: |
|
|
(?xi)
|
|
\b
|
|
(?:plaid[\w-]{0,32})?
|
|
(?:client[_-]?id|plaid[_-]?client[_-]?id)
|
|
\b
|
|
(?:\s*[:=]\s*|["']\s*:\s*["']|=\s*["'])
|
|
\s*
|
|
\b
|
|
(
|
|
[a-z0-9]{24}
|
|
)
|
|
\b
|
|
min_entropy: 2.8
|
|
confidence: medium
|
|
examples:
|
|
- 'plaid_client_id="sd479fjropblyr5b4m2dutha"'
|
|
references:
|
|
- https://plaid.com/docs/api/institutions/
|
|
|
|
# -------------------------
|
|
- name: Plaid Secret (Production)
|
|
id: kingfisher.plaid.2
|
|
pattern: |
|
|
(?xi)
|
|
\b
|
|
plaid
|
|
(?:.|[\n\r]){0,32}?
|
|
(?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|ACCESS_KEY)
|
|
(?:.|[\n\r]){0,32}?
|
|
\b
|
|
(
|
|
[a-z0-9]{30}
|
|
)
|
|
\b
|
|
min_entropy: 3.2
|
|
confidence: medium
|
|
pattern_requirements:
|
|
min_digits: 2
|
|
min_lowercase: 6
|
|
ignore_if_contains:
|
|
- changeme
|
|
- example
|
|
- test
|
|
examples:
|
|
- 'plaid_secret_key="wuxd6sw7ma4lv10xremyhz7ulf9owc"'
|
|
references:
|
|
- https://plaid.com/docs/api/institutions/
|
|
- https://plaid.com/docs/quickstart/glossary/
|
|
- https://plaid.com/docs/errors/invalid-input/
|
|
depends_on_rule:
|
|
- rule_id: kingfisher.plaid.1
|
|
variable: CLIENT_ID
|
|
validation:
|
|
type: Http
|
|
content:
|
|
request:
|
|
method: POST
|
|
url: https://production.plaid.com/institutions/get
|
|
headers:
|
|
Accept: application/json
|
|
Content-Type: application/json
|
|
body: |
|
|
{
|
|
"client_id": "{{ CLIENT_ID | json_escape }}",
|
|
"secret": "{{ TOKEN | json_escape }}",
|
|
"count": 1,
|
|
"offset": 0,
|
|
"country_codes": ["US"]
|
|
}
|
|
response_matcher:
|
|
- report_response: true
|
|
- type: StatusMatch
|
|
status: [200]
|
|
- type: JsonValid
|
|
# If keys are invalid, Plaid returns INVALID_API_KEYS (HTTP 400).
|
|
- type: WordMatch
|
|
negative: true
|
|
words:
|
|
- '"INVALID_API_KEYS"'
|
|
|
|
- name: Plaid Secret (Sandbox)
|
|
id: kingfisher.plaid.3
|
|
pattern: |
|
|
(?xi)
|
|
\b
|
|
plaid
|
|
(?:.|[\n\r]){0,32}?
|
|
(?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|ACCESS_KEY)
|
|
(?:.|[\n\r]){0,32}?
|
|
\b
|
|
(
|
|
[a-z0-9]{30}
|
|
)
|
|
\b
|
|
min_entropy: 3.2
|
|
confidence: medium
|
|
pattern_requirements:
|
|
min_digits: 2
|
|
min_lowercase: 6
|
|
ignore_if_contains:
|
|
- changeme
|
|
- example
|
|
- test
|
|
examples:
|
|
- 'PLAID_SECRET="wuxd6sw7ma4lv10xremyhz7ulf9owc"'
|
|
references:
|
|
- https://plaid.com/docs/api/institutions/
|
|
- https://plaid.com/docs/quickstart/glossary/
|
|
- https://plaid.com/docs/errors/invalid-input/
|
|
depends_on_rule:
|
|
- rule_id: kingfisher.plaid.1
|
|
variable: CLIENT_ID
|
|
validation:
|
|
type: Http
|
|
content:
|
|
request:
|
|
method: POST
|
|
url: https://sandbox.plaid.com/institutions/get
|
|
headers:
|
|
Accept: application/json
|
|
Content-Type: application/json
|
|
body: |
|
|
{
|
|
"client_id": "{{ CLIENT_ID | json_escape }}",
|
|
"secret": "{{ TOKEN | json_escape }}",
|
|
"count": 1,
|
|
"offset": 0,
|
|
"country_codes": ["US"]
|
|
}
|
|
response_matcher:
|
|
- report_response: true
|
|
- type: StatusMatch
|
|
status: [200]
|
|
- type: JsonValid
|
|
# If keys are invalid, Plaid returns INVALID_API_KEYS (HTTP 400).
|
|
- type: WordMatch
|
|
negative: true
|
|
words:
|
|
- '"INVALID_API_KEYS"'
|
|
|
|
# -------------------------
|
|
# Plaid access tokens (env-specific)
|
|
# Validate using /accounts/get (requires client_id + secret + access_token)
|
|
# -------------------------
|
|
- name: Plaid Access Token (Production)
|
|
id: kingfisher.plaid.4
|
|
pattern: |
|
|
(?xi)
|
|
\b
|
|
(
|
|
access-production-
|
|
[0-9a-f]{8}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{12}
|
|
)
|
|
\b
|
|
min_entropy: 3.4
|
|
confidence: medium
|
|
examples:
|
|
- 'plaid_api_token="access-production-822f6ce0-ee1a-221e-3cd8-f3ce5094b3e2"'
|
|
references:
|
|
- https://plaid.com/docs/quickstart/glossary/
|
|
- https://plaid.com/docs/api/accounts/
|
|
- https://plaid.com/docs/errors/invalid-input/
|
|
depends_on_rule:
|
|
- rule_id: kingfisher.plaid.1
|
|
variable: CLIENT_ID
|
|
- rule_id: kingfisher.plaid.2
|
|
variable: PLAID_SECRET
|
|
validation:
|
|
type: Http
|
|
content:
|
|
request:
|
|
method: POST
|
|
url: https://production.plaid.com/accounts/get
|
|
headers:
|
|
Accept: application/json
|
|
Content-Type: application/json
|
|
body: |
|
|
{
|
|
"client_id": "{{ CLIENT_ID | json_escape }}",
|
|
"secret": "{{ PLAID_SECRET | json_escape }}",
|
|
"access_token": "{{ TOKEN | json_escape }}"
|
|
}
|
|
response_matcher:
|
|
- report_response: true
|
|
- type: StatusMatch
|
|
status: [200]
|
|
- type: JsonValid
|
|
- type: WordMatch
|
|
match_all_words: true
|
|
words:
|
|
- '"accounts"'
|
|
- type: WordMatch
|
|
negative: true
|
|
match_all_words: false
|
|
words:
|
|
- '"INVALID_ACCESS_TOKEN"'
|
|
- '"INVALID_API_KEYS"'
|
|
|
|
- name: Plaid Access Token (Sandbox)
|
|
id: kingfisher.plaid.5
|
|
pattern: |
|
|
(?xi)
|
|
\b
|
|
(
|
|
access-sandbox-
|
|
[0-9a-f]{8}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{4}-
|
|
[0-9a-f]{12}
|
|
)
|
|
\b
|
|
min_entropy: 3.4
|
|
confidence: medium
|
|
examples:
|
|
- 'PLAID_ACCESS_TOKEN="access-sandbox-822f6ce0-ee1a-221e-3cd8-f3ce5094b3e2"'
|
|
references:
|
|
- https://plaid.com/docs/quickstart/glossary/
|
|
- https://plaid.com/docs/api/accounts/
|
|
- https://plaid.com/docs/errors/invalid-input/
|
|
depends_on_rule:
|
|
- rule_id: kingfisher.plaid.1
|
|
variable: CLIENT_ID
|
|
- rule_id: kingfisher.plaid.3
|
|
variable: PLAID_SECRET
|
|
validation:
|
|
type: Http
|
|
content:
|
|
request:
|
|
method: POST
|
|
url: https://sandbox.plaid.com/accounts/get
|
|
headers:
|
|
Accept: application/json
|
|
Content-Type: application/json
|
|
body: |
|
|
{
|
|
"client_id": "{{ CLIENT_ID | json_escape }}",
|
|
"secret": "{{ PLAID_SECRET | json_escape }}",
|
|
"access_token": "{{ TOKEN | json_escape }}"
|
|
}
|
|
response_matcher:
|
|
- report_response: true
|
|
- type: StatusMatch
|
|
status: [200]
|
|
- type: JsonValid
|
|
- type: WordMatch
|
|
match_all_words: true
|
|
words:
|
|
- '"accounts"'
|
|
- type: WordMatch
|
|
negative: true
|
|
match_all_words: false
|
|
words:
|
|
- '"INVALID_ACCESS_TOKEN"'
|
|
- '"INVALID_API_KEYS"' |