forked from mirrors/kingfisher
Added checksum to GitLab rule
This commit is contained in:
parent
116aac2f83
commit
ae01a24414
5 changed files with 111 additions and 7 deletions
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [v1.67.0]
|
||||
- Added checksum to GitLab rule
|
||||
|
||||
## [v1.66.0]
|
||||
- Updating to support Bitbucket App Passwords
|
||||
- Improved boundaries for several rules
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ publish = false
|
|||
|
||||
[package]
|
||||
name = "kingfisher"
|
||||
version = "1.66.0"
|
||||
version = "1.67.0"
|
||||
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
|
|
|||
|
|
@ -120,21 +120,37 @@ rules:
|
|||
- '"403 Forbidden"'
|
||||
negative: true
|
||||
url: https://gitlab.com/api/v4/ci/pipeline_triggers/{{ TOKEN }}
|
||||
- name: GitLab Private Token - Updated Format
|
||||
- name: GitLab Private Token - Routable Format
|
||||
id: kingfisher.gitlab.4
|
||||
pattern: |
|
||||
(?x)
|
||||
(?xi)
|
||||
\b
|
||||
(
|
||||
glpat-[A-Za-z0-9_-]{36,38}\.01\.[a-z0-9]{9}
|
||||
glpat-
|
||||
(?<base64_payload>[0-9A-Za-z_-]{27,300})
|
||||
\.
|
||||
(?<version>01)
|
||||
\.
|
||||
(?<base36_payload_length>[0-9a-z]{2})
|
||||
(?<crc32>[0-9a-z]{7})
|
||||
)
|
||||
\b
|
||||
pattern_requirements:
|
||||
min_digits: 2
|
||||
# GitLab's RoutableTokenGenerator renders the CRC32 digest as lowercase
|
||||
# base36 with a fixed width of 7 characters. The regex and checksum
|
||||
# expectation mirror that encoding so we only report matches that carry a
|
||||
# valid GitLab-style checksum.
|
||||
checksum:
|
||||
actual:
|
||||
template: "{{ MATCH | suffix: 7 }}"
|
||||
requires_capture: crc32
|
||||
expected: "{{ \"glpat-\" | append: BASE64_PAYLOAD | append: \".01.\" | append: BASE36_PAYLOAD_LENGTH | crc32 | base36: 7 }}"
|
||||
skip_if_missing: true
|
||||
min_entropy: 3.5
|
||||
confidence: medium
|
||||
examples:
|
||||
- glpat-5m8CwMZi4bwlRSCKzG0-3W86MQp1OmV5Y2UK.01.1012mzo24
|
||||
- glpat-ymiBP0-I-J6ghspoBPoZxtSC3g7MyHYG0X0r.01.101erjmwl
|
||||
references:
|
||||
- https://github.com/diffblue/gitlab/blob/39c63ee83369bf5353256a6b95f3116728edd102/doc/api/personal_access_tokens.md
|
||||
- https://docs.gitlab.com/api/personal_access_tokens/
|
||||
|
|
@ -150,4 +166,4 @@ rules:
|
|||
- type: WordMatch
|
||||
words:
|
||||
- '"id"'
|
||||
url: https://gitlab.com/api/v4/personal_access_tokens/self
|
||||
url: https://gitlab.com/api/v4/personal_access_tokens/self
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ rules:
|
|||
ignore_if_contains:
|
||||
- "*****"
|
||||
- "xxxxx"
|
||||
- "username:"
|
||||
min_entropy: 4.0
|
||||
confidence: medium
|
||||
confidence: low
|
||||
examples:
|
||||
- https://username:secret@example.com/path
|
||||
validation:
|
||||
|
|
|
|||
|
|
@ -728,6 +728,83 @@ fn value_to_usize(value: &Value) -> Option<usize> {
|
|||
.or_else(|| view.to_kstr().parse::<usize>().ok())
|
||||
}
|
||||
|
||||
#[derive(Debug, FilterParameters)]
|
||||
struct Base36Args {
|
||||
#[parameter(
|
||||
description = "Pad the encoded value to at least this width",
|
||||
arg_type = "integer"
|
||||
)]
|
||||
width: Option<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Clone, ParseFilter, FilterReflection, Default)]
|
||||
#[filter(
|
||||
name = "base36",
|
||||
description = "Encode the provided integer value using Base36.",
|
||||
parameters(Base36Args),
|
||||
parsed(Base36)
|
||||
)]
|
||||
pub struct Base36Filter;
|
||||
|
||||
#[derive(Debug, FromFilterParameters, Display_filter)]
|
||||
#[name = "base36"]
|
||||
struct Base36 {
|
||||
#[parameters]
|
||||
args: Base36Args,
|
||||
}
|
||||
|
||||
impl Filter for Base36 {
|
||||
fn evaluate(&self, input: &dyn ValueView, runtime: &dyn Runtime) -> Result<Value> {
|
||||
let args = self.args.evaluate(runtime)?;
|
||||
let value = input
|
||||
.as_scalar()
|
||||
.and_then(|scalar| {
|
||||
if let Some(int) = scalar.to_integer() {
|
||||
Some(if int < 0 { 0 } else { int as u64 })
|
||||
} else if let Some(float) = scalar.to_float() {
|
||||
Some(if float.is_sign_negative() { 0 } else { float.floor() as u64 })
|
||||
} else if let Some(boolean) = scalar.to_bool() {
|
||||
Some(u64::from(boolean))
|
||||
} else {
|
||||
scalar.to_kstr().to_string().parse::<u64>().ok()
|
||||
}
|
||||
})
|
||||
.or_else(|| input.to_kstr().to_string().parse::<u64>().ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
let mut encoded = encode_base36(value);
|
||||
if let Some(width) = args.width.and_then(|value| {
|
||||
let scalar = Value::scalar(value);
|
||||
value_to_usize(&scalar)
|
||||
}) {
|
||||
if encoded.len() < width {
|
||||
let mut padded = String::with_capacity(width);
|
||||
for _ in 0..(width - encoded.len()) {
|
||||
padded.push('0');
|
||||
}
|
||||
padded.push_str(&encoded);
|
||||
encoded = padded;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::scalar(encoded))
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_base36(mut value: u64) -> String {
|
||||
const ALPHABET: &[u8; 36] = b"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
if value == 0 {
|
||||
return "0".to_string();
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
while value > 0 {
|
||||
let rem = (value % 36) as usize;
|
||||
buf.push(ALPHABET[rem] as char);
|
||||
value /= 36;
|
||||
}
|
||||
buf.iter().rev().collect()
|
||||
}
|
||||
|
||||
// {{ value | b64url_enc }} – URL-safe base64 w/o padding
|
||||
static_filter!(
|
||||
/// Base64 URL-safe (no ‘=’ padding).
|
||||
|
|
@ -844,6 +921,7 @@ pub fn register_all(builder: liquid::ParserBuilder) -> liquid::ParserBuilder {
|
|||
.filter(Crc32HexFilter::default())
|
||||
.filter(Crc32LeB64Filter::default())
|
||||
.filter(Base62Filter::default())
|
||||
.filter(Base36Filter::default())
|
||||
.filter(HmacSha256::default())
|
||||
.filter(HmacSha1::default())
|
||||
.filter(HmacSha384::default())
|
||||
|
|
@ -911,6 +989,12 @@ mod tests {
|
|||
assert_eq!(render(r#"{{ "hello" | crc32 | base62: 6 }}"#), "0zNvy2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base36_filter() {
|
||||
assert_eq!(render(r#"{{ 123456 | base36 }}"#), "2n9c");
|
||||
assert_eq!(render(r#"{{ 123456 | base36: 6 }}"#), "002n9c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crc32_dec_filter() {
|
||||
assert_eq!(render(r#"{{ "hello" | crc32_dec }}"#), "907060870");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue