kingfisher/crates/kingfisher-rules/data/rules/github.yml
Mick Grove f22b7768e9 fix(github): address PR review feedback
- Update X-GitHub-Api-Version to 2026-03-10 for /credentials/revoke
  endpoint (the endpoint is only documented under this API version).
- Clarify sha256_b32 filter description: note that the optional `len`
  parameter may produce output that is not valid RFC 4648 Base32.
- Move base32 to [workspace.dependencies] and reference it via
  .workspace = true from both the root crate and kingfisher-rules
  to avoid version skew.
2026-04-20 08:44:41 -07:00

364 lines
11 KiB
YAML

rules:
- name: GitHub Personal Access Token - fine-grained permissions
id: kingfisher.github.1
pattern: |
(?x)
(
(?P<body>github_pat_[0-9][A-Za-z0-9]{21}_[A-Za-z0-9]{43})
(?P<checksum>[A-Za-z2-7]{8})
[A-Za-z0-9]{8}
)
\b
pattern_requirements:
min_digits: 2
min_lowercase: 2
checksum:
actual:
template: "{{ checksum }}"
requires_capture: checksum
expected: "{{ body | sha256_b32: 8 }}"
skip_if_missing: true
min_entropy: 3.5
examples:
- "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"
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: POST
url: https://api.github.com/credentials/revoke
headers:
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2026-03-10
Content-Type: application/json
body: '{"credentials":["{{ TOKEN }}"]}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [202]
- name: GitHub Personal Access Token
id: kingfisher.github.2
pattern: |
(?x)
(
ghp_(?P<body>[A-Za-z0-9]{30})(?P<checksum>[A-Za-z0-9]{6})
)
pattern_requirements:
min_digits: 2
min_lowercase: 2
checksum:
actual:
template: "{{ checksum }}"
requires_capture: checksum
expected: "{{ body | crc32 | base62: 6 }}"
skip_if_missing: true
min_entropy: 3.5
examples:
- "GITHUB_KEY=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"
- "let g:gh_token='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'"
- |
## git developer settings
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
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: POST
url: https://api.github.com/credentials/revoke
headers:
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2026-03-10
Content-Type: application/json
body: '{"credentials":["{{ TOKEN }}"]}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [202]
- name: GitHub OAuth Access Token
id: kingfisher.github.3
pattern: |
(?x)
(
gho_(?P<body>[A-Za-z0-9]{30})(?P<checksum>[A-Za-z0-9]{6})
)
pattern_requirements:
min_digits: 2
checksum:
actual:
template: "{{ checksum }}"
requires_capture: checksum
expected: "{{ body | crc32 | base62: 6 }}"
skip_if_missing: true
min_entropy: 3.5
confidence: medium
examples:
- ' "url": "git+https://FelipeMestre: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@github.com/gontarz/PW_2021_Website-FelipeMestre.git"'
- ' oauth_token: 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'
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: POST
url: https://api.github.com/credentials/revoke
headers:
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2026-03-10
Content-Type: application/json
body: '{"credentials":["{{ TOKEN }}"]}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [202]
- name: GitHub App User-to-Server Token
id: kingfisher.github.4
pattern: |
(?x)
(
ghu_(?P<body>[A-Za-z0-9]{30})(?P<checksum>[A-Za-z0-9]{6})
)
pattern_requirements:
checksum:
actual:
template: "{{ checksum }}"
requires_capture: checksum
expected: "{{ body | crc32 | base62: 6 }}"
skip_if_missing: true
examples:
- ' "token": "ghu_TIOHHEVefAwRonSMALCFfWMYK0un1R1dj2rn",'
- |
Example usage:
git clone http://ghu_imqBAXUtRirzzcJPwAiqImhkzsvzYZ1eDtPf@github.com/username/repo.git
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: POST
url: https://api.github.com/credentials/revoke
headers:
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2026-03-10
Content-Type: application/json
body: '{"credentials":["{{ TOKEN }}"]}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [202]
- name: GitHub App Server-to-Server Token
id: kingfisher.github.5
pattern: |
(?x)
(
ghs_(?P<body>[A-Za-z0-9]{30})(?P<checksum>[A-Za-z0-9]{6})
)
examples:
- ' "token": "ghs_16C7e42F292c69C2E7C10c838347Ae178B4a",'
- |
Example usage:
git clone http://ghs_RguXIkihJjwHAP6eXEYxaPNvywurTr5IOAbg@github.com/username/repo.git
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: DELETE
url: https://api.github.com/installation/token
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- type: StatusMatch
status: [204]
- name: GitHub Refresh Token
id: kingfisher.github.6
pattern: |
(?x)
(
ghr_(?P<body>[A-Za-z0-9]{70})(?P<checksum>[A-Za-z0-9]{6})
)
pattern_requirements:
checksum:
actual:
template: "{{ checksum }}"
requires_capture: checksum
expected: "{{ body | crc32 | base62: 6 }}"
skip_if_missing: true
examples:
- ' "refresh_token": "ghr_xgrrGzSbbGRL34Wp39JU9nxtN27Pr1v1He8FjE7x7wbExGGs7nfJszJDAmZuoKasxZ0KxJ1HSzgc",'
references:
- https://docs.github.com/en/rest/users?apiVersion=2022-11-28
validation:
type: Http
content:
request:
method: GET
url: https://api.github.com/user
headers:
Authorization: token {{ TOKEN }}
Accept: application/vnd.github+json
response_matcher:
- report_response: true
- match_all_words: true
type: WordMatch
words:
- '"login"'
- '"id"'
revocation:
type: Http
content:
request:
method: POST
url: https://api.github.com/credentials/revoke
headers:
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2026-03-10
Content-Type: application/json
body: '{"credentials":["{{ TOKEN }}"]}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [202]
- name: GitHub Client ID
id: kingfisher.github.7
pattern: |
(?xi)
(?:github)
.?
(?: api | app | application | client | consumer | customer )?
.?
(?: id | identifier | key )
.{0,2} \s{0,20} .{0,2} \s{0,20} .{0,2}
\b ([a-z0-9]{20}) \b
visible: false
examples:
- |
GITHUB_CLIENT_ID=ac58d6da7d7a84c039b7
GITHUB_SECRET=37d02377a3e9d849e18704c3ec883f9c5787d857
- name: GitHub Legacy Secret Key
id: kingfisher.github.8
pattern: |
(?xi)
\b
(?:github|gh)
(?:.|[\n\r]){0,4}?
(?:oauth|pat|token|key|secret|api[_-]?key|access[_-]?token)\b
(?:.|[\n\r]){0,32}?
\b
(
[a-z0-9]{40}
)
\b
depends_on_rule:
- rule_id: "kingfisher.github.5"
variable: GITHUB_CLIENT_ID
validation:
type: Http
content:
request:
method: POST
url: "https://github.com/login/oauth/access_token"
headers:
Accept: "application/json"
Content-Type: "application/json"
body: '{"client_id":"{{GITHUB_CLIENT_ID}}","client_secret":"{{TOKEN}}","code":"invalid_code"}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"error":"bad_verification_code"'
examples:
- |
GITHUB_CLIENT_ID=ac58d6da7d7a84c039b7
GITHUB_SECRET=37d02377a3e9d849e18704c3ec883f9c5787d857