diff --git a/CHANGELOG.md b/CHANGELOG.md index fe1383c00..bf8df6c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - `Credentials in .NET System.DirectoryServices.DirectoryEntry` ([#234](https://github.com/praetorian-inc/noseyparker/pull/234)) - `Credentials in .NET System.Net.NetworkCredential` ([#234](https://github.com/praetorian-inc/noseyparker/pull/234)) - `Kubernetes Bootstrap Token` ([#235](https://github.com/praetorian-inc/noseyparker/pull/235)) + - `Sensitive value in .NET configuration` ([#237](https://github.com/praetorian-inc/noseyparker/pull/237)) - Rules now contain an optional `description` string field. This is intended to be a message for human consumption that indicates (a) what was detected and (b) how an attacker might use it. diff --git a/README.md b/README.md index b1a035f04..a933b7120 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Nosey Parker is a command-line tool that finds secrets and sensitive information **Key features:** - It natively scans files, directories, and Git repository history -- It uses regular expression matching with a set of [159 patterns](crates/noseyparker/data/default/builtin/rules) chosen for high signal-to-noise based on experience and feedback from offensive security engagements +- It uses regular expression matching with a set of [160 patterns](crates/noseyparker/data/default/builtin/rules) chosen for high signal-to-noise based on experience and feedback from offensive security engagements - It deduplicates its findings, grouping matches together that share the same secret, which in practice can reduce review burden by 100x or more compared to other tools - It is fast: it can scan at hundreds of megabytes per second on a single core, and is able to scan 100GB of Linux kernel source history in less than 2 minutes on an older MacBook Pro - It scales: it has scanned inputs as large as 20TiB during security engagements diff --git a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_check_builtins-2.snap b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_check_builtins-2.snap index 83590b9f1..26008594b 100644 --- a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_check_builtins-2.snap +++ b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_check_builtins-2.snap @@ -2,4 +2,4 @@ source: crates/noseyparker-cli/tests/rules/mod.rs expression: stdout --- -159 rules and 3 rulesets: no issues detected +160 rules and 3 rulesets: no issues detected diff --git a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_json-2.snap b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_json-2.snap index d6c203c5a..51ef8f8ac 100644 --- a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_json-2.snap +++ b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_json-2.snap @@ -1289,7 +1289,7 @@ expression: stdout "name": "Credentials in .NET System.Net.NetworkCredential", "id": "np.generic.7", "pattern": "(?x)\n\\b\n(?: NetworkCredential | NETWORKCREDENTIAL | networkcredential )\n\\s* \\( \\s*\n \" ( [^\"\\n]{3,50} ) \" (?# username )\n \\s* , \\s*\n \" ( [^\"\\n]{3,50} ) \" (?# password )\n\\s* \\)\n", - "description": "A .NET `System.Net.NetworkCredential` value with hardcoded parameters was found.\nThis may allow an attack access to a resource that uses basic, digest, NTLM, or Kerberos authentication.\n", + "description": "A .NET `System.Net.NetworkCredential` value with hardcoded parameters was found. This may allow an attack access to a resource that uses basic, digest, NTLM, or Kerberos authentication.\n", "examples": [ "sender.Credentials = new NetworkCredential(\"NuGets@example.com\", \"vzihlaquknriqlht\");\n", "$webClient.Credentials = new-object System.Net.NetworkCredential(\"cidownload\", \"AP7JaG9ToerxBc6gWP5LcU2CNpb\");\n" @@ -1313,7 +1313,7 @@ expression: stdout "name": "Credentials in .NET System.DirectoryServices.DirectoryEntry", "id": "np.generic.8", "pattern": "(?x)\n\\b\n(?: DirectoryEntry | DIRECTORYENTRY | directoryentry )\n\\s* \\( \\s*\n \" ( [^\"\\n]{3,100} ) \" (?# path )\n \\s* , \\s*\n \" ( [^\"\\n]{3,50} ) \" (?# username )\n \\s* , \\s*\n \" ( [^\"\\n]{3,50} ) \" (?# password )\n (?: \\s* , \\s* [^)]{3,50} )? (?# authentication type )\n\\s* \\)\n", - "description": "A .NET `System.DirectoryServices.DirectoryEntry` value was found with hardcoded credentials.\nThis may allow an attack access to an Active Directory instance.\n", + "description": "A .NET `System.DirectoryServices.DirectoryEntry` value was found with hardcoded credentials. This may allow an attacker access to an Active Directory instance.\n", "examples": [ "$domain = New-Object DirectoryServices.DirectoryEntry(\"LDAP://10.10.10.1\",\"domain\\user\", \"secret\")\n", "new DirectoryEntry(\"LDAP://EXAMPLE.COM\",\n \"ADMNALRRHH@EXAMPLE.COM\",\n \"Rrhh1234\");\n" @@ -1329,6 +1329,30 @@ expression: stdout ] } }, + { + "id": "np.generic.9", + "structural_id": "37dadc2ef09aa6f150315ce6f9aaebdf2d8b473b", + "name": "Sensitive value in .NET configuration", + "syntax": { + "name": "Sensitive value in .NET configuration", + "id": "np.generic.9", + "pattern": "(?x)\n< \\s* add \\s+ key \\s* = \\s*\n \" (\n [^\\n\"]{0,20}\n (?: pass | Pass | PASS\n | secret | Secret | SECRET\n | user | User | USER\n | admin | Admin | ADMIN\n | token | Token | TOKEN\n )\n [^\\n\"]{0,20}\n ) \"\n\\s+\nvalue \\s* = \\s* \" ([^\\n\"]{3,100}) \" \\s* / \\s* >\n", + "description": "A possibly-sensitive value in .NET app configuration was found. This may allow an attacker a way to bypass authentication or move laterally.\n", + "examples": [ + "\n\n" + ], + "negative_examples": [], + "references": [ + "https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/application-settings-overview", + "https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/appsettings/appsettings-element-for-configuration" + ], + "categories": [ + "fuzzy", + "generic", + "secret" + ] + } + }, { "id": "np.github.1", "structural_id": "f6c4fca24a1c7f275d51d2718a1585ca6e4ae664", @@ -4009,7 +4033,7 @@ expression: stdout { "id": "default", "name": "Nosey Parker default rules", - "num_rules": 138 + "num_rules": 139 }, { "id": "np.assets", diff --git a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_noargs-2.snap b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_noargs-2.snap index 9f1687df3..0dcca123d 100644 --- a/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_noargs-2.snap +++ b/crates/noseyparker-cli/tests/rules/snapshots/test_noseyparker__rules__rules_list_noargs-2.snap @@ -56,6 +56,7 @@ expression: stdout np.generic.6 Generic Password fuzzy, generic, secret np.generic.7 Credentials in .NET System.Net.NetworkCredential fuzzy, generic, secret np.generic.8 Credentials in .NET System.DirectoryServices.DirectoryEntry fuzzy, generic, secret + np.generic.9 Sensitive value in .NET configuration fuzzy, generic, secret np.github.1 GitHub Personal Access Token api, secret np.github.2 GitHub OAuth Access Token api, secret np.github.3 GitHub App Token api, secret @@ -166,6 +167,6 @@ expression: stdout Ruleset ID Ruleset Name Rules ───────────────────────────────────────────────────────── - default Nosey Parker default rules 138 + default Nosey Parker default rules 139 np.assets Nosey Parker asset detection rules 15 np.hashes Nosey Parker password hash rules 6 diff --git a/crates/noseyparker/data/default/builtin/rules/generic.yml b/crates/noseyparker/data/default/builtin/rules/generic.yml index 061e85186..d04b8c47d 100644 --- a/crates/noseyparker/data/default/builtin/rules/generic.yml +++ b/crates/noseyparker/data/default/builtin/rules/generic.yml @@ -291,7 +291,7 @@ rules: references: - https://learn.microsoft.com/en-us/dotnet/api/system.net.networkcredential - description: | + description: > A .NET `System.Net.NetworkCredential` value with hardcoded parameters was found. This may allow an attack access to a resource that uses basic, digest, NTLM, or Kerberos authentication. @@ -326,6 +326,41 @@ rules: references: - https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry - description: | + description: > A .NET `System.DirectoryServices.DirectoryEntry` value was found with hardcoded credentials. - This may allow an attack access to an Active Directory instance. + This may allow an attacker access to an Active Directory instance. + + +- name: Sensitive value in .NET configuration + id: np.generic.9 + + pattern: | + (?x) + < \s* add \s+ key \s* = \s* + " ( + [^\n"]{0,20} + (?: pass | Pass | PASS + | secret | Secret | SECRET + | user | User | USER + | admin | Admin | ADMIN + | token | Token | TOKEN + ) + [^\n"]{0,20} + ) " + \s+ + value \s* = \s* " ([^\n"]{3,100}) " \s* / \s* > + + categories: [fuzzy, generic, secret] + + description: > + A possibly-sensitive value in .NET app configuration was found. + This may allow an attacker a way to bypass authentication or move laterally. + + examples: + - | + + + + references: + - https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/application-settings-overview + - https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/appsettings/appsettings-element-for-configuration diff --git a/crates/noseyparker/data/default/builtin/rulesets/default.yml b/crates/noseyparker/data/default/builtin/rulesets/default.yml index 1aeae92c8..cc7d72290 100644 --- a/crates/noseyparker/data/default/builtin/rulesets/default.yml +++ b/crates/noseyparker/data/default/builtin/rulesets/default.yml @@ -58,6 +58,7 @@ rulesets: - np.generic.6 # Generic Password - np.generic.7 # Credentials in .NET System.Net.NetworkCredential - np.generic.8 # Credentials in .NET System.DirectoryServices.DirectoryEntry + - np.generic.9 # Sensitive value in .NET configuration - np.github.1 # GitHub Personal Access Token - np.github.2 # GitHub OAuth Access Token - np.github.3 # GitHub App Token