forked from mirrors/kingfisher
Authored Devin / Cognition rule
This commit is contained in:
parent
a0d2fa3611
commit
0552d67df7
7 changed files with 214 additions and 2 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -239,5 +239,6 @@ rust-project.json
|
||||||
# MkDocs build output
|
# MkDocs build output
|
||||||
docs-site/site/
|
docs-site/site/
|
||||||
|
|
||||||
|
.codegraph/
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/python
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [v1.102.0]
|
||||||
|
- Added 3 detection and validation rules for Cognition Devin API credentials: `kingfisher.devin.1` (legacy personal keys, `apk_user_` prefix), `kingfisher.devin.2` (legacy service keys, `apk_` prefix), and `kingfisher.devin.3` (v3 service-user tokens, `cog_` prefix / RFC 4648 base32). Live validation uses `GET /v1/sessions` for `apk_*` keys and `GET /v3/self` for `cog_` tokens.
|
||||||
|
|
||||||
## [v1.101.0]
|
## [v1.101.0]
|
||||||
- Fixed asymmetric JWT validation panics by using a single `jsonwebtoken` crypto backend and adding RS256 regression coverage. Thanks @AgentEnder. [#386](https://github.com/mongodb/kingfisher/pull/386)
|
- Fixed asymmetric JWT validation panics by using a single `jsonwebtoken` crypto backend and adding RS256 regression coverage. Thanks @AgentEnder. [#386](https://github.com/mongodb/kingfisher/pull/386)
|
||||||
- Validator panics now fail that validation result instead of crashing the scan, with panic payloads kept out of cached and user-visible validation responses. Thanks @AgentEnder. [#387](https://github.com/mongodb/kingfisher/pull/387)
|
- Validator panics now fail that validation result instead of crashing the scan, with panic payloads kept out of cached and user-visible validation responses. Thanks @AgentEnder. [#387](https://github.com/mongodb/kingfisher/pull/387)
|
||||||
|
|
|
||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4958,7 +4958,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kingfisher"
|
name = "kingfisher"
|
||||||
version = "1.101.0"
|
version = "1.102.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"asar",
|
"asar",
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ http = "1.4"
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kingfisher"
|
name = "kingfisher"
|
||||||
version = "1.101.0"
|
version = "1.102.0"
|
||||||
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
|
||||||
153
crates/kingfisher-rules/data/rules/devin.yml
Normal file
153
crates/kingfisher-rules/data/rules/devin.yml
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
rules:
|
||||||
|
- name: Cognition Devin Personal API Key
|
||||||
|
id: kingfisher.devin.1
|
||||||
|
# Personal/user API keys are emitted as:
|
||||||
|
# apk_user_<base64( "user-<32hex>_org-<32hex>:<32hex>" )>
|
||||||
|
# The encoded body is ~144 base64 chars and may end with `=` padding.
|
||||||
|
pattern: |
|
||||||
|
(?x)
|
||||||
|
\b
|
||||||
|
(
|
||||||
|
apk_user_[A-Za-z0-9+/]{120,180}={0,2}
|
||||||
|
)
|
||||||
|
pattern_requirements:
|
||||||
|
min_digits: 2
|
||||||
|
min_lowercase: 1
|
||||||
|
min_uppercase: 1
|
||||||
|
ignore_if_contains:
|
||||||
|
- "YOUR_"
|
||||||
|
- "REPLACE_"
|
||||||
|
- "EXAMPLE"
|
||||||
|
min_entropy: 4.0
|
||||||
|
confidence: medium
|
||||||
|
examples:
|
||||||
|
- apk_user_dXNlci0yMDc5ZjllYTUyZDA0OWE0OTVlOWUwNDc2OTJiNWZhYl9vcmctZmE4NzllMzdjYWRmNGI2YmJmMmE3YWYzMTgxZGVjMTM6MjUwZjRhNzc2ZDEyNGVlMTk0NDk5OGNhNmRmNjBiY2I=
|
||||||
|
- "DEVIN_API_KEY=apk_user_dXNlci0yMDc5ZjllYTUyZDA0OWE0OTVlOWUwNDc2OTJiNWZhYl9vcmctZmE4NzllMzdjYWRmNGI2YmJmMmE3YWYzMTgxZGVjMTM6YTYzNWU0MTA3M2VkNDU3OGFmZDFhMjAxZDhkMjNkODg="
|
||||||
|
- "Authorization: Bearer apk_user_dXNlci0yMDc5ZjllYTUyZDA0OWE0OTVlOWUwNDc2OTJiNWZhYl9vcmctZmE4NzllMzdjYWRmNGI2YmJmMmE3YWYzMTgxZGVjMTM6NDMxYWFhYjBmN2VmNGRmMTlmZjkwNTBiNDhlYmE3NjM="
|
||||||
|
references:
|
||||||
|
- https://docs.devin.ai/api-reference/overview
|
||||||
|
- https://docs.devin.ai/api-reference/v1/sessions
|
||||||
|
validation:
|
||||||
|
type: Http
|
||||||
|
content:
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
url: https://api.devin.ai/v1/sessions?limit=1
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {{ TOKEN }}"
|
||||||
|
Accept: application/json
|
||||||
|
response_matcher:
|
||||||
|
- report_response: true
|
||||||
|
- type: StatusMatch
|
||||||
|
status: [200]
|
||||||
|
- type: JsonValid
|
||||||
|
- type: WordMatch
|
||||||
|
words:
|
||||||
|
- '"sessions"'
|
||||||
|
match_all_words: true
|
||||||
|
# Revocation: no documented self-service revocation endpoint exists for
|
||||||
|
# legacy apk_user_* keys; users must rotate them via the Devin web UI.
|
||||||
|
|
||||||
|
- name: Cognition Devin Service API Key
|
||||||
|
id: kingfisher.devin.2
|
||||||
|
# Legacy service API keys are emitted as:
|
||||||
|
# apk_<base64( "org-<32hex>:<32hex>" )>
|
||||||
|
# The encoded body is ~92 base64 chars. The base64 charset contains no
|
||||||
|
# underscore, so apk_user_* tokens (which contain an underscore after
|
||||||
|
# "user") cannot be matched by this rule.
|
||||||
|
pattern: |
|
||||||
|
(?x)
|
||||||
|
\b
|
||||||
|
(
|
||||||
|
apk_[A-Za-z0-9+/]{80,100}={0,2}
|
||||||
|
)
|
||||||
|
\b
|
||||||
|
pattern_requirements:
|
||||||
|
min_digits: 2
|
||||||
|
min_lowercase: 1
|
||||||
|
min_uppercase: 1
|
||||||
|
ignore_if_contains:
|
||||||
|
- "apk_user_"
|
||||||
|
- "YOUR_"
|
||||||
|
- "REPLACE_"
|
||||||
|
- "EXAMPLE"
|
||||||
|
min_entropy: 4.0
|
||||||
|
confidence: medium
|
||||||
|
examples:
|
||||||
|
- apk_b3JnLWZhODc5ZTM3Y2FkZjRiNmJiZjJhN2FmMzE4MWRlYzEzOjM0MTU3ZWU4NTZiMjRkMjI5MDYwNzAxOGJmMGEyYzU0
|
||||||
|
- "DEVIN_API_KEY=apk_b3JnLWZhODc5ZTM3Y2FkZjRiNmJiZjJhN2FmMzE4MWRlYzEzOmFjMWE2YWEwZjhjYzQ0OGNiY2Q5ZDJlOTI5MGEyN2Jh"
|
||||||
|
- "Authorization: Bearer apk_b3JnLWZhODc5ZTM3Y2FkZjRiNmJiZjJhN2FmMzE4MWRlYzEzOjU2NTNiMWJhNTMyMDRmMmFhNjg5Y2E5OGE2OTM4Yzc2"
|
||||||
|
references:
|
||||||
|
- https://docs.devin.ai/api-reference/overview
|
||||||
|
- https://docs.devin.ai/api-reference/v1/sessions
|
||||||
|
validation:
|
||||||
|
type: Http
|
||||||
|
content:
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
url: https://api.devin.ai/v1/sessions?limit=1
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {{ TOKEN }}"
|
||||||
|
Accept: application/json
|
||||||
|
response_matcher:
|
||||||
|
- report_response: true
|
||||||
|
- type: StatusMatch
|
||||||
|
status: [200]
|
||||||
|
- type: JsonValid
|
||||||
|
- type: WordMatch
|
||||||
|
words:
|
||||||
|
- '"sessions"'
|
||||||
|
match_all_words: true
|
||||||
|
# Revocation: no documented self-service revocation endpoint exists for
|
||||||
|
# legacy apk_* service keys; users must rotate them via the Devin web UI.
|
||||||
|
|
||||||
|
- name: Cognition Devin Service User Token
|
||||||
|
id: kingfisher.devin.3
|
||||||
|
# v3 service-user credentials issued via the Devin UI. Format:
|
||||||
|
# cog_<52 chars from RFC 4648 base32 lowercase alphabet [a-z2-7]>
|
||||||
|
pattern: |
|
||||||
|
(?x)
|
||||||
|
\b
|
||||||
|
(
|
||||||
|
cog_[a-z2-7]{52}
|
||||||
|
)
|
||||||
|
\b
|
||||||
|
pattern_requirements:
|
||||||
|
min_lowercase: 10
|
||||||
|
ignore_if_contains:
|
||||||
|
- "YOUR_"
|
||||||
|
- "REPLACE_"
|
||||||
|
- "EXAMPLE"
|
||||||
|
min_entropy: 4.0
|
||||||
|
confidence: medium
|
||||||
|
examples:
|
||||||
|
- cog_l5osrifmypvazi4j3yko52gj6jfj7qprsmy4lrcf27jas4szffha
|
||||||
|
- "DEVIN_API_KEY=cog_uv23fh6fc5kpaxdqif7hyvmzslnbmwriqita7cqkbb4rpaixnleq"
|
||||||
|
- "Authorization: Bearer cog_nxcgv6nuzdvwpgla5wcqsf6dhqrvjmi63j6f6say2au72ihjlxua"
|
||||||
|
references:
|
||||||
|
- https://docs.devin.ai/api-reference/overview
|
||||||
|
- https://docs.devin.ai/api-reference/v3/self
|
||||||
|
validation:
|
||||||
|
type: Http
|
||||||
|
content:
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
url: https://api.devin.ai/v3/self
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {{ TOKEN }}"
|
||||||
|
Accept: application/json
|
||||||
|
response_matcher:
|
||||||
|
- report_response: true
|
||||||
|
- type: StatusMatch
|
||||||
|
status: [200]
|
||||||
|
- type: JsonValid
|
||||||
|
- type: WordMatch
|
||||||
|
words:
|
||||||
|
- '"principal_type"'
|
||||||
|
- '"service_user_id"'
|
||||||
|
match_all_words: false
|
||||||
|
# Revocation: DELETE /v3beta1/enterprise/service-users/{service_user_id}/api-keys/{api_key_id}
|
||||||
|
# is not implemented here because (1) it requires a separate admin service user with the
|
||||||
|
# `ManageAccountServiceUsers` permission (no self-revoke) and (2) the corresponding
|
||||||
|
# list-api-keys endpoint returns only metadata (no key value/hash), so a leaked token
|
||||||
|
# cannot be matched to its api_key_id from the token alone. Rotate via the Devin web UI.
|
||||||
|
|
@ -6,6 +6,10 @@ description: "Kingfisher release history: new features, rules, bug fixes, and im
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [v1.102.0]
|
||||||
|
- Added 3 detection and validation rules for Cognition Devin API credentials: `kingfisher.devin.1` (legacy personal keys, `apk_user_` prefix), `kingfisher.devin.2` (legacy service keys, `apk_` prefix), and `kingfisher.devin.3` (v3 service-user tokens, `cog_` prefix / RFC 4648 base32). Live validation uses `GET /v1/sessions` for `apk_*` keys and `GET /v3/self` for `cog_` tokens.
|
||||||
|
|
||||||
## [v1.101.0]
|
## [v1.101.0]
|
||||||
- Fixed asymmetric JWT validation panics by using a single `jsonwebtoken` crypto backend and adding RS256 regression coverage. Thanks @AgentEnder. [#386](https://github.com/mongodb/kingfisher/pull/386)
|
- Fixed asymmetric JWT validation panics by using a single `jsonwebtoken` crypto backend and adding RS256 regression coverage. Thanks @AgentEnder. [#386](https://github.com/mongodb/kingfisher/pull/386)
|
||||||
- Validator panics now fail that validation result instead of crashing the scan, with panic payloads kept out of cached and user-visible validation responses. Thanks @AgentEnder. [#387](https://github.com/mongodb/kingfisher/pull/387)
|
- Validator panics now fail that validation result instead of crashing the scan, with panic payloads kept out of cached and user-visible validation responses. Thanks @AgentEnder. [#387](https://github.com/mongodb/kingfisher/pull/387)
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,57 @@ kingfisher scan . --config ./kingfisher.yaml --confidence low
|
||||||
# scan.confidence: high in YAML → CLI flag wins, runs at low confidence
|
# scan.confidence: high in YAML → CLI flag wins, runs at low confidence
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Provider endpoint overrides
|
||||||
|
|
||||||
|
For self-hosted or private instances of GitHub, GitLab, Gitea, Jira, Confluence,
|
||||||
|
or Artifactory you can redirect validation and revocation requests away from the
|
||||||
|
public cloud endpoints.
|
||||||
|
|
||||||
|
**Per-run (CLI):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Single provider
|
||||||
|
kingfisher scan ./repo \
|
||||||
|
--endpoint github=https://ghe.corp.example.com \
|
||||||
|
--allow-internal-ips
|
||||||
|
|
||||||
|
# Multiple providers at once via a YAML file
|
||||||
|
kingfisher scan ./repo \
|
||||||
|
--endpoint-config ./kingfisher-endpoints.yml \
|
||||||
|
--allow-internal-ips
|
||||||
|
```
|
||||||
|
|
||||||
|
**Persisted in `kingfisher.yaml`** (under `global:`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
global:
|
||||||
|
endpoints:
|
||||||
|
- github=https://ghe.corp.example.com
|
||||||
|
- gitlab=https://gitlab.corp.example.com
|
||||||
|
endpoint_config: ./kingfisher-endpoints.yml # merged with `endpoints` list
|
||||||
|
allow_internal_ips: true # required for private/localhost URLs
|
||||||
|
```
|
||||||
|
|
||||||
|
`--endpoint-config` / `endpoint_config` points to a YAML file that maps provider
|
||||||
|
keys to base URLs:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
endpoints:
|
||||||
|
github: https://ghe.corp.example.com
|
||||||
|
gitlab: https://gitlab.corp.example.com
|
||||||
|
jira: https://jira.corp.example.com
|
||||||
|
confluence: https://confluence.corp.example.com
|
||||||
|
artifactory: http://localhost:8071
|
||||||
|
```
|
||||||
|
|
||||||
|
Supported provider keys: `github`, `gitlab`, `gitea`, `jira`, `jira-cloud`,
|
||||||
|
`confluence`, `artifactory`. For endpoints on private IPs or `localhost`,
|
||||||
|
always combine with `--allow-internal-ips` (or `global.allow_internal_ips: true`
|
||||||
|
in `kingfisher.yaml`) — Kingfisher blocks SSRF by default.
|
||||||
|
|
||||||
|
See the [GitHub Enterprise section](basic-scanning.md#scan-a-github-enterprise-self-hosted-github-instance)
|
||||||
|
in the scanning guide for end-to-end examples.
|
||||||
|
|
||||||
## Webhook URL policy
|
## Webhook URL policy
|
||||||
|
|
||||||
`alerts.webhooks[].url` (and `--alert-webhook URL`) **must use `https://`**.
|
`alerts.webhooks[].url` (and `--alert-webhook URL`) **must use `https://`**.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue