Skip to content

Commit 132d9df

Browse files
authoredNov 19, 2024··
feat(secret): Add built-in secrets rules for Private Packagist (#7826)
1 parent afd7216 commit 132d9df

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed
 

‎pkg/fanal/secret/builtin-rules.go

+10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ var (
5959
CategoryNewRelic = types.SecretRuleCategory("NewRelic")
6060
CategoryNpm = types.SecretRuleCategory("Npm")
6161
CategoryPlanetscale = types.SecretRuleCategory("Planetscale")
62+
CategoryPrivatePackagist = types.SecretRuleCategory("Private Packagist")
6263
CategoryPostman = types.SecretRuleCategory("Postman")
6364
CategoryPulumi = types.SecretRuleCategory("Pulumi")
6465
CategoryRubyGems = types.SecretRuleCategory("RubyGems")
@@ -743,6 +744,15 @@ var builtinRules = []Rule{
743744
Regex: MustCompile(`pscale_tkn_(?i)[a-z0-9\-_\.]{43}`),
744745
Keywords: []string{"pscale_tkn_"},
745746
},
747+
{
748+
ID: "private-packagist-token",
749+
Category: CategoryPrivatePackagist,
750+
Title: "Private Packagist token",
751+
Severity: "HIGH",
752+
// https://packagist.com/docs/composer-authentication#token-format
753+
Regex: MustCompile(`packagist_[ou][ru]t_(?i)[a-f0-9]{68}`),
754+
Keywords: []string{"packagist_uut_", "packagist_ort_", "packagist_out_"},
755+
},
746756
{
747757
ID: "postman-api-token",
748758
Category: CategoryPostman,

‎pkg/fanal/secret/scanner_test.go

+124
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,117 @@ func TestSecretScanner(t *testing.T) {
668668
},
669669
},
670670
}
671+
wantFindingPrivatePackagistOrgReadToken := types.SecretFinding{
672+
RuleID: "private-packagist-token",
673+
Category: secret.CategoryPrivatePackagist,
674+
Title: "Private Packagist token",
675+
Severity: "HIGH",
676+
StartLine: 1,
677+
EndLine: 1,
678+
Match: "ORG_READ_TOKEN=**********************************************************************************",
679+
Code: types.Code{
680+
Lines: []types.Line{
681+
{
682+
Number: 1,
683+
Content: "ORG_READ_TOKEN=**********************************************************************************",
684+
Highlighted: "ORG_READ_TOKEN=**********************************************************************************",
685+
IsCause: true,
686+
FirstCause: true,
687+
LastCause: true,
688+
},
689+
{
690+
Number: 2,
691+
Content: "ORG_WRITE_TOKEN=**********************************************************************************",
692+
Highlighted: "ORG_WRITE_TOKEN=**********************************************************************************",
693+
IsCause: false,
694+
FirstCause: false,
695+
LastCause: false,
696+
},
697+
},
698+
},
699+
}
700+
wantFindingPrivatePackagistOrgUpdateToken := types.SecretFinding{
701+
RuleID: "private-packagist-token",
702+
Category: secret.CategoryPrivatePackagist,
703+
Title: "Private Packagist token",
704+
Severity: "HIGH",
705+
StartLine: 2,
706+
EndLine: 2,
707+
Match: "ORG_WRITE_TOKEN=**********************************************************************************",
708+
Code: types.Code{
709+
Lines: []types.Line{
710+
{
711+
Number: 1,
712+
Content: "ORG_READ_TOKEN=**********************************************************************************",
713+
Highlighted: "ORG_READ_TOKEN=**********************************************************************************",
714+
IsCause: false,
715+
FirstCause: false,
716+
LastCause: false,
717+
},
718+
{
719+
Number: 2,
720+
Content: "ORG_WRITE_TOKEN=**********************************************************************************",
721+
Highlighted: "ORG_WRITE_TOKEN=**********************************************************************************",
722+
IsCause: true,
723+
FirstCause: true,
724+
LastCause: true,
725+
},
726+
{
727+
Number: 3,
728+
Content: "USER_TOKEN=**********************************************************************************",
729+
Highlighted: "USER_TOKEN=**********************************************************************************",
730+
IsCause: false,
731+
FirstCause: false,
732+
LastCause: false,
733+
},
734+
},
735+
},
736+
}
737+
wantFindingPrivatePackagistUserToken := types.SecretFinding{
738+
RuleID: "private-packagist-token",
739+
Category: secret.CategoryPrivatePackagist,
740+
Title: "Private Packagist token",
741+
Severity: "HIGH",
742+
StartLine: 3,
743+
EndLine: 3,
744+
Match: "USER_TOKEN=**********************************************************************************",
745+
Code: types.Code{
746+
Lines: []types.Line{
747+
{
748+
Number: 1,
749+
Content: "ORG_READ_TOKEN=**********************************************************************************",
750+
Highlighted: "ORG_READ_TOKEN=**********************************************************************************",
751+
IsCause: false,
752+
FirstCause: false,
753+
LastCause: false,
754+
},
755+
{
756+
Number: 2,
757+
Content: "ORG_WRITE_TOKEN=**********************************************************************************",
758+
Highlighted: "ORG_WRITE_TOKEN=**********************************************************************************",
759+
IsCause: false,
760+
FirstCause: false,
761+
LastCause: false,
762+
},
763+
{
764+
Number: 3,
765+
Content: "USER_TOKEN=**********************************************************************************",
766+
Highlighted: "USER_TOKEN=**********************************************************************************",
767+
IsCause: true,
768+
FirstCause: true,
769+
LastCause: true,
770+
},
771+
{
772+
Number: 4,
773+
Content: "",
774+
Highlighted: "",
775+
IsCause: false,
776+
FirstCause: false,
777+
LastCause: false,
778+
},
779+
},
780+
},
781+
}
671782
wantFindingHuggingFace := types.SecretFinding{
672783
RuleID: "hugging-face-access-token",
673784
Category: secret.CategoryHuggingFace,
@@ -941,6 +1052,19 @@ func TestSecretScanner(t *testing.T) {
9411052
Findings: []types.SecretFinding{wantFindingJWT},
9421053
},
9431054
},
1055+
{
1056+
name: "find Private Packagist tokens",
1057+
configPath: filepath.Join("testdata", "config.yaml"),
1058+
inputFilePath: filepath.Join("testdata", "private-packagist.txt"),
1059+
want: types.Secret{
1060+
FilePath: filepath.Join("testdata", "private-packagist.txt"),
1061+
Findings: []types.SecretFinding{
1062+
wantFindingPrivatePackagistOrgReadToken,
1063+
wantFindingPrivatePackagistOrgUpdateToken,
1064+
wantFindingPrivatePackagistUserToken,
1065+
},
1066+
},
1067+
},
9441068
{
9451069
name: "include when keyword found",
9461070
configPath: filepath.Join("testdata", "config-happy-keywords.yaml"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ORG_READ_TOKEN=packagist_ort_6675e11a686c692f3f2e3b6ce528c3d122d22d912ea69a20713cdf51714ba710ad74
2+
ORG_WRITE_TOKEN=packagist_out_d63BD7be741c67ca810f924225b525fa5d20e6e1b316c8bfc0a1b33c68e4861bd5a4
3+
USER_TOKEN=packagist_uut_02f17e5917451dcdcc2995157e08cac2976a0373097b95d7021ba7a6844437973421

0 commit comments

Comments
 (0)
Please sign in to comment.