forked from mirrors/kingfisher
Compare commits
18 commits
677c7a5d5f
...
4d5ce57a12
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d5ce57a12 | |||
|
|
165768b5ca |
||
|
|
ba30b1788f | ||
|
|
9c448eec60 | ||
|
|
49d980acb0 | ||
|
|
8da61ab553 | ||
|
|
fc542afa99 | ||
|
|
92b23b1f82 | ||
|
|
01f3a12106 | ||
|
|
2b99c6a354 | ||
|
|
ac2198e3bd | ||
|
|
482a60bb9d | ||
|
|
3d7629cf8b | ||
|
|
b1c2953d25 | ||
|
|
3442e92405 | ||
|
|
b9da8e2829 | ||
|
|
a28250be19 | ||
|
|
2265d2b1f0 |
39 changed files with 2205 additions and 56 deletions
49
.github/workflows/release-provenance.yml
vendored
49
.github/workflows/release-provenance.yml
vendored
|
|
@ -1,49 +0,0 @@
|
|||
name: SLSA Provenance
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
# Compute SHA256 hashes of all release assets
|
||||
hash:
|
||||
name: Compute artifact hashes
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
hashes: ${{ steps.hash.outputs.hashes }}
|
||||
steps:
|
||||
- name: Download release assets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG_NAME: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p assets
|
||||
gh release download "${TAG_NAME}" \
|
||||
--repo "${{ github.repository }}" \
|
||||
--dir assets
|
||||
|
||||
- name: Compute SHA256 hashes
|
||||
id: hash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd assets
|
||||
# Base64-encode the SHA256 hashes for SLSA provenance
|
||||
echo "hashes=$(sha256sum -- * | base64 -w0)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Generate SLSA provenance for the release artifacts
|
||||
provenance:
|
||||
name: Generate SLSA provenance
|
||||
needs: [hash]
|
||||
permissions:
|
||||
actions: read
|
||||
id-token: write
|
||||
contents: write
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
|
||||
with:
|
||||
base64-subjects: "${{ needs.hash.outputs.hashes }}"
|
||||
upload-assets: true
|
||||
51
.github/workflows/release.yml
vendored
51
.github/workflows/release.yml
vendored
|
|
@ -408,6 +408,57 @@ jobs:
|
|||
with:
|
||||
subject-path: 'target/release/*'
|
||||
|
||||
# ──────────────── SLSA Provenance ────────────────
|
||||
hash:
|
||||
name: Compute artifact hashes
|
||||
needs: [release]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
hashes: ${{ steps.hash.outputs.hashes }}
|
||||
steps:
|
||||
- name: Download release assets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG_NAME: ${{ needs.release.outputs.tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p assets
|
||||
gh release download "${TAG_NAME}" \
|
||||
--repo "${{ github.repository }}" \
|
||||
--dir assets \
|
||||
--pattern '*.tgz' \
|
||||
--pattern '*.deb' \
|
||||
--pattern '*.rpm' \
|
||||
--pattern '*.zip'
|
||||
|
||||
- name: Compute SHA256 hashes
|
||||
id: hash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd assets
|
||||
shopt -s nullglob
|
||||
files=( * )
|
||||
if [ ${#files[@]} -eq 0 ]; then
|
||||
echo "Error: no release assets found to hash in $(pwd)" >&2
|
||||
exit 1
|
||||
fi
|
||||
hashes=$(sha256sum -- "${files[@]}" | base64 -w0)
|
||||
echo "hashes=${hashes}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
provenance:
|
||||
name: Generate SLSA provenance
|
||||
needs: [hash]
|
||||
permissions:
|
||||
actions: read
|
||||
id-token: write
|
||||
contents: write
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
|
||||
with:
|
||||
base64-subjects: "${{ needs.hash.outputs.hashes }}"
|
||||
upload-assets: true
|
||||
|
||||
# ──────────────── Publish Docker image ────────────────
|
||||
publish-docker:
|
||||
needs: [release]
|
||||
|
|
|
|||
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -2,6 +2,19 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [v1.92.0]
|
||||
- Added new built-in rules for Etsy, Flutterwave, Freemius, JFrog, Kraken, KuCoin, Trello, Octopus Deploy, OpenShift, Private AI, SettleMint, Sidekiq, and Polymarket.
|
||||
- Added live HTTP validation for Etsy, JFrog, Octopus Deploy, OpenShift, and Private AI where provider documentation supported reliable token-only checks.
|
||||
- Added detection + validation rules for Anthropic Admin, Azure Speech, Azure Translator, Databento, DataStax Astra, DevCycle, Fullstory, GC Notify, and Stytch; built-in runtime rule count is now 601 with `--confidence=low`.
|
||||
- Added Heroku token revocation support for both legacy UUID-format tokens and `HRKU-` platform tokens via the OAuth authorizations API.
|
||||
- Added `hmac_sha256_b64key` Liquid filter for HMAC-SHA256 signing with base64-encoded keys (decodes key to raw bytes before signing), enabling correct Azure Notification Hub SAS validation.
|
||||
- Integrated SLSA v3 provenance generation into the release workflow; hash computation now scopes to build artifacts only for idempotent re-runs.
|
||||
- Removed Zapier webhook live validation (GET to a catch hook triggers the Zap).
|
||||
- Hardened Heroku revocation regex to prevent crossing JSON object boundaries when extracting authorization IDs.
|
||||
- Fixed Zendesk subdomain regex to reject trailing hyphens; renamed `ZENDESK_SUBDOMAIN` to `ZENDESK_HOST` for clarity.
|
||||
- Fixed Stytch and Polymarket trailing `\b` boundaries that prevented matching base64-padded secrets ending with `=`.
|
||||
- Tightened Kubernetes API Server URL pattern to require kube-specific identifiers, preventing bootstrap tokens from binding to unrelated `server:` entries.
|
||||
|
||||
## [v1.91.0]
|
||||
- Added SSRF protection for credential validation: outbound HTTP requests now block connections to loopback, private, link-local, and other non-public IP addresses. HTTP redirect targets are DNS-resolved and validated against the same SSRF rules. Use `--allow-internal-ips` to opt out when scanning internal infrastructure.
|
||||
- Consolidated JWT SSRF checks to use the shared `is_ssrf_safe_ip` function, covering additional reserved ranges (CGNAT, documentation, benchmarking, IPv6 unique-local).
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ http = "1.4"
|
|||
|
||||
[package]
|
||||
name = "kingfisher"
|
||||
version = "1.91.0"
|
||||
version = "1.92.0"
|
||||
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
|
|
|||
76
NOTICE
76
NOTICE
|
|
@ -47,10 +47,16 @@ Certain detection rules:
|
|||
* crates/kingfisher-rules/data/rules/instagram.yml
|
||||
* crates/kingfisher-rules/data/rules/iterable.yml
|
||||
* crates/kingfisher-rules/data/rules/lokalise.yml
|
||||
* crates/kingfisher-rules/data/rules/azure-notification-hub.yml
|
||||
* crates/kingfisher-rules/data/rules/firebase.yml
|
||||
* crates/kingfisher-rules/data/rules/helpscout.yml
|
||||
* crates/kingfisher-rules/data/rules/kubernetes.yml
|
||||
* crates/kingfisher-rules/data/rules/pendo.yml
|
||||
* crates/kingfisher-rules/data/rules/razorpay.yml
|
||||
* crates/kingfisher-rules/data/rules/spotify.yml
|
||||
* crates/kingfisher-rules/data/rules/wakatime.yml
|
||||
* crates/kingfisher-rules/data/rules/zapier.yml
|
||||
* crates/kingfisher-rules/data/rules/zendesk.yml
|
||||
|
||||
are derived in part from Titus (https://github.com/praetorian-inc/titus),
|
||||
which is licensed under the Apache License, Version 2.0.
|
||||
|
|
@ -72,3 +78,73 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Certain detection rules:
|
||||
* crates/kingfisher-rules/data/rules/octopusdeploy.yml
|
||||
* crates/kingfisher-rules/data/rules/openshift.yml
|
||||
* crates/kingfisher-rules/data/rules/polymarket.yml
|
||||
* crates/kingfisher-rules/data/rules/privateai.yml
|
||||
* crates/kingfisher-rules/data/rules/settlemint.yml
|
||||
* crates/kingfisher-rules/data/rules/sidekiq.yml
|
||||
|
||||
are derived in part from Betterleaks
|
||||
(https://github.com/betterleaks/betterleaks), which is licensed under the MIT
|
||||
License.
|
||||
|
||||
Betterleaks
|
||||
Copyright (c) 2026 Zachary Rice
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Certain detection rules:
|
||||
* crates/kingfisher-rules/data/rules/etsy.yml
|
||||
* crates/kingfisher-rules/data/rules/flutterwave.yml
|
||||
* crates/kingfisher-rules/data/rules/freemius.yml
|
||||
* crates/kingfisher-rules/data/rules/jfrog.yml
|
||||
* crates/kingfisher-rules/data/rules/kraken.yml
|
||||
* crates/kingfisher-rules/data/rules/kucoin.yml
|
||||
* crates/kingfisher-rules/data/rules/trello.yml
|
||||
|
||||
are derived in part from Gitleaks (https://github.com/gitleaks/gitleaks),
|
||||
which is licensed under the MIT License.
|
||||
|
||||
Gitleaks
|
||||
Copyright (c) 2019 Zachary Rice
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
36
README.md
36
README.md
|
|
@ -4,7 +4,7 @@
|
|||
<img src="docs/kingfisher_logo.png" alt="Kingfisher Logo" width="126" height="173" style="vertical-align: right;" />
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/mongodb/kingfisher)<br>
|
||||
[](https://github.com/mongodb/kingfisher)<br>
|
||||
[](https://github.com/mongodb/kingfisher/pkgs/container/kingfisher)<br>
|
||||
|
||||
|
||||
|
|
@ -302,6 +302,40 @@ Kingfisher supports multiple installation methods:
|
|||
|
||||
**For complete installation instructions and pre-commit hook setup, see [docs/INSTALLATION.md](docs/INSTALLATION.md).**
|
||||
|
||||
## Verifying Releases
|
||||
|
||||
Every Kingfisher release includes [SLSA v3](https://slsa.dev) provenance and GitHub build attestations so you can verify that artifacts were built by our CI pipeline and haven't been tampered with.
|
||||
|
||||
### SLSA provenance
|
||||
|
||||
Each GitHub release includes a `multiple.intoto.jsonl` provenance file. Verify any release artifact with [`slsa-verifier`](https://github.com/slsa-framework/slsa-verifier):
|
||||
|
||||
```bash
|
||||
# Install slsa-verifier
|
||||
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest
|
||||
|
||||
# Download the artifact and provenance from the release
|
||||
gh release download <version> --repo mongodb/kingfisher \
|
||||
--pattern 'kingfisher-linux-x64.tgz' \
|
||||
--pattern 'multiple.intoto.jsonl'
|
||||
|
||||
# Verify
|
||||
slsa-verifier verify-artifact kingfisher-linux-x64.tgz \
|
||||
--provenance-path multiple.intoto.jsonl \
|
||||
--source-uri github.com/mongodb/kingfisher
|
||||
```
|
||||
|
||||
### GitHub attestations
|
||||
|
||||
Release artifacts also have GitHub build attestations, verifiable with the GitHub CLI:
|
||||
|
||||
```bash
|
||||
gh release download <version> --repo mongodb/kingfisher \
|
||||
--pattern 'kingfisher-linux-x64.tgz'
|
||||
|
||||
gh attestation verify kingfisher-linux-x64.tgz --repo mongodb/kingfisher
|
||||
```
|
||||
|
||||
# Detection Rules
|
||||
|
||||
Kingfisher ships with [hundreds of rules](crates/kingfisher-rules/data/rules/) that cover everything from classic cloud keys to the latest AI SaaS tokens. Below is an overview:
|
||||
|
|
|
|||
|
|
@ -30,8 +30,27 @@ Strongly recommended fields:
|
|||
|
||||
## Pattern Quality Rules
|
||||
- Prefer specific anchors/prefixes and provider context over broad generic regex.
|
||||
- When the token format is generic or common-looking (for example bare 32-hex keys), prefer contextual patterns of the form: provider keyword -> short flexible gap -> key/secret label -> short flexible gap -> token. A good default is:
|
||||
- `\b`
|
||||
- provider identifier (for example `amplitude`, `azure`, `speech`, `translator`)
|
||||
- `(?:.|[\n\r]){0,N}?`
|
||||
- common credential labels such as `(?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|AUTHORIZATION|API)`
|
||||
- `(?:.|[\n\r]){0,M}?`
|
||||
- the token capture wrapped in a single unnamed capture group
|
||||
- Do not add surrounding context when the token is already strongly self-identifying by prefix or structure (for example `sk-ant-api...`, `AstraCS:...`, `dvc_client_...`, `secret-test-...`). In those cases, prefer the tighter self-identifying regex.
|
||||
- Use `pattern_requirements` to enforce quality constraints (`min_digits`, `min_uppercase`, `min_lowercase`, `min_special_chars`, `ignore_if_contains`, `checksum`).
|
||||
- Use checksum validation in `pattern_requirements.checksum` when token formats support it.
|
||||
- Use checksum validation in `pattern_requirements.checksum` when token formats support it. This is preferred when the provider token format includes a documented or reverse-engineered check segment, because it can sharply reduce false positives without adding brittle surrounding context.
|
||||
- For checksum-based rules, prefer named captures for the main token body and checksum suffix/prefix, then compute the expected checksum in Liquid. A typical pattern is:
|
||||
- `(
|
||||
prefix_(?P<body>...)(?P<checksum>...)
|
||||
)`
|
||||
- with:
|
||||
- `actual.template: "{{ checksum }}"`
|
||||
- `actual.requires_capture: checksum`
|
||||
- `expected: "{{ body | <checksum-filter> | <encoding/filter chain> }}"`
|
||||
- `skip_if_missing: true`
|
||||
- Example: GitHub PATs use a CRC32-derived base62 checksum. The rule in `github.yml` captures `body` and `checksum`, then compares `{{ checksum }}` against `{{ body | crc32 | base62: 6 }}`.
|
||||
- Prefer checksum validation over extra loose context whenever the token structure itself supports it. If the checksum is only present on some token generations, keep `skip_if_missing: true` so older examples continue to load safely.
|
||||
- Use `visible: false` for helper/non-secret captures used only by dependent rules.
|
||||
- Use `depends_on_rule` for multi-part credential validation (for example ID + secret).
|
||||
|
||||
|
|
|
|||
|
|
@ -47,4 +47,38 @@ rules:
|
|||
words:
|
||||
- '"type":"message"'
|
||||
- 'credit balance is too low'
|
||||
url: https://api.anthropic.com/v1/messages
|
||||
url: https://api.anthropic.com/v1/messages
|
||||
|
||||
- name: Anthropic Admin API Key
|
||||
id: kingfisher.anthropic.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
(
|
||||
sk-ant-admin(?:\d{2,4})?-[A-Za-z0-9_-]{40,}
|
||||
)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- sk-ant-admin03-4mB9zY2Qx8LmN7pR5sT1uV6wX0aBcDeFgHiJkLmNoPqRsTuVwXyZ1234
|
||||
references:
|
||||
- https://docs.anthropic.com/en/api/administration-api
|
||||
- https://docs.anthropic.com/en/api/admin-api/organization/get-me
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.anthropic.com/v1/organizations/me
|
||||
headers:
|
||||
x-api-key: '{{ TOKEN }}'
|
||||
anthropic-version: "2023-06-01"
|
||||
content-type: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
|
|
|
|||
156
crates/kingfisher-rules/data/rules/azure-notification-hub.yml
Normal file
156
crates/kingfisher-rules/data/rules/azure-notification-hub.yml
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
rules:
|
||||
- name: Azure Notification Hub Namespace Host
|
||||
id: kingfisher.azure.notificationhub.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
endpoint
|
||||
\s*=\s*
|
||||
sb://
|
||||
|
|
||||
notification
|
||||
(?:.|[\n\r]){0,48}?
|
||||
https://
|
||||
)
|
||||
(
|
||||
[a-z0-9]
|
||||
[a-z0-9-]{1,62}
|
||||
\.servicebus\.windows\.net
|
||||
)
|
||||
(?:/|;|\b)
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- Endpoint=sb://acme-push.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=VGhpcytpcythK3Rlc3Qra2V5K3ZhbHVlLzEyMzQ1Njc4OTA=
|
||||
- 'notificationHubEndpoint: "https://mobile-prod.servicebus.windows.net"'
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/rest/api/notificationhubs/use-rest-api-backend
|
||||
|
||||
- name: Azure Notification Hub Name
|
||||
id: kingfisher.azure.notificationhub.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
notification
|
||||
(?:hub)?
|
||||
(?:name|path)
|
||||
|
|
||||
hub
|
||||
(?:name|path)
|
||||
)
|
||||
\s*[:=]\s*
|
||||
["']?
|
||||
(
|
||||
[A-Za-z0-9]
|
||||
[A-Za-z0-9._-]{6,63}
|
||||
)
|
||||
["']?
|
||||
\b
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- NotificationHubPath=my-mobile-hub
|
||||
- 'notificationHubName: "android-prod"'
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/notification-hubs/create-notification-hub-portal
|
||||
|
||||
- name: Azure Notification Hub SAS Key Name
|
||||
id: kingfisher.azure.notificationhub.3
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
["']?
|
||||
SharedAccessKeyName
|
||||
["']?
|
||||
\s*[:=]\s*
|
||||
["']?
|
||||
(
|
||||
[A-Za-z]
|
||||
[A-Za-z0-9_-]{6,63}
|
||||
)
|
||||
["']?
|
||||
\b
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- SharedAccessKeyName=DefaultListenSharedAccessSignature
|
||||
- '"SharedAccessKeyName": "DefaultFullSharedAccessSignature"'
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/notification-hubs/notification-hubs-push-notification-security
|
||||
|
||||
- name: Azure Notification Hub Access Key
|
||||
id: kingfisher.azure.notificationhub.4
|
||||
pattern: |
|
||||
(?xi)
|
||||
(?:
|
||||
(?:notification\s*hub|Endpoint\s*=\s*sb://[a-z0-9-]{2,63}\.servicebus\.windows\.net/?)
|
||||
(?:.|[\n\r]){0,160}?
|
||||
SharedAccessKey
|
||||
|
|
||||
\b
|
||||
(?:hubAccessKey|notificationHub(?:Access)?Key)
|
||||
\b
|
||||
)
|
||||
\s*[:=]\s*
|
||||
["']?
|
||||
(
|
||||
[A-Za-z0-9+/]{32,88}={0,2}
|
||||
)
|
||||
["']?
|
||||
(?:[^A-Za-z0-9+/=]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- sample
|
||||
- document
|
||||
- placeholder
|
||||
min_entropy: 3.7
|
||||
confidence: medium
|
||||
examples:
|
||||
- Endpoint=sb://acme-push.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=Q29udG9zb1Rlc3RLZXkrMTIzNDU2Nzg5MC9BQkNERUZHSEk=
|
||||
- |
|
||||
const config = {
|
||||
notificationHubName: "android-prod",
|
||||
hubAccessKey: "U2FmZUtleVZhbHVlKzEyMzQ1Njc4OTBBQkNERUYrLz09"
|
||||
};
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/notification-hubs/notification-hubs-push-notification-security
|
||||
- https://learn.microsoft.com/en-us/rest/api/notificationhubs/use-rest-api-backend
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.azure.notificationhub.1
|
||||
variable: NH_HOST
|
||||
- rule_id: kingfisher.azure.notificationhub.2
|
||||
variable: NH_HUB
|
||||
- rule_id: kingfisher.azure.notificationhub.3
|
||||
variable: NH_KEY_NAME
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: 'https://{{ NH_HOST }}/{{ NH_HUB }}/registrations/?api-version=2015-01'
|
||||
headers:
|
||||
Accept: application/atom+xml
|
||||
Authorization: |
|
||||
{%- assign uri = "https://" | append: NH_HOST | append: "/" | append: NH_HUB | append: "/registrations/?api-version=2015-01" -%}
|
||||
{%- assign se = "" | unix_timestamp | plus: 300 -%}
|
||||
{%- assign nl = "" | newline -%}
|
||||
{%- assign to_sign = uri | url_encode | append: nl | append: se -%}
|
||||
{%- capture auth -%}SharedAccessSignature sr={{ uri | url_encode }}&sig={{ to_sign | hmac_sha256_b64key: TOKEN | url_encode }}&se={{ se }}&skn={{ NH_KEY_NAME | url_encode }}{%- endcapture -%}
|
||||
{{ auth | strip_newlines }}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: XmlValid
|
||||
- type: WordMatch
|
||||
words:
|
||||
- "<feed"
|
||||
84
crates/kingfisher-rules/data/rules/azurespeech.yml
Normal file
84
crates/kingfisher-rules/data/rules/azurespeech.yml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
rules:
|
||||
- name: Azure Speech Region
|
||||
id: kingfisher.azurespeech.1
|
||||
visible: false
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
SPEECH_REGION
|
||||
|
|
||||
AZURE_SPEECH_REGION
|
||||
|
|
||||
speech[_-]?region
|
||||
|
|
||||
azure[_-]?speech[_-]?region
|
||||
)
|
||||
\b
|
||||
(?:.|[\n\r]){0,16}?
|
||||
[=:]
|
||||
\s*["']?
|
||||
(
|
||||
[a-z0-9-]{4,32}
|
||||
)
|
||||
["']?
|
||||
min_entropy: 1.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- SPEECH_REGION=eastus
|
||||
- azure_speech_region="westus2"
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech
|
||||
|
||||
- name: Azure Speech API Key
|
||||
id: kingfisher.azurespeech.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
speech
|
||||
|
|
||||
azure[_-]?speech
|
||||
)
|
||||
(?:.|[\n\r]){0,24}?
|
||||
(?:
|
||||
key
|
||||
|
|
||||
api[_-]?key
|
||||
|
|
||||
subscription[_-]?key
|
||||
|
|
||||
secret
|
||||
)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
(
|
||||
[a-f0-9]{32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- AZURE_SPEECH_KEY=1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
|
||||
- speech_subscription_key="abcdef0123456789abcdef0123456789"
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.azurespeech.1
|
||||
variable: AZURE_SPEECH_REGION
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://{{ AZURE_SPEECH_REGION }}.api.cognitive.microsoft.com/sts/v1.0/issueToken
|
||||
headers:
|
||||
Ocp-Apim-Subscription-Key: "{{ TOKEN }}"
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: "0"
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
97
crates/kingfisher-rules/data/rules/azuretranslator.yml
Normal file
97
crates/kingfisher-rules/data/rules/azuretranslator.yml
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
rules:
|
||||
- name: Azure Translator Region
|
||||
id: kingfisher.azuretranslator.1
|
||||
visible: false
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
TRANSLATOR_REGION
|
||||
|
|
||||
AZURE_TRANSLATOR_REGION
|
||||
|
|
||||
translator[_-]?region
|
||||
|
|
||||
translation[_-]?region
|
||||
|
|
||||
Ocp-Apim-Subscription-Region
|
||||
)
|
||||
\b
|
||||
(?:.|[\n\r]){0,16}?
|
||||
[=:]
|
||||
\s*["']?
|
||||
(
|
||||
[a-z0-9-]{4,32}
|
||||
)
|
||||
["']?
|
||||
min_entropy: 1.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- TRANSLATOR_REGION=eastus
|
||||
- azure_translator_region="westeurope"
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/translator/text-translation/reference/authentication
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/translator/reference/v3-0-reference
|
||||
|
||||
- name: Azure Translator API Key
|
||||
id: kingfisher.azuretranslator.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
translator
|
||||
|
|
||||
translation
|
||||
|
|
||||
azure[_-]?(?:translator|translation)
|
||||
)
|
||||
(?:.|[\n\r]){0,24}?
|
||||
(?:
|
||||
key
|
||||
|
|
||||
api[_-]?key
|
||||
|
|
||||
subscription[_-]?key
|
||||
|
|
||||
secret
|
||||
)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
(
|
||||
[a-f0-9]{32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- AZURE_TRANSLATOR_KEY=1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
|
||||
- translator_subscription_key="abcdef0123456789abcdef0123456789"
|
||||
references:
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/translator/text-translation/reference/authentication
|
||||
- https://learn.microsoft.com/en-us/azure/ai-services/translator/reference/v3-0-reference
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.azuretranslator.1
|
||||
variable: AZURE_TRANSLATOR_REGION
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=es
|
||||
headers:
|
||||
Ocp-Apim-Subscription-Key: "{{ TOKEN }}"
|
||||
Ocp-Apim-Subscription-Region: "{{ AZURE_TRANSLATOR_REGION }}"
|
||||
Content-Type: application/json
|
||||
body: |
|
||||
[
|
||||
{
|
||||
"Text": "hello"
|
||||
}
|
||||
]
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
34
crates/kingfisher-rules/data/rules/databento.yml
Normal file
34
crates/kingfisher-rules/data/rules/databento.yml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
rules:
|
||||
- name: Databento API Key
|
||||
id: kingfisher.databento.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
db-[A-Za-z0-9]{29}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.3
|
||||
confidence: medium
|
||||
examples:
|
||||
- DATABENTO_API_KEY=db-abc123def456ghi789jkl012mno34
|
||||
references:
|
||||
- https://databento.com/docs/api-reference-historical
|
||||
- https://databento.com/docs/portal/api-keys
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://hist.databento.com/v0/metadata.list_datasets
|
||||
headers:
|
||||
Authorization: "Basic {{ TOKEN | append: ':' | b64enc }}"
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
33
crates/kingfisher-rules/data/rules/datastax.yml
Normal file
33
crates/kingfisher-rules/data/rules/datastax.yml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
rules:
|
||||
- name: DataStax Astra Application Token
|
||||
id: kingfisher.datastax.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
AstraCS:[A-Za-z0-9]{20,}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_entropy: 4.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- ASTRA_DB_APPLICATION_TOKEN=AstraCS:Q29kZXhWYWxpZGF0aW9uVG9rZW5FeGFtcGxlMTIzNDU2Nzg5
|
||||
references:
|
||||
- https://docs.datastax.com/en/astra-db-serverless/administration/manage-application-tokens.html
|
||||
- https://docs.datastax.com/en/astra-db-classic/api-reference/devops-api.html
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.astra.datastax.com/v2/databases
|
||||
headers:
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
117
crates/kingfisher-rules/data/rules/devcycle.yml
Normal file
117
crates/kingfisher-rules/data/rules/devcycle.yml
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
rules:
|
||||
- name: DevCycle Client SDK Key
|
||||
id: kingfisher.devcycle.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
dvc_client_[A-Za-z0-9]{8,32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- dvc_client_abc12345
|
||||
- 'sdkKey: "dvc_client_abcdefg1234"'
|
||||
references:
|
||||
- https://docs.devcycle.com/cli-guides/environments/
|
||||
- https://docs.devcycle.com/bucketing-api/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://bucketing-api.devcycle.com/v1/variables
|
||||
headers:
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
Content-Type: application/json
|
||||
body: |
|
||||
{
|
||||
"user_id": "kingfisher-validation-user"
|
||||
}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
|
||||
- name: DevCycle Mobile SDK Key
|
||||
id: kingfisher.devcycle.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
dvc_mobile_[A-Za-z0-9]{8,32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- dvc_mobile_abc12345
|
||||
- 'mobileKey: "dvc_mobile_abcdefg1234"'
|
||||
references:
|
||||
- https://docs.devcycle.com/cli-guides/environments/
|
||||
- https://docs.devcycle.com/bucketing-api/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://bucketing-api.devcycle.com/v1/variables
|
||||
headers:
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
Content-Type: application/json
|
||||
body: |
|
||||
{
|
||||
"user_id": "kingfisher-validation-user"
|
||||
}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
|
||||
- name: DevCycle Server SDK Key
|
||||
id: kingfisher.devcycle.3
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
dvc_server_[A-Za-z0-9]{8,32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- dvc_server_abc12345
|
||||
- 'serverKey: "dvc_server_abcdefg1234"'
|
||||
references:
|
||||
- https://docs.devcycle.com/cli-guides/environments/
|
||||
- https://docs.devcycle.com/bucketing-api/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://bucketing-api.devcycle.com/v1/variables
|
||||
headers:
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
Content-Type: application/json
|
||||
body: |
|
||||
{
|
||||
"user_id": "kingfisher-validation-user"
|
||||
}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
51
crates/kingfisher-rules/data/rules/etsy.yml
Normal file
51
crates/kingfisher-rules/data/rules/etsy.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
rules:
|
||||
- name: Etsy Open API Key
|
||||
id: kingfisher.etsy.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
etsy
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?key |
|
||||
keystring |
|
||||
x-api-key
|
||||
)
|
||||
|
|
||||
x-api-key
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-z0-9]{24}:[A-Za-z0-9]{10,64}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 8
|
||||
ignore_if_contains:
|
||||
- your_api_key
|
||||
- your_key_here
|
||||
- placeholder
|
||||
min_entropy: 3.4
|
||||
confidence: medium
|
||||
examples:
|
||||
- 'x-api-key: 1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5'
|
||||
- ETSY_API_KEY=1aa2bb33c44d55eeeeee6fff:a1b2c3d4e5
|
||||
references:
|
||||
- https://developers.etsy.com/documentation/tutorials/quickstart/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.etsy.com/v3/application/openapi-ping
|
||||
headers:
|
||||
x-api-key: '{{ TOKEN | split: ":" | first }}'
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
|
||||
58
crates/kingfisher-rules/data/rules/firebase.yml
Normal file
58
crates/kingfisher-rules/data/rules/firebase.yml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
rules:
|
||||
- name: Firebase Cloud Messaging Server Key
|
||||
id: kingfisher.firebase.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
AAAA[A-Za-z0-9_-]{7}
|
||||
:
|
||||
APA91b[A-Za-z0-9_-]{120,180}
|
||||
)
|
||||
(?:[^A-Za-z0-9_-]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- sample
|
||||
- placeholder
|
||||
- your_key_here
|
||||
min_entropy: 4.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- FCM_SERVER_KEY=AAAAA1b2CdE:APA91bAbCdEfGhIjKlMnOpQrStUvWxYz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-AaBbCcDdEeFfGgHhIiJj
|
||||
- 'firebase_server_key: "AAAAQ1w2ErT:APA91bZaYxWvUtSrQpOnMlKjIhGfEdCbA9876543210ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-MmNnOoPpQqRrSsTtUuVv"'
|
||||
references:
|
||||
- https://firebase.google.com/docs/cloud-messaging/migrate-v1
|
||||
# FCM legacy server keys no longer have a safe token-only validation path.
|
||||
# HTTP v1 requires OAuth2 access tokens from service accounts rather than the legacy key itself.
|
||||
|
||||
- name: Firebase Cloud Messaging Device Token
|
||||
id: kingfisher.firebase.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
[A-Za-z0-9_-]{22}
|
||||
:
|
||||
APA91b[A-Za-z0-9_-]{120,180}
|
||||
)
|
||||
(?:[^A-Za-z0-9_-]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- sample
|
||||
- placeholder
|
||||
min_entropy: 4.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- FCM_DEVICE_TOKEN=AbCdEfGhIjKlMnOpQrStUv:APA91bZaYxWvUtSrQpOnMlKjIhGfEdCbA9876543210ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-AaBbCcDdEeFfGgHhIiJj
|
||||
- 'registrationToken: "AbCdEfGhIjKlMnOpQrStUv:APA91bZaYxWvUtSrQpOnMlKjIhGfEdCbA9876543210ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-AaBbCcDdEeFfGgHhIiJj"'
|
||||
references:
|
||||
- https://firebase.google.com/docs/cloud-messaging/manage-tokens
|
||||
# Registration tokens can’t be safely live-validated using only the token value.
|
||||
43
crates/kingfisher-rules/data/rules/flutterwave.yml
Normal file
43
crates/kingfisher-rules/data/rules/flutterwave.yml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
rules:
|
||||
- name: Flutterwave Public Key
|
||||
id: kingfisher.flutterwave.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
FLWPUBK(?:_TEST)?-[a-f0-9]{32}-X
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 4
|
||||
min_entropy: 3.1
|
||||
confidence: medium
|
||||
examples:
|
||||
- FLW_PUBLIC_KEY=FLWPUBK_TEST-32193bba8dab84e3d9c4525c85ea7a12-X
|
||||
- data-PBFPubKey="FLWPUBK_TEST-589490616a6297324231c5e89b58f3f6-X"
|
||||
references:
|
||||
- https://developer.flutterwave.com/docs/authentication
|
||||
- https://developer.flutterwave.com/v2.0/docs/api-keys
|
||||
|
||||
- name: Flutterwave Secret Key
|
||||
id: kingfisher.flutterwave.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
FLWSECK(?:_TEST)?-[a-f0-9]{32}-X
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 8
|
||||
min_entropy: 3.3
|
||||
confidence: medium
|
||||
examples:
|
||||
- FLW_SECRET_KEY=FLWSECK_TEST-a514d8f1abd080db1502a144f22954dc-X
|
||||
- 'Authorization: Bearer FLWSECK_TEST-5b1f0a33de9c41748c2a7e9b51d3c6af-X'
|
||||
- seckey=FLWSECK-e6db11d1f8a6208de8cb2f94e293450e-X
|
||||
references:
|
||||
- https://developer.flutterwave.com/docs/authentication
|
||||
- https://developer.flutterwave.com/v2.0/reference/api-request-and-response-standards
|
||||
29
crates/kingfisher-rules/data/rules/freemius.yml
Normal file
29
crates/kingfisher-rules/data/rules/freemius.yml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
rules:
|
||||
- name: Freemius Secret Key
|
||||
id: kingfisher.freemius.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
["']secret_key["']
|
||||
\s*=>\s*
|
||||
["']
|
||||
(
|
||||
sk_[^"' \t\r\n]{29}
|
||||
)
|
||||
["']
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 6
|
||||
min_special_chars: 2
|
||||
ignore_if_contains:
|
||||
- xxxxxxxxx
|
||||
- placeholder
|
||||
min_entropy: 3.6
|
||||
confidence: medium
|
||||
examples:
|
||||
- |
|
||||
$config = array(
|
||||
"secret_key" => "sk_ubb4yN3mzqGR2x8#P7r5&@*xC$utE",
|
||||
);
|
||||
references:
|
||||
- https://freemius.com/help/documentation/wordpress-sdk/integrating-freemius-sdk/
|
||||
|
||||
41
crates/kingfisher-rules/data/rules/fullstory.yml
Normal file
41
crates/kingfisher-rules/data/rules/fullstory.yml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
rules:
|
||||
- name: Fullstory API Key
|
||||
id: kingfisher.fullstory.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:fullstory|fs_api|fullstory_api)
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|AUTHORIZATION|API)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
\b
|
||||
(
|
||||
(?:na1|eu1)\.[A-Za-z0-9]{20,}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.3
|
||||
confidence: medium
|
||||
examples:
|
||||
- FULLSTORY_API_KEY=na1.Abcd1234Efgh5678Ijkl9012Mnop3456
|
||||
- 'fs_api_key: "eu1.Abcd1234Efgh5678Ijkl9012Mnop3456"'
|
||||
references:
|
||||
- https://developer.fullstory.com/server/v1/getting-started/
|
||||
- https://developer.fullstory.com/server/authentication/
|
||||
- https://developer.fullstory.com/server/v1/authentication/me/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.fullstory.com/me
|
||||
headers:
|
||||
Authorization: "Basic {{ TOKEN | append: ':' | b64enc }}"
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
41
crates/kingfisher-rules/data/rules/gcnotify.yml
Normal file
41
crates/kingfisher-rules/data/rules/gcnotify.yml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
rules:
|
||||
- name: GC Notify API Key
|
||||
id: kingfisher.gcnotify.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
ApiKey-v1
|
||||
\s+
|
||||
gcntfy-[a-z0-9_]+
|
||||
-
|
||||
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
|
||||
-
|
||||
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 2
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- 'Authorization: "ApiKey-v1 gcntfy-my_test_key-26785a09-ab16-4eb0-8407-a37497a57506-3d844edf-8d35-48ac-975b-e847b4f122b0"'
|
||||
references:
|
||||
- https://documentation.notification.canada.ca/en/start.html
|
||||
- https://documentation.notification.canada.ca/en/status.html
|
||||
- https://documentation.notification.canada.ca/en/keys.html
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.notification.canada.ca/v2/notifications
|
||||
headers:
|
||||
Authorization: "{{ TOKEN }}"
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
82
crates/kingfisher-rules/data/rules/helpscout.yml
Normal file
82
crates/kingfisher-rules/data/rules/helpscout.yml
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
rules:
|
||||
- name: Help Scout Client ID
|
||||
id: kingfisher.helpscout.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:help[\s_-]?scout|helpscout)
|
||||
(?:.|[\n\r]){0,48}?
|
||||
(?:client[\s_.-]*id|app[\s_.-]*id|application[\s_.-]*id)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
(
|
||||
[A-Za-z0-9]{10,40}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 1
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
min_entropy: 3.1
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- HELPSCOUT_CLIENT_ID=Ab12Cd34Ef56Gh78Ij90
|
||||
- 'helpscout_app_id: "a1B2c3D4e5F6g7H8i9J0K1L2"'
|
||||
references:
|
||||
- https://developer.helpscout.com/mailbox-api/
|
||||
|
||||
- name: Help Scout OAuth Client Secret
|
||||
id: kingfisher.helpscout.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:help[\s_-]?scout|helpscout)
|
||||
(?:.|[\n\r]){0,48}?
|
||||
(?:
|
||||
client[\s_.-]*secret
|
||||
|
|
||||
app[\s_.-]*secret
|
||||
|
|
||||
oauth[\s_.-]*secret
|
||||
)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
(
|
||||
[A-Za-z0-9]{24,64}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- placeholder
|
||||
- yoursecret
|
||||
min_entropy: 3.7
|
||||
confidence: medium
|
||||
examples:
|
||||
- HELPSCOUT_CLIENT_SECRET=a3B8f29E4d1C6a0578e23D9f41b6C8e2
|
||||
- 'helpscout_client_secret: "E7d2A1f849c3B05d6e81F2a794c3D5b0"'
|
||||
references:
|
||||
- https://developer.helpscout.com/mailbox-api/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.helpscout.1
|
||||
variable: CLIENT_ID
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://api.helpscout.net/v2/oauth2/token
|
||||
headers:
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Accept: application/json
|
||||
body: 'grant_type=client_credentials&client_id={{ CLIENT_ID | url_encode }}&client_secret={{ TOKEN | url_encode }}'
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
- type: WordMatch
|
||||
words:
|
||||
- '"access_token"'
|
||||
|
|
@ -20,6 +20,7 @@ rules:
|
|||
- 'HEROKU_API_KEY: c55dbac4-e0e8-4a06-b892-75cac2387ce5'
|
||||
references:
|
||||
- https://devcenter.heroku.com/articles/authentication
|
||||
- https://devcenter.heroku.com/articles/oauth
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
|
|
@ -33,6 +34,35 @@ rules:
|
|||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
revocation:
|
||||
type: HttpMultiStep
|
||||
content:
|
||||
steps:
|
||||
- name: lookup_authorization_id
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.heroku.com/oauth/authorizations
|
||||
headers:
|
||||
Accept: application/vnd.heroku+json; version=3
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
response_matcher:
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
extract:
|
||||
AUTHORIZATION_ID:
|
||||
type: Regex
|
||||
pattern: '"id":"([^"]+)"[^{}]{0,2048}?"token":"{{ TOKEN }}"'
|
||||
- name: revoke_authorization
|
||||
request:
|
||||
method: DELETE
|
||||
url: https://api.heroku.com/oauth/authorizations/{{ AUTHORIZATION_ID }}
|
||||
headers:
|
||||
Accept: application/vnd.heroku+json; version=3
|
||||
Authorization: Bearer {{ TOKEN }}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- name: Heroku API Key (Platform Key)
|
||||
id: kingfisher.heroku.2
|
||||
pattern: |
|
||||
|
|
@ -61,8 +91,38 @@ rules:
|
|||
- '"id":'
|
||||
- '"name":'
|
||||
match_all_words: true
|
||||
revocation:
|
||||
type: HttpMultiStep
|
||||
content:
|
||||
steps:
|
||||
- name: lookup_authorization_id
|
||||
request:
|
||||
method: GET
|
||||
url: https://api.heroku.com/oauth/authorizations
|
||||
headers:
|
||||
Accept: application/vnd.heroku+json; version=3
|
||||
Authorization: Bearer {{TOKEN}}
|
||||
response_matcher:
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
extract:
|
||||
AUTHORIZATION_ID:
|
||||
type: Regex
|
||||
pattern: '"id":"([^"]+)"[^{}]{0,2048}?"token":"{{ TOKEN }}"'
|
||||
- name: revoke_authorization
|
||||
request:
|
||||
method: DELETE
|
||||
url: https://api.heroku.com/oauth/authorizations/{{ AUTHORIZATION_ID }}
|
||||
headers:
|
||||
Accept: application/vnd.heroku+json; version=3
|
||||
Authorization: "Bearer {{TOKEN}}"
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
references:
|
||||
- https://devcenter.heroku.com/articles/platform-api-quickstart
|
||||
- https://devcenter.heroku.com/articles/oauth
|
||||
examples:
|
||||
- "HRKU-AADVTUYvfjT4nhuJ07bEfAUq9GS3PkTdyWuNBiXYmYMg_____wgAf6OTnGyh"
|
||||
- "HRKU-AABW9W1iH9NHEIlAABq9nZUq9GS3PkTdyWuNBiXYmYMg_____wV2XYIXxm5p"
|
||||
|
|
|
|||
129
crates/kingfisher-rules/data/rules/jfrog.yml
Normal file
129
crates/kingfisher-rules/data/rules/jfrog.yml
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
rules:
|
||||
- name: JFrog Cloud Host
|
||||
id: kingfisher.jfrog.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
[a-z0-9]
|
||||
(?:
|
||||
[a-z0-9\-]{0,61}
|
||||
[a-z0-9]
|
||||
)?
|
||||
\.jfrog\.io
|
||||
)
|
||||
\b
|
||||
min_entropy: 2.5
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- company.jfrog.io
|
||||
- my-team.jfrog.io
|
||||
references:
|
||||
- https://jfrog.com/help/api/khub/documents/xrOb4ANk_fqUw5nctnsIww/content
|
||||
|
||||
- name: JFrog API Key
|
||||
id: kingfisher.jfrog.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
jfrog |
|
||||
artifactory |
|
||||
bintray |
|
||||
xray
|
||||
)
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?key |
|
||||
password |
|
||||
token |
|
||||
secret
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9]{73}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_uppercase: 2
|
||||
min_lowercase: 6
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- jfrog_api_key=Ab12Cd34Ef56Gh78Ij90Kl12Mn34Op56Qr78St90Uv12Wx34Yz56Ab78Cd90Ef12Gh34Ij5Kl
|
||||
- jfrog_password=Ab12Cd34Ef56Gh78Ij90Kl12Mn34Op56Qr78St90Uv12Wx34Yz56Ab78Cd90Ef12Gh34Ij5Kl
|
||||
references:
|
||||
- https://jfrog.com/help/api/khub/documents/xrOb4ANk_fqUw5nctnsIww/content
|
||||
- https://jfrog.com/article/access-service/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.jfrog.1
|
||||
variable: JFROG_HOST
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://{{ JFROG_HOST }}/artifactory/api/repositories
|
||||
headers:
|
||||
X-JFrog-Art-Api: '{{ TOKEN }}'
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
|
||||
- name: JFrog Identity Token
|
||||
id: kingfisher.jfrog.3
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
jfrog |
|
||||
artifactory |
|
||||
bintray |
|
||||
xray
|
||||
)
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
identity[_-]?token |
|
||||
access[_-]?token |
|
||||
bearer |
|
||||
token
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9]{64}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_uppercase: 2
|
||||
min_lowercase: 6
|
||||
min_entropy: 3.4
|
||||
confidence: medium
|
||||
examples:
|
||||
- jfrog_identity_token=Ab12Cd34Ef56Gh78Ij90Kl12Mn34Op56Qr78St90Uv12Wx34Yz56Ab78Cd90Ef12
|
||||
- artifactory_access_token=Zx12Cv34Bn56Mm78Aa90Ss12Dd34Ff56Gg78Hh90Jj12Kk34Ll56Qq78Ww90Ee12
|
||||
references:
|
||||
- https://jfrog.com/help/api/khub/documents/xrOb4ANk_fqUw5nctnsIww/content
|
||||
- https://jfrog.com/article/access-service/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.jfrog.1
|
||||
variable: JFROG_HOST
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: https://{{ JFROG_HOST }}/artifactory/api/repositories
|
||||
headers:
|
||||
Authorization: 'Bearer {{ TOKEN }}'
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
31
crates/kingfisher-rules/data/rules/kraken.yml
Normal file
31
crates/kingfisher-rules/data/rules/kraken.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
rules:
|
||||
- name: Kraken API Secret
|
||||
id: kingfisher.kraken.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
kraken
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?secret |
|
||||
secret |
|
||||
private[_-]?key |
|
||||
token
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9+/=_-]{80,90}
|
||||
)
|
||||
(?:[^A-Za-z0-9+/=_-]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_uppercase: 2
|
||||
min_lowercase: 8
|
||||
min_entropy: 4.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- KRAKEN_API_SECRET=dGhpcy1sb29rcy1saWtlLWEtYmFzZTY0LWtyYWtlbi1zZWNyZXQtdGhhdC1pcy1sb25nLWVub3VnaA==
|
||||
- kraken_secret="Aq1Bq2Cr3Ds4Et5Fu6Gv7Hw8Ix9Jy0Kz1La2Mb3Nc4Od5Pe6Qf7Rg8Sh9Ti0Uj1Vk2Wm3Xn4Yo5Za6Bc7"
|
||||
references:
|
||||
- https://docs.kraken.com/api/docs/guides/spot-rest-auth/
|
||||
- https://docs.kraken.com/api/docs/rest-api/get-account-balance/
|
||||
116
crates/kingfisher-rules/data/rules/kubernetes.yml
Normal file
116
crates/kingfisher-rules/data/rules/kubernetes.yml
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
rules:
|
||||
- name: Kubernetes API Server URL
|
||||
id: kingfisher.kubernetes.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
kube(?:rnetes)?(?:_api)?_server
|
||||
|
|
||||
api_server
|
||||
)
|
||||
\s*[:=]\s*
|
||||
["']?
|
||||
(
|
||||
https://
|
||||
(?:
|
||||
\[[0-9a-f:.]+\]
|
||||
|
|
||||
[a-z0-9]
|
||||
[a-z0-9.-]{1,253}
|
||||
)
|
||||
(?::\d{2,5})?
|
||||
)
|
||||
["']?
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- "kube_server: https://10.96.0.1:443"
|
||||
- KUBE_API_SERVER=https://api.cluster.example.com:6443
|
||||
references:
|
||||
- https://kubernetes.io/docs/reference/access-authn-authz/authentication/
|
||||
|
||||
- name: Kubernetes Bootstrap Token
|
||||
id: kingfisher.kubernetes.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
bootstrap(?:[-_ ]token)?
|
||||
|
|
||||
tls[-_ ]bootstrap[-_ ]token
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-z0-9]{6}
|
||||
\.
|
||||
[a-z0-9]{16}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_entropy: 3.2
|
||||
confidence: medium
|
||||
examples:
|
||||
- BOOTSTRAP_TOKEN=be8dfd.da8a689a46edc282
|
||||
- --tls-bootstrap-token abcdef.1234567890abcdef
|
||||
references:
|
||||
- https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.kubernetes.1
|
||||
variable: KUBE_API_SERVER
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: '{{ KUBE_API_SERVER }}/api/v1/namespaces?limit=1'
|
||||
headers:
|
||||
Accept: application/json
|
||||
Authorization: 'Bearer {{ TOKEN }}'
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200, 403]
|
||||
- type: JsonValid
|
||||
|
||||
- name: Kubernetes Bootstrap Token Pair
|
||||
id: kingfisher.kubernetes.3
|
||||
pattern: |
|
||||
(?xis)
|
||||
\btoken-id\b
|
||||
\s*:\s*
|
||||
(?P<TOKEN_ID>[a-z0-9]{6})
|
||||
(?:.|[\n\r]){0,24}?
|
||||
\btoken-secret\b
|
||||
\s*:\s*
|
||||
(?P<TOKEN_SECRET>[a-z0-9]{16})
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_entropy: 2.8
|
||||
confidence: medium
|
||||
examples:
|
||||
- |
|
||||
token-id: 07402b
|
||||
token-secret: f395accd245ae53d
|
||||
references:
|
||||
- https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.kubernetes.1
|
||||
variable: KUBE_API_SERVER
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: '{{ KUBE_API_SERVER }}/api/v1/namespaces?limit=1'
|
||||
headers:
|
||||
Accept: application/json
|
||||
Authorization: 'Bearer {{ TOKEN_ID }}.{{ TOKEN_SECRET }}'
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200, 403]
|
||||
- type: JsonValid
|
||||
62
crates/kingfisher-rules/data/rules/kucoin.yml
Normal file
62
crates/kingfisher-rules/data/rules/kucoin.yml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
rules:
|
||||
- name: KuCoin API Key
|
||||
id: kingfisher.kucoin.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
kucoin
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?key |
|
||||
key
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-f0-9]{24}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 8
|
||||
ignore_if_contains:
|
||||
- xxxxxx
|
||||
- your_api_key
|
||||
min_entropy: 3.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- KUCOIN_API_KEY=4f4ecb6f11b1a70001c8e2ff
|
||||
- 'kucoin_api_key: a1b2c3d4e5f60718293a4b5c'
|
||||
references:
|
||||
- https://www.kucoin.com/docs-new/authentication
|
||||
- https://www.kucoin.com/docs-new/api-3470125
|
||||
|
||||
- name: KuCoin API Secret
|
||||
id: kingfisher.kucoin.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
kucoin
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?secret |
|
||||
secret
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 6
|
||||
min_lowercase: 8
|
||||
ignore_if_contains:
|
||||
- 00000000-0000-0000-0000-000000000000
|
||||
- xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
min_entropy: 3.3
|
||||
confidence: medium
|
||||
examples:
|
||||
- KUCOIN_API_SECRET=7d70f6c7-42e9-4261-8a8d-8ca2d5028d4f
|
||||
- 'kucoin_secret: a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
||||
references:
|
||||
- https://www.kucoin.com/docs-new/authentication
|
||||
|
||||
66
crates/kingfisher-rules/data/rules/octopusdeploy.yml
Normal file
66
crates/kingfisher-rules/data/rules/octopusdeploy.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
rules:
|
||||
- name: Octopus Deploy Server URL
|
||||
id: kingfisher.octopusdeploy.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
(?:
|
||||
\boctopus(?:[_\s.-]?deploy)?(?:[_\s.-]?(?:url|server|host))?\b
|
||||
(?:.|[\n\r]){0,32}?
|
||||
[:=]
|
||||
|
|
||||
\boctopus(?:url|server|host)\b
|
||||
\s*[:=]
|
||||
)
|
||||
\s*["']?
|
||||
(
|
||||
https://
|
||||
[A-Za-z0-9.-]+
|
||||
(?::\d{2,5})?
|
||||
)
|
||||
["']?
|
||||
min_entropy: 2.3
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- OCTOPUS_URL=https://deploy.acme.example
|
||||
- 'octopus_server: "https://octopus.internal.example:8443"'
|
||||
references:
|
||||
- https://octopus.com/docs/octopus-rest-api/getting-started
|
||||
|
||||
- name: Octopus Deploy API Key
|
||||
id: kingfisher.octopusdeploy.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
API-[A-Z0-9]{26}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_uppercase: 4
|
||||
min_entropy: 3.4
|
||||
confidence: medium
|
||||
examples:
|
||||
- OCTOPUS_API_KEY=API-ZNRMR7SL6L3ATMOIK7GKJDKLPY
|
||||
- 'set apikey="API-A1B2C3D4E5F6G7H8J9K0LMNOPQ"'
|
||||
references:
|
||||
- https://octopus.com/docs/octopus-rest-api/getting-started
|
||||
- https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.octopusdeploy.1
|
||||
variable: OCTOPUS_URL
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: '{{ OCTOPUS_URL }}/api'
|
||||
headers:
|
||||
X-Octopus-ApiKey: '{{ TOKEN }}'
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
78
crates/kingfisher-rules/data/rules/openshift.yml
Normal file
78
crates/kingfisher-rules/data/rules/openshift.yml
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
rules:
|
||||
- name: OpenShift API Server URL
|
||||
id: kingfisher.openshift.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
(?:
|
||||
\boc\s+login\b
|
||||
(?:.|[\n\r]){0,128}?
|
||||
--server=
|
||||
|
|
||||
\bopenshift(?:[_-]?(?:server|api(?:[_-]?server)?|cluster(?:[_-]?url)?))?\b
|
||||
(?:.|[\n\r]){0,32}?
|
||||
\b(?:server|api(?:[_-]?server)?|cluster(?:[_-]?url)?)?\b
|
||||
\s*[:=]\s*
|
||||
)
|
||||
["']?
|
||||
(
|
||||
https://
|
||||
(?:
|
||||
\[[0-9a-f:.]+\]
|
||||
|
|
||||
[a-z0-9]
|
||||
[a-z0-9.-]{1,253}
|
||||
)
|
||||
(?::\d{2,5})?
|
||||
)
|
||||
["']?
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- oc login --token=sha256~kV46hPnEYhCWFnB85r5NrprAxggzgb6GOeLbgcKNsH0 --server=https://api.cluster.example.com:6443
|
||||
- OPENSHIFT_SERVER=https://api.dev-cluster.example.net:6443
|
||||
references:
|
||||
- https://docs.redhat.com/en/documentation/openshift_container_platform/4.9/html-single/authentication_and_authorization/index
|
||||
- https://docs.redhat.com/en/documentation/openshift_container_platform/4.17/html/user_and_group_apis/user-user-openshift-io-v1
|
||||
|
||||
- name: OpenShift OAuth Access Token
|
||||
id: kingfisher.openshift.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
sha256~[A-Za-z0-9_-]{43}
|
||||
)
|
||||
(?:[^A-Za-z0-9_-]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 3
|
||||
min_uppercase: 1
|
||||
min_lowercase: 3
|
||||
ignore_if_contains:
|
||||
- put_your_token_here
|
||||
- xxxxxx
|
||||
min_entropy: 3.8
|
||||
confidence: medium
|
||||
examples:
|
||||
- 'Authorization: Bearer sha256~kV46hPnEYhCWFnB85r5NrprAxggzgb6GOeLbgcKNsH0'
|
||||
- oc login --token=sha256~ZBMKw9VAayhdnyANaHvjJeXDiGwA7Fsr5gtLKj3-eh- --server=https://api.cluster.example.com:6443
|
||||
references:
|
||||
- https://docs.redhat.com/en/documentation/openshift_container_platform/4.17/html/oauth_apis/oauthaccesstoken-oauth-openshift-io-v1
|
||||
- https://docs.redhat.com/en/documentation/openshift_container_platform/4.9/html-single/authentication_and_authorization/index
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.openshift.1
|
||||
variable: OPENSHIFT_API_SERVER
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: '{{ OPENSHIFT_API_SERVER }}/apis/user.openshift.io/v1/users'
|
||||
headers:
|
||||
Authorization: 'Bearer {{ TOKEN }}'
|
||||
Accept: application/json
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200, 403]
|
||||
- type: JsonValid
|
||||
85
crates/kingfisher-rules/data/rules/polymarket.yml
Normal file
85
crates/kingfisher-rules/data/rules/polymarket.yml
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
rules:
|
||||
- name: Polymarket Builder Secret
|
||||
id: kingfisher.polymarket.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
poly(?:market)?
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:builder|api)?
|
||||
(?:.|[\n\r]){0,16}?
|
||||
secret
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9+/]{40,88}={0,2}
|
||||
)
|
||||
(?:[^A-Za-z0-9+/=]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 8
|
||||
min_entropy: 3.6
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- POLY_BUILDER_SECRET=QmFzZTY0U2VjcmV0VGVzdEtleTEyMzQ1Njc4OTBBQkNERUY=
|
||||
- 'polymarket_builder_secret: Q29tcGxleFNlY3JldE1hdGVyaWFsMTIzNDU2Nzg5MDEyMzQ='
|
||||
references:
|
||||
- https://docs.polymarket.com/trading/orders/attribution
|
||||
|
||||
- name: Polymarket Builder Passphrase
|
||||
id: kingfisher.polymarket.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
poly(?:market)?
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:builder|api)?
|
||||
(?:.|[\n\r]){0,16}?
|
||||
passphrase
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9_]{8,128}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 1
|
||||
min_uppercase: 1
|
||||
min_lowercase: 4
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- placeholder
|
||||
min_entropy: 3.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- POLY_BUILDER_PASSPHRASE=BuilderPass_2026
|
||||
- 'polymarket_passphrase: AlphaPass_7788'
|
||||
references:
|
||||
- https://docs.polymarket.com/trading/orders/attribution
|
||||
|
||||
- name: Polymarket Builder API Key
|
||||
id: kingfisher.polymarket.3
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
poly(?:market)?
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:builder|api)?
|
||||
(?:.|[\n\r]){0,16}?
|
||||
key
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 6
|
||||
min_lowercase: 8
|
||||
min_entropy: 3.2
|
||||
confidence: medium
|
||||
examples:
|
||||
- POLY_BUILDER_API_KEY=12345678-abcd-1234-efab-1234567890ab
|
||||
- 'polymarket_api_key: a1b2c3d4-e5f6-789a-bcde-f0123456789a'
|
||||
references:
|
||||
- https://docs.polymarket.com/trading/orders/attribution
|
||||
58
crates/kingfisher-rules/data/rules/privateai.yml
Normal file
58
crates/kingfisher-rules/data/rules/privateai.yml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
rules:
|
||||
- name: Private AI API Key
|
||||
id: kingfisher.privateai.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
private[_-]?ai
|
||||
|
|
||||
limina
|
||||
)
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
api[_-]?key
|
||||
|
|
||||
x-api-key
|
||||
|
|
||||
token
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[a-z0-9]{32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 8
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- placeholder
|
||||
- insert
|
||||
- your
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- PRIVATEAI_API_KEY=4fa2d7c81be9063d4ea8bc1f6d2a7e9c
|
||||
- 'privateai_x_api_key: 2ab4d6e8f0c1a3b5d7e9f1a2b4c6d8e0'
|
||||
references:
|
||||
- https://docs.private-ai.com/fundamentals/getting-started
|
||||
- https://docs.private-ai.com/reference/4.0.0/operation/ner_text_ner_text_post/
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: https://api.private-ai.com/community/v4/process/text
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
x-api-key: '{{ TOKEN }}'
|
||||
body: '{"text":["Hello Jane Doe"]}'
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
- type: WordMatch
|
||||
words:
|
||||
- '"processed_text"'
|
||||
63
crates/kingfisher-rules/data/rules/settlemint.yml
Normal file
63
crates/kingfisher-rules/data/rules/settlemint.yml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
rules:
|
||||
- name: SettleMint Personal Access Token
|
||||
id: kingfisher.settlemint.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
sm_pat_[A-Za-z0-9]{16}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 4
|
||||
min_entropy: 3.2
|
||||
confidence: medium
|
||||
examples:
|
||||
- SETTLEMINT_ACCESS_TOKEN=sm_pat_A1b2C3d4E5f6G7h8
|
||||
- settlemint connect --pat=sm_pat_Z9y8X7w6V5u4T3s2
|
||||
references:
|
||||
- https://console.settlemint.com/documentation/blockchain-platform/platform-components/security-and-authentication/personal-access-tokens
|
||||
|
||||
- name: SettleMint Application Access Token
|
||||
id: kingfisher.settlemint.2
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
sm_aat_[A-Za-z0-9]{16}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 4
|
||||
min_entropy: 3.2
|
||||
confidence: medium
|
||||
examples:
|
||||
- BLOCKSCOUT_SETTLEMINT_APPLICATION_ACCESS_TOKEN=sm_aat_A1b2C3d4E5f6G7h8
|
||||
- 'x-auth-token: sm_aat_Z9y8X7w6V5u4T3s2'
|
||||
references:
|
||||
- https://console.settlemint.com/documentation/blockchain-platform/platform-components/security-and-authentication/application-access-tokens
|
||||
|
||||
- name: SettleMint Service Access Token
|
||||
id: kingfisher.settlemint.3
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
sm_sat_[A-Za-z0-9]{16}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 4
|
||||
min_entropy: 3.2
|
||||
confidence: medium
|
||||
examples:
|
||||
- SETTLEMINT_SERVICE_TOKEN=sm_sat_A1b2C3d4E5f6G7h8
|
||||
- 'Authorization: Bearer sm_sat_Z9y8X7w6V5u4T3s2'
|
||||
references:
|
||||
- https://console.settlemint.com/documentation
|
||||
58
crates/kingfisher-rules/data/rules/sidekiq.yml
Normal file
58
crates/kingfisher-rules/data/rules/sidekiq.yml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
rules:
|
||||
- name: Sidekiq Enterprise Credential
|
||||
id: kingfisher.sidekiq.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:
|
||||
BUNDLE_ENTERPRISE__CONTRIBSYS__COM
|
||||
|
|
||||
BUNDLE_GEMS__CONTRIBSYS__COM
|
||||
)
|
||||
\s*[:=]\s*
|
||||
["']?
|
||||
(
|
||||
[a-f0-9]{8}:[a-f0-9]{8}
|
||||
)
|
||||
["']?
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 4
|
||||
min_entropy: 2.8
|
||||
confidence: medium
|
||||
examples:
|
||||
- BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafe1234:dead5678
|
||||
- 'export BUNDLE_GEMS__CONTRIBSYS__COM="ca1eb4b3:d3ad533f"'
|
||||
|
||||
- name: Sidekiq Sensitive URL
|
||||
id: kingfisher.sidekiq.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
(
|
||||
https?://
|
||||
[a-f0-9]{8}:[a-f0-9]{8}
|
||||
@
|
||||
(?:
|
||||
gems\.contribsys\.com
|
||||
|
|
||||
enterprise\.contribsys\.com
|
||||
)
|
||||
(?:
|
||||
/[^ \t\r\n"'<>]*
|
||||
|
|
||||
\?[^ \t\r\n"'<>]*
|
||||
|
|
||||
\#[^ \t\r\n"'<>]*
|
||||
|
|
||||
:[0-9]{1,5}(?:/[^ \t\r\n"'<>]*)?
|
||||
)?
|
||||
)
|
||||
pattern_requirements:
|
||||
min_digits: 4
|
||||
min_lowercase: 4
|
||||
min_entropy: 2.8
|
||||
confidence: medium
|
||||
examples:
|
||||
- https://cafe1234:dead5678@gems.contribsys.com/
|
||||
- http://ca1eb4b3:d3ad533f@enterprise.contribsys.com:80/path?param1=true
|
||||
76
crates/kingfisher-rules/data/rules/stytch.yml
Normal file
76
crates/kingfisher-rules/data/rules/stytch.yml
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
rules:
|
||||
- name: Stytch Project ID
|
||||
id: kingfisher.stytch.1
|
||||
visible: false
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
project-(?:test|live)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
|
||||
)
|
||||
\b
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
examples:
|
||||
- project-test-8aed2e54-0266-4793-9b5e-0cc9c56064da
|
||||
references:
|
||||
- https://stytch.com/docs/api-reference/consumer/api/overview
|
||||
- https://stytch.com/docs/api-reference/b2b/api/sessions/authenticate-jwt
|
||||
|
||||
- name: Stytch Project Secret
|
||||
id: kingfisher.stytch.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
secret-(?:test|live)-[A-Za-z0-9_-]{35}=?
|
||||
)
|
||||
(?:[^A-Za-z0-9_=-]|$)
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- secret-test-IJ7zLTgXp8xoS7yXO2xavNxZTbYfvm-2nZM=
|
||||
references:
|
||||
- https://stytch.com/docs/api-reference/consumer/api/overview
|
||||
- https://stytch.com/docs/api-reference/b2b/api/m2m/overview
|
||||
- https://stytch.com/docs/api-reference/b2b/api/sessions/authenticate-jwt
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.stytch.1
|
||||
variable: STYTCH_PROJECT_ID
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: POST
|
||||
url: >
|
||||
{%- if TOKEN contains "-live-" -%}
|
||||
https://api.stytch.com/v1/m2m/clients/search
|
||||
{%- else -%}
|
||||
https://test.stytch.com/v1/m2m/clients/search
|
||||
{%- endif -%}
|
||||
headers:
|
||||
Authorization: "Basic {{ STYTCH_PROJECT_ID | append: ':' | append: TOKEN | b64enc }}"
|
||||
Content-Type: application/json
|
||||
body: |
|
||||
{
|
||||
"query": {
|
||||
"operator": "AND",
|
||||
"operands": [
|
||||
{
|
||||
"filter_name": "status",
|
||||
"filter_value": ["active"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: WordMatch
|
||||
words:
|
||||
- '"m2m_clients"'
|
||||
31
crates/kingfisher-rules/data/rules/trello.yml
Normal file
31
crates/kingfisher-rules/data/rules/trello.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
rules:
|
||||
- name: Trello API Token
|
||||
id: kingfisher.trello.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
trello
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:
|
||||
token |
|
||||
api[_-]?token |
|
||||
access[_-]?token
|
||||
)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9]{32}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_lowercase: 6
|
||||
ignore_if_contains:
|
||||
- yourtoken
|
||||
- placeholder
|
||||
min_entropy: 3.1
|
||||
confidence: medium
|
||||
examples:
|
||||
- TRELLO_TOKEN=0a1b2c3d4e5f6g7h8i9j0k1l2m3n4p5q
|
||||
- trello_access_token="Ab12Cd34Ef56Gh78Ij90Kl12Mn34Op56"
|
||||
references:
|
||||
- https://developer.atlassian.com/cloud/trello/guides/rest-api/api-introduction/
|
||||
20
crates/kingfisher-rules/data/rules/zapier.yml
Normal file
20
crates/kingfisher-rules/data/rules/zapier.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
rules:
|
||||
- name: Zapier Webhook URL
|
||||
id: kingfisher.zapier.1
|
||||
pattern: |
|
||||
(?x)
|
||||
\b
|
||||
(
|
||||
https://hooks\.zapier\.com/hooks/catch/
|
||||
[0-9]{5,10}
|
||||
/
|
||||
[a-z0-9]{5,12}
|
||||
/?
|
||||
)
|
||||
min_entropy: 3.4
|
||||
confidence: medium
|
||||
examples:
|
||||
- ZAPIER_WEBHOOK=https://hooks.zapier.com/hooks/catch/11595998/3ouwv7m/
|
||||
- webhook_url="https://hooks.zapier.com/hooks/catch/2929690/ztd17n/"
|
||||
references:
|
||||
- https://help.zapier.com/hc/en-us/articles/8496288690317-Trigger-Zaps-from-webhooks
|
||||
105
crates/kingfisher-rules/data/rules/zendesk.yml
Normal file
105
crates/kingfisher-rules/data/rules/zendesk.yml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
rules:
|
||||
- name: Zendesk Subdomain
|
||||
id: kingfisher.zendesk.1
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
[a-z0-9]
|
||||
(?:
|
||||
[a-z0-9-]{0,61}
|
||||
[a-z0-9]
|
||||
)?
|
||||
\.zendesk\.com
|
||||
)
|
||||
\b
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- acme-support.zendesk.com
|
||||
- helpdesk-prod.zendesk.com
|
||||
references:
|
||||
- https://developer.zendesk.com/api-reference/introduction/doc-conventions/
|
||||
|
||||
- name: Zendesk Account Email
|
||||
id: kingfisher.zendesk.2
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:zendesk|zd)
|
||||
(?:.|[\n\r]){0,32}?
|
||||
(?:email|user(?:name)?)
|
||||
(?:.|[\n\r]){0,12}?
|
||||
(
|
||||
[A-Za-z0-9._%+\-]+
|
||||
@
|
||||
[A-Za-z0-9.\-]+\.[A-Za-z]{2,}
|
||||
)
|
||||
\b
|
||||
min_entropy: 2.0
|
||||
confidence: medium
|
||||
visible: false
|
||||
examples:
|
||||
- ZENDESK_EMAIL=agent@example.com
|
||||
- 'zendesk_user: "support.bot@example.org"'
|
||||
references:
|
||||
- https://developer.zendesk.com/api-reference/introduction/security-and-auth/
|
||||
|
||||
- name: Zendesk API Token
|
||||
id: kingfisher.zendesk.3
|
||||
pattern: |
|
||||
(?xi)
|
||||
\b
|
||||
(?:zendesk|zd)
|
||||
(?:.|[\n\r]){0,48}?
|
||||
(?:
|
||||
api[\s_.-]*token
|
||||
|
|
||||
token
|
||||
|
|
||||
api[\s_.-]*key
|
||||
)
|
||||
(?:.|[\n\r]){0,16}?
|
||||
(
|
||||
[A-Za-z0-9]{40}
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
min_uppercase: 1
|
||||
min_lowercase: 1
|
||||
ignore_if_contains:
|
||||
- example
|
||||
- placeholder
|
||||
- yourtoken
|
||||
min_entropy: 3.8
|
||||
confidence: medium
|
||||
examples:
|
||||
- ZENDESK_API_TOKEN=a3B8f29E4d1C6a0578e23D9f41b6C8e2qR7tY4uI
|
||||
- zendesk_token="E7d2A1f849c3B05d6e81F2a794c3D5b0pQ8wX1zK"
|
||||
references:
|
||||
- https://developer.zendesk.com/api-reference/introduction/security-and-auth/
|
||||
- https://developer.zendesk.com/api-reference/ticketing/account-configuration/current_user/
|
||||
depends_on_rule:
|
||||
- rule_id: kingfisher.zendesk.1
|
||||
variable: ZENDESK_HOST
|
||||
- rule_id: kingfisher.zendesk.2
|
||||
variable: ZENDESK_EMAIL
|
||||
validation:
|
||||
type: Http
|
||||
content:
|
||||
request:
|
||||
method: GET
|
||||
url: 'https://{{ ZENDESK_HOST }}/api/v2/users/me.json'
|
||||
headers:
|
||||
Accept: application/json
|
||||
Authorization: 'Basic {{ ZENDESK_EMAIL | append: "/token:" | append: TOKEN | b64enc }}'
|
||||
response_matcher:
|
||||
- report_response: true
|
||||
- type: StatusMatch
|
||||
status: [200]
|
||||
- type: JsonValid
|
||||
- type: WordMatch
|
||||
words:
|
||||
- '"user"'
|
||||
|
|
@ -182,6 +182,45 @@ impl Filter for HmacSha256Filter {
|
|||
}
|
||||
}
|
||||
|
||||
// ── HMAC-SHA256 with base64-encoded key ──────────────────────────────────
|
||||
#[derive(Debug, FilterParameters)]
|
||||
struct HmacB64KeyArgs {
|
||||
#[parameter(description = "Base64-encoded HMAC key", arg_type = "str")]
|
||||
key: Expression,
|
||||
}
|
||||
|
||||
#[derive(Clone, ParseFilter, FilterReflection, Default)]
|
||||
#[filter(
|
||||
name = "hmac_sha256_b64key",
|
||||
description = "HMAC-SHA256 with a base64-encoded key – decodes the key to raw bytes before signing. Returns Base64.",
|
||||
parameters(HmacB64KeyArgs),
|
||||
parsed(HmacSha256B64KeyFilter)
|
||||
)]
|
||||
pub struct HmacSha256B64Key;
|
||||
|
||||
#[derive(Debug, FromFilterParameters, Display_filter)]
|
||||
#[name = "hmac_sha256_b64key"]
|
||||
struct HmacSha256B64KeyFilter {
|
||||
#[parameters]
|
||||
args: HmacB64KeyArgs,
|
||||
}
|
||||
|
||||
impl Filter for HmacSha256B64KeyFilter {
|
||||
fn evaluate(&self, input: &dyn ValueView, runtime: &dyn Runtime) -> Result<Value> {
|
||||
let args = self.args.evaluate(runtime)?;
|
||||
let key_b64 = args.key.to_kstr();
|
||||
|
||||
let key_bytes = general_purpose::STANDARD.decode(key_b64.as_bytes()).map_err(|e| {
|
||||
LiquidError::with_msg(format!("hmac_sha256_b64key: invalid base64 key: {e}"))
|
||||
})?;
|
||||
|
||||
let mut mac = Hmac::<Sha256>::new_from_slice(&key_bytes)
|
||||
.map_err(|e| LiquidError::with_msg(format!("hmac_sha256_b64key: {e}")))?;
|
||||
mac.update(input.to_kstr().as_bytes());
|
||||
Ok(Value::scalar(general_purpose::STANDARD.encode(mac.finalize().into_bytes())))
|
||||
}
|
||||
}
|
||||
|
||||
// ── HMAC-SHA1 ─────────────────────────────────────────────
|
||||
#[derive(Debug, FilterParameters)]
|
||||
struct HmacSha1Args {
|
||||
|
|
@ -439,6 +478,14 @@ impl Filter for B64DecFilter {
|
|||
}
|
||||
}
|
||||
|
||||
// {{ "any" | newline }} → "\n" (appends nothing, just returns a newline character)
|
||||
static_filter!(
|
||||
/// Returns a single newline character. Useful inside YAML block scalars where
|
||||
/// a literal newline in the template would break indentation.
|
||||
NewlineFilter, "newline",
|
||||
|_input: &dyn ValueView| -> String { "\n".to_string() }
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Authentication & Security
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -912,6 +959,7 @@ pub fn register_all(builder: liquid::ParserBuilder) -> liquid::ParserBuilder {
|
|||
.filter(JwtHeaderFilter::default())
|
||||
.filter(B64EncFilter::default())
|
||||
.filter(B64DecFilter::default())
|
||||
.filter(NewlineFilter::default())
|
||||
.filter(RandomStringFilter::default())
|
||||
.filter(SuffixFilter::default())
|
||||
.filter(PrefixFilter::default())
|
||||
|
|
@ -923,6 +971,7 @@ pub fn register_all(builder: liquid::ParserBuilder) -> liquid::ParserBuilder {
|
|||
.filter(Base62Filter::default())
|
||||
.filter(Base36Filter::default())
|
||||
.filter(HmacSha256::default())
|
||||
.filter(HmacSha256B64Key::default())
|
||||
.filter(HmacSha1::default())
|
||||
.filter(HmacSha384::default())
|
||||
}
|
||||
|
|
@ -1073,6 +1122,21 @@ mod tests {
|
|||
assert_eq!(render(r#"{{ "hi!" | hmac_sha256: "secret" }}"#), expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hmac_sha256_b64key_filter() {
|
||||
// Key is base64-encoded; the filter must decode it to raw bytes before HMAC.
|
||||
let raw_key: &[u8] = &[0x00, 0x80, 0xFF, 0x42, 0xDE, 0xAD, 0xBE, 0xEF];
|
||||
let b64_key = general_purpose::STANDARD.encode(raw_key);
|
||||
|
||||
let data = b"hello azure";
|
||||
let mut mac = Hmac::<Sha256>::new_from_slice(raw_key).unwrap();
|
||||
mac.update(data);
|
||||
let expect = general_purpose::STANDARD.encode(mac.finalize().into_bytes());
|
||||
|
||||
let template = format!(r#"{{{{ "hello azure" | hmac_sha256_b64key: "{b64_key}" }}}}"#);
|
||||
assert_eq!(render(&template), expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hmac_sha384_filter() {
|
||||
let key = b"topsecret";
|
||||
|
|
|
|||
|
|
@ -315,10 +315,10 @@ let template = parser.parse("{{ secret | sha256 }}")?;
|
|||
|
||||
Available filters:
|
||||
- **Encoding**: `b64enc`, `b64dec`, `b64url_enc`, `url_encode`, `json_escape`
|
||||
- **Hashing**: `sha256`, `crc32`, `crc32_dec`, `crc32_hex`
|
||||
- **HMAC**: `hmac_sha256`, `hmac_sha384`, `hmac_sha1`
|
||||
- **Hashing**: `sha256`, `crc32`, `crc32_dec`, `crc32_hex`, `crc32_le_b64`
|
||||
- **HMAC**: `hmac_sha256`, `hmac_sha384`, `hmac_sha1`, `hmac_sha256_b64key`
|
||||
- **Encoding**: `base62`, `base36`
|
||||
- **Strings**: `prefix`, `suffix`, `replace`, `lstrip_chars`, `random_string`
|
||||
- **Strings**: `prefix`, `suffix`, `replace`, `lstrip_chars`, `random_string`, `newline`
|
||||
- **Time**: `unix_timestamp`, `iso_timestamp`, `iso_timestamp_no_frac`
|
||||
- **Other**: `uuid`, `jwt_header`
|
||||
|
||||
|
|
|
|||
|
|
@ -468,6 +468,7 @@ Below is the complete list of Liquid filters available in Kingfisher, along with
|
|||
| `hmac_sha1` | `key` (string) | Computes HMAC-SHA1 over the input, returns Base64-encoded result. | `{{ TOKEN \| hmac_sha1: "secret-key" }}` |
|
||||
| `hmac_sha256` | `key` (string) | Computes HMAC-SHA256 over the input, returns Base64-encoded result. | `{{ TOKEN \| hmac_sha256: "secret-key" }}` |
|
||||
| `hmac_sha384` | `key` (string) | Computes HMAC-SHA384 over the input, returns Base64-encoded result. | `{{ TOKEN \| hmac_sha384: "secret-key" }}` |
|
||||
| `hmac_sha256_b64key` | `key` (string, base64-encoded) | Decodes the key from Base64 to raw bytes, then computes HMAC-SHA256. Returns Base64. Use for Azure SAS and other protocols where the signing key is base64-encoded. | `{{ to_sign \| hmac_sha256_b64key: TOKEN }}` |
|
||||
| `random_string` | `len` (integer, optional) | Generates a cryptographically-secure random alphanumeric string of the specified length (default: 32). | `{{ "" \| random_string: 16 }}` |
|
||||
| `prefix` | `len` (integer, optional) | Returns the first `len` characters from the string (default: full). | `{{ TOKEN \| prefix: 6 }}` |
|
||||
| `suffix` | `len` (integer, optional) | Returns the last `len` characters from the string (default: full). | `{{ TOKEN \| suffix: 6 }}` |
|
||||
|
|
@ -480,6 +481,8 @@ Below is the complete list of Liquid filters available in Kingfisher, along with
|
|||
| `uuid` | – | Generates a random UUIDv4 string. | `{{ "" \| uuid }}` |
|
||||
| `jwt_header` | – | Builds a minimal JWT header JSON (`{"typ":"JWT","alg":…}`) and Base64URL-encodes it. | `{{ "HS256" \| jwt_header }}` |
|
||||
| `replace` | `from` (string), `to` (string) | Replaces every occurrence of `from` with `to` in the input string. | `{{ "hello world" \| replace: "world", "mars" }}` |
|
||||
| `newline` | – | Returns a single newline character (`\n`). Useful inside YAML block scalars where a literal newline would break indentation. | `{{ "" \| newline }}` |
|
||||
| `base36` | `width` (integer, optional) | Encodes the input number as Base36, left-padding with zeros as needed. | `{{ TOKEN \| crc32 \| base36: 6 }}` |
|
||||
|
||||
|
||||
**Chaining & Composition:** Filters can be stacked; e.g.:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue