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
|
||||
docs-site/site/
|
||||
|
||||
.codegraph/
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/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.
|
||||
|
||||
## [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]
|
||||
- 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)
|
||||
|
|
|
|||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4958,7 +4958,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "kingfisher"
|
||||
version = "1.101.0"
|
||||
version = "1.102.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"asar",
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ http = "1.4"
|
|||
|
||||
[package]
|
||||
name = "kingfisher"
|
||||
version = "1.101.0"
|
||||
version = "1.102.0"
|
||||
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
||||
edition.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
|
||||
|
||||
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]
|
||||
- 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)
|
||||
|
|
|
|||
|
|
@ -97,6 +97,57 @@ kingfisher scan . --config ./kingfisher.yaml --confidence low
|
|||
# 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
|
||||
|
||||
`alerts.webhooks[].url` (and `--alert-webhook URL`) **must use `https://`**.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue