mobbdev 0.0.163 → 0.0.165
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +2 -2
- package/dist/index.mjs +2620 -444
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -32,58 +32,82 @@ import fs4 from "node:fs";
|
|
|
32
32
|
import path7 from "node:path";
|
|
33
33
|
|
|
34
34
|
// src/constants.ts
|
|
35
|
-
import
|
|
35
|
+
import path from "node:path";
|
|
36
36
|
import { fileURLToPath } from "node:url";
|
|
37
37
|
import chalk from "chalk";
|
|
38
38
|
import Debug from "debug";
|
|
39
39
|
import * as dotenv from "dotenv";
|
|
40
|
-
import { z as
|
|
40
|
+
import { z as z2 } from "zod";
|
|
41
41
|
|
|
42
42
|
// src/features/analysis/scm/shared/src/types.ts
|
|
43
|
-
var scmCloudUrl = {
|
|
44
|
-
GitLab: "https://gitlab.com",
|
|
45
|
-
GitHub: "https://github.com",
|
|
46
|
-
Ado: "https://dev.azure.com",
|
|
47
|
-
Bitbucket: "https://bitbucket.org"
|
|
48
|
-
};
|
|
49
|
-
var ScmType = /* @__PURE__ */ ((ScmType2) => {
|
|
50
|
-
ScmType2["GitHub"] = "GitHub";
|
|
51
|
-
ScmType2["GitLab"] = "GitLab";
|
|
52
|
-
ScmType2["Ado"] = "Ado";
|
|
53
|
-
ScmType2["Bitbucket"] = "Bitbucket";
|
|
54
|
-
return ScmType2;
|
|
55
|
-
})(ScmType || {});
|
|
56
|
-
|
|
57
|
-
// src/features/analysis/scm/ado/constants.ts
|
|
58
|
-
var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
59
|
-
|
|
60
|
-
// src/features/analysis/scm/ado/utils.ts
|
|
61
|
-
import querystring3 from "node:querystring";
|
|
62
|
-
import * as api from "azure-devops-node-api";
|
|
63
|
-
import { z as z10 } from "zod";
|
|
64
|
-
|
|
65
|
-
// src/features/analysis/scm/env.ts
|
|
66
43
|
import { z } from "zod";
|
|
67
|
-
var EnvVariablesZod = z.object({
|
|
68
|
-
GITLAB_API_TOKEN: z.string().optional(),
|
|
69
|
-
GITHUB_API_TOKEN: z.string().optional(),
|
|
70
|
-
GIT_PROXY_HOST: z.string()
|
|
71
|
-
});
|
|
72
|
-
var { GITLAB_API_TOKEN, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
|
|
73
|
-
|
|
74
|
-
// src/features/analysis/scm/scm.ts
|
|
75
|
-
import { z as z8 } from "zod";
|
|
76
|
-
|
|
77
|
-
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
78
|
-
import querystring from "node:querystring";
|
|
79
|
-
import bitbucketPkg from "bitbucket";
|
|
80
|
-
import * as bitbucketPkgNode from "bitbucket";
|
|
81
|
-
import { z as z4 } from "zod";
|
|
82
|
-
|
|
83
|
-
// src/features/analysis/scm/shared/src/get_issue_type.ts
|
|
84
|
-
import { z as z2 } from "zod";
|
|
85
44
|
|
|
86
45
|
// src/features/analysis/scm/generates/client_generates.ts
|
|
46
|
+
var FixQuestionInputType = /* @__PURE__ */ ((FixQuestionInputType2) => {
|
|
47
|
+
FixQuestionInputType2["Number"] = "NUMBER";
|
|
48
|
+
FixQuestionInputType2["Select"] = "SELECT";
|
|
49
|
+
FixQuestionInputType2["Text"] = "TEXT";
|
|
50
|
+
return FixQuestionInputType2;
|
|
51
|
+
})(FixQuestionInputType || {});
|
|
52
|
+
var Language = /* @__PURE__ */ ((Language2) => {
|
|
53
|
+
Language2["Cpp"] = "CPP";
|
|
54
|
+
Language2["Csharp"] = "CSHARP";
|
|
55
|
+
Language2["Java"] = "JAVA";
|
|
56
|
+
Language2["Js"] = "JS";
|
|
57
|
+
Language2["Python"] = "PYTHON";
|
|
58
|
+
Language2["Sql"] = "SQL";
|
|
59
|
+
Language2["Xml"] = "XML";
|
|
60
|
+
return Language2;
|
|
61
|
+
})(Language || {});
|
|
62
|
+
var ManifestAction = /* @__PURE__ */ ((ManifestAction2) => {
|
|
63
|
+
ManifestAction2["Add"] = "add";
|
|
64
|
+
ManifestAction2["Relock"] = "relock";
|
|
65
|
+
ManifestAction2["Upgrade"] = "upgrade";
|
|
66
|
+
return ManifestAction2;
|
|
67
|
+
})(ManifestAction || {});
|
|
68
|
+
var Effort_To_Apply_Fix_Enum = /* @__PURE__ */ ((Effort_To_Apply_Fix_Enum2) => {
|
|
69
|
+
Effort_To_Apply_Fix_Enum2["Easy"] = "EASY";
|
|
70
|
+
Effort_To_Apply_Fix_Enum2["Hard"] = "HARD";
|
|
71
|
+
Effort_To_Apply_Fix_Enum2["Moderate"] = "MODERATE";
|
|
72
|
+
return Effort_To_Apply_Fix_Enum2;
|
|
73
|
+
})(Effort_To_Apply_Fix_Enum || {});
|
|
74
|
+
var Fix_Rating_Tag_Enum = /* @__PURE__ */ ((Fix_Rating_Tag_Enum2) => {
|
|
75
|
+
Fix_Rating_Tag_Enum2["BadPattern"] = "BAD_PATTERN";
|
|
76
|
+
Fix_Rating_Tag_Enum2["BreakingFix"] = "BREAKING_FIX";
|
|
77
|
+
Fix_Rating_Tag_Enum2["FalsePositive"] = "FALSE_POSITIVE";
|
|
78
|
+
Fix_Rating_Tag_Enum2["Other"] = "OTHER";
|
|
79
|
+
Fix_Rating_Tag_Enum2["UnresolvedFix"] = "UNRESOLVED_FIX";
|
|
80
|
+
return Fix_Rating_Tag_Enum2;
|
|
81
|
+
})(Fix_Rating_Tag_Enum || {});
|
|
82
|
+
var Fix_Report_State_Enum = /* @__PURE__ */ ((Fix_Report_State_Enum2) => {
|
|
83
|
+
Fix_Report_State_Enum2["Created"] = "Created";
|
|
84
|
+
Fix_Report_State_Enum2["Deleted"] = "Deleted";
|
|
85
|
+
Fix_Report_State_Enum2["Digested"] = "Digested";
|
|
86
|
+
Fix_Report_State_Enum2["Expired"] = "Expired";
|
|
87
|
+
Fix_Report_State_Enum2["Failed"] = "Failed";
|
|
88
|
+
Fix_Report_State_Enum2["Finished"] = "Finished";
|
|
89
|
+
Fix_Report_State_Enum2["Initialized"] = "Initialized";
|
|
90
|
+
Fix_Report_State_Enum2["Requested"] = "Requested";
|
|
91
|
+
return Fix_Report_State_Enum2;
|
|
92
|
+
})(Fix_Report_State_Enum || {});
|
|
93
|
+
var Fix_State_Enum = /* @__PURE__ */ ((Fix_State_Enum2) => {
|
|
94
|
+
Fix_State_Enum2["Committed"] = "Committed";
|
|
95
|
+
Fix_State_Enum2["Done"] = "Done";
|
|
96
|
+
Fix_State_Enum2["Downloaded"] = "Downloaded";
|
|
97
|
+
Fix_State_Enum2["Merged"] = "Merged";
|
|
98
|
+
Fix_State_Enum2["Ready"] = "Ready";
|
|
99
|
+
return Fix_State_Enum2;
|
|
100
|
+
})(Fix_State_Enum || {});
|
|
101
|
+
var IssueLanguage_Enum = /* @__PURE__ */ ((IssueLanguage_Enum3) => {
|
|
102
|
+
IssueLanguage_Enum3["CSharp"] = "CSharp";
|
|
103
|
+
IssueLanguage_Enum3["Cpp"] = "Cpp";
|
|
104
|
+
IssueLanguage_Enum3["Java"] = "Java";
|
|
105
|
+
IssueLanguage_Enum3["JavaScript"] = "JavaScript";
|
|
106
|
+
IssueLanguage_Enum3["Python"] = "Python";
|
|
107
|
+
IssueLanguage_Enum3["Sql"] = "SQL";
|
|
108
|
+
IssueLanguage_Enum3["Xml"] = "XML";
|
|
109
|
+
return IssueLanguage_Enum3;
|
|
110
|
+
})(IssueLanguage_Enum || {});
|
|
87
111
|
var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
88
112
|
IssueType_Enum2["AutoEscapeFalse"] = "AUTO_ESCAPE_FALSE";
|
|
89
113
|
IssueType_Enum2["CmDi"] = "CMDi";
|
|
@@ -158,6 +182,28 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
158
182
|
IssueType_Enum2["ZipSlip"] = "ZIP_SLIP";
|
|
159
183
|
return IssueType_Enum2;
|
|
160
184
|
})(IssueType_Enum || {});
|
|
185
|
+
var Project_Role_Type_Enum = /* @__PURE__ */ ((Project_Role_Type_Enum2) => {
|
|
186
|
+
Project_Role_Type_Enum2["Admin"] = "admin";
|
|
187
|
+
Project_Role_Type_Enum2["Read"] = "read";
|
|
188
|
+
Project_Role_Type_Enum2["Writer"] = "writer";
|
|
189
|
+
return Project_Role_Type_Enum2;
|
|
190
|
+
})(Project_Role_Type_Enum || {});
|
|
191
|
+
var Vulnerability_Report_Vendor_Enum = /* @__PURE__ */ ((Vulnerability_Report_Vendor_Enum3) => {
|
|
192
|
+
Vulnerability_Report_Vendor_Enum3["Checkmarx"] = "checkmarx";
|
|
193
|
+
Vulnerability_Report_Vendor_Enum3["CheckmarxXml"] = "checkmarxXml";
|
|
194
|
+
Vulnerability_Report_Vendor_Enum3["Codeql"] = "codeql";
|
|
195
|
+
Vulnerability_Report_Vendor_Enum3["Fortify"] = "fortify";
|
|
196
|
+
Vulnerability_Report_Vendor_Enum3["Snyk"] = "snyk";
|
|
197
|
+
Vulnerability_Report_Vendor_Enum3["Sonarqube"] = "sonarqube";
|
|
198
|
+
return Vulnerability_Report_Vendor_Enum3;
|
|
199
|
+
})(Vulnerability_Report_Vendor_Enum || {});
|
|
200
|
+
var Vulnerability_Severity_Enum = /* @__PURE__ */ ((Vulnerability_Severity_Enum2) => {
|
|
201
|
+
Vulnerability_Severity_Enum2["Critical"] = "critical";
|
|
202
|
+
Vulnerability_Severity_Enum2["High"] = "high";
|
|
203
|
+
Vulnerability_Severity_Enum2["Low"] = "low";
|
|
204
|
+
Vulnerability_Severity_Enum2["Medium"] = "medium";
|
|
205
|
+
return Vulnerability_Severity_Enum2;
|
|
206
|
+
})(Vulnerability_Severity_Enum || {});
|
|
161
207
|
var MeDocument = `
|
|
162
208
|
query Me {
|
|
163
209
|
me {
|
|
@@ -264,10 +310,49 @@ var GetFixesDocument = `
|
|
|
264
310
|
fixes: fix(where: $filters) {
|
|
265
311
|
issueType
|
|
266
312
|
id
|
|
313
|
+
vulnerabilitySeverity
|
|
314
|
+
issueLanguage
|
|
267
315
|
patchAndQuestions {
|
|
268
316
|
__typename
|
|
269
317
|
... on FixData {
|
|
270
318
|
patch
|
|
319
|
+
questions {
|
|
320
|
+
defaultValue
|
|
321
|
+
extraContext {
|
|
322
|
+
key
|
|
323
|
+
value
|
|
324
|
+
}
|
|
325
|
+
index
|
|
326
|
+
inputType
|
|
327
|
+
key
|
|
328
|
+
name
|
|
329
|
+
options
|
|
330
|
+
value
|
|
331
|
+
__typename
|
|
332
|
+
}
|
|
333
|
+
extraContext {
|
|
334
|
+
extraContext {
|
|
335
|
+
key
|
|
336
|
+
value
|
|
337
|
+
__typename
|
|
338
|
+
}
|
|
339
|
+
fixDescription
|
|
340
|
+
manifestActionsRequired {
|
|
341
|
+
action
|
|
342
|
+
lib {
|
|
343
|
+
name
|
|
344
|
+
version
|
|
345
|
+
}
|
|
346
|
+
language
|
|
347
|
+
typesLib {
|
|
348
|
+
envName
|
|
349
|
+
name
|
|
350
|
+
version
|
|
351
|
+
}
|
|
352
|
+
__typename
|
|
353
|
+
}
|
|
354
|
+
__typename
|
|
355
|
+
}
|
|
271
356
|
}
|
|
272
357
|
}
|
|
273
358
|
}
|
|
@@ -416,6 +501,10 @@ var CreateCommunityUserDocument = `
|
|
|
416
501
|
error
|
|
417
502
|
status
|
|
418
503
|
}
|
|
504
|
+
... on UserHasNoPermissionInProjectError {
|
|
505
|
+
error
|
|
506
|
+
status
|
|
507
|
+
}
|
|
419
508
|
}
|
|
420
509
|
}
|
|
421
510
|
`;
|
|
@@ -561,91 +650,2328 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
561
650
|
};
|
|
562
651
|
}
|
|
563
652
|
|
|
564
|
-
// src/features/analysis/scm/shared/src/
|
|
565
|
-
var
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
653
|
+
// src/features/analysis/scm/shared/src/types.ts
|
|
654
|
+
var OrganizationScreenQueryParamsZ = z.object({
|
|
655
|
+
organizationId: z.string().uuid()
|
|
656
|
+
});
|
|
657
|
+
var ProjectPageQueryParamsZ = z.object({
|
|
658
|
+
organizationId: z.string().uuid(),
|
|
659
|
+
projectId: z.string().uuid()
|
|
660
|
+
});
|
|
661
|
+
var AnalysisPageQueryParamsZ = ProjectPageQueryParamsZ.extend({
|
|
662
|
+
reportId: z.string().uuid()
|
|
663
|
+
});
|
|
664
|
+
var FixPageQueryParamsZ = AnalysisPageQueryParamsZ.extend({
|
|
665
|
+
fixId: z.string().uuid()
|
|
666
|
+
});
|
|
667
|
+
var CliLoginPageQueryParamsZ = z.object({
|
|
668
|
+
loginId: z.string().uuid()
|
|
669
|
+
});
|
|
670
|
+
var ScmSubmitFixRequestsZ = z.array(
|
|
671
|
+
z.object({
|
|
672
|
+
scmSubmitFixRequest: z.object({
|
|
673
|
+
submitFixRequest: z.object({
|
|
674
|
+
createdByUser: z.object({
|
|
675
|
+
email: z.string()
|
|
676
|
+
})
|
|
677
|
+
}),
|
|
678
|
+
prUrl: z.string().nullable(),
|
|
679
|
+
scmId: z.string()
|
|
680
|
+
})
|
|
681
|
+
})
|
|
682
|
+
);
|
|
683
|
+
var AnalysisReportDigestedZ = z.object({
|
|
684
|
+
id: z.string().uuid(),
|
|
685
|
+
state: z.nativeEnum(Fix_Report_State_Enum),
|
|
686
|
+
vulnerabilityReport: z.object({
|
|
687
|
+
reportSummaryUrl: z.string().url().nullish(),
|
|
688
|
+
scanDate: z.string().nullable(),
|
|
689
|
+
supported: z.object({
|
|
690
|
+
aggregate: z.object({
|
|
691
|
+
count: z.number()
|
|
692
|
+
})
|
|
693
|
+
}),
|
|
694
|
+
all: z.object({
|
|
695
|
+
aggregate: z.object({
|
|
696
|
+
count: z.number()
|
|
697
|
+
})
|
|
698
|
+
}),
|
|
699
|
+
vendor: z.nativeEnum(Vulnerability_Report_Vendor_Enum),
|
|
700
|
+
project: z.object({
|
|
701
|
+
organizationId: z.string().uuid()
|
|
702
|
+
})
|
|
703
|
+
})
|
|
704
|
+
});
|
|
705
|
+
var FixRatingZ = z.object({
|
|
706
|
+
voteScore: z.number(),
|
|
707
|
+
fixRatingTag: z.nativeEnum(Fix_Rating_Tag_Enum).nullable().default(null),
|
|
708
|
+
comment: z.string().nullable().default(null),
|
|
709
|
+
updatedDate: z.string().nullable(),
|
|
710
|
+
user: z.object({
|
|
711
|
+
email: z.string(),
|
|
712
|
+
name: z.string()
|
|
713
|
+
})
|
|
714
|
+
});
|
|
715
|
+
var ReportQueryResultZ = z.object({
|
|
716
|
+
fixReport_by_pk: z.object({
|
|
717
|
+
id: z.string().uuid(),
|
|
718
|
+
fixesCommitted: z.object({
|
|
719
|
+
aggregate: z.object({ count: z.number() })
|
|
720
|
+
}),
|
|
721
|
+
fixesDownloaded: z.object({
|
|
722
|
+
aggregate: z.object({ count: z.number() })
|
|
723
|
+
}),
|
|
724
|
+
fixesReadyCount: z.number(),
|
|
725
|
+
issueTypes: z.record(z.string(), z.number()).nullable(),
|
|
726
|
+
issueLanguages: z.record(z.string(), z.number()).nullable(),
|
|
727
|
+
fixesCountByEffort: z.record(z.string(), z.number()).nullable(),
|
|
728
|
+
vulnerabilitySeverities: z.record(z.string(), z.number()).nullable(),
|
|
729
|
+
createdOn: z.string(),
|
|
730
|
+
expirationOn: z.string().nullable(),
|
|
731
|
+
state: z.nativeEnum(Fix_Report_State_Enum),
|
|
732
|
+
fixes_aggregate: z.object({
|
|
733
|
+
aggregate: z.object({
|
|
734
|
+
count: z.number()
|
|
735
|
+
})
|
|
736
|
+
}),
|
|
737
|
+
fixes: z.array(
|
|
738
|
+
z.object({
|
|
739
|
+
id: z.string().uuid(),
|
|
740
|
+
issueLanguage: z.nativeEnum(IssueLanguage_Enum).nullable(),
|
|
741
|
+
issueType: z.nativeEnum(IssueType_Enum).nullable(),
|
|
742
|
+
confidence: z.number(),
|
|
743
|
+
effortToApplyFix: z.nativeEnum(Effort_To_Apply_Fix_Enum).nullable(),
|
|
744
|
+
modifiedBy: z.string().nullable(),
|
|
745
|
+
gitBlameLogin: z.string().nullable(),
|
|
746
|
+
fixReportId: z.string().uuid(),
|
|
747
|
+
vulnerabilitySeverity: z.nativeEnum(Vulnerability_Severity_Enum).nullable().transform((i) => i ?? "low" /* Low */),
|
|
748
|
+
filePaths: z.array(
|
|
749
|
+
z.object({
|
|
750
|
+
fileRepoRelativePath: z.string()
|
|
751
|
+
})
|
|
752
|
+
),
|
|
753
|
+
state: z.nativeEnum(Fix_State_Enum),
|
|
754
|
+
numberOfVulnerabilityIssues: z.number(),
|
|
755
|
+
vulnerabilityReportIssues: z.array(
|
|
756
|
+
z.object({
|
|
757
|
+
issueType: z.string(),
|
|
758
|
+
issueLanguage: z.string()
|
|
759
|
+
})
|
|
760
|
+
),
|
|
761
|
+
scmSubmitFixRequests: ScmSubmitFixRequestsZ,
|
|
762
|
+
isArchived: z.boolean().nullable(),
|
|
763
|
+
fixRatings: z.array(FixRatingZ).default([])
|
|
764
|
+
})
|
|
765
|
+
),
|
|
766
|
+
repo: z.object({
|
|
767
|
+
name: z.string().nullable(),
|
|
768
|
+
originalUrl: z.string(),
|
|
769
|
+
reference: z.string(),
|
|
770
|
+
commitSha: z.string(),
|
|
771
|
+
isKnownBranch: z.boolean().nullish().default(true)
|
|
772
|
+
}),
|
|
773
|
+
vulnerabilityReport: z.object({
|
|
774
|
+
reportSummaryUrl: z.string().url().nullish(),
|
|
775
|
+
vendor: z.nativeEnum(Vulnerability_Report_Vendor_Enum).nullable(),
|
|
776
|
+
issuesWithKnownLanguage: z.number().nullable(),
|
|
777
|
+
scanDate: z.string().nullable(),
|
|
778
|
+
vendorReportId: z.string().uuid().nullable(),
|
|
779
|
+
projectId: z.string().uuid(),
|
|
780
|
+
project: z.object({
|
|
781
|
+
organizationId: z.string().uuid()
|
|
782
|
+
}),
|
|
783
|
+
file: z.object({
|
|
784
|
+
id: z.string().uuid(),
|
|
785
|
+
path: z.string()
|
|
786
|
+
}),
|
|
787
|
+
pending: z.object({
|
|
788
|
+
aggregate: z.object({
|
|
789
|
+
count: z.number()
|
|
790
|
+
})
|
|
791
|
+
}),
|
|
792
|
+
supported: z.object({
|
|
793
|
+
aggregate: z.object({
|
|
794
|
+
count: z.number()
|
|
795
|
+
})
|
|
796
|
+
}),
|
|
797
|
+
digested: z.object({
|
|
798
|
+
aggregate: z.object({
|
|
799
|
+
count: z.number()
|
|
800
|
+
})
|
|
801
|
+
}),
|
|
802
|
+
all: z.object({
|
|
803
|
+
aggregate: z.object({
|
|
804
|
+
count: z.number()
|
|
805
|
+
})
|
|
806
|
+
}),
|
|
807
|
+
fixable: z.object({
|
|
808
|
+
aggregate: z.object({
|
|
809
|
+
count: z.number()
|
|
810
|
+
})
|
|
811
|
+
}),
|
|
812
|
+
errors: z.object({
|
|
813
|
+
aggregate: z.object({
|
|
814
|
+
count: z.number()
|
|
815
|
+
})
|
|
816
|
+
}),
|
|
817
|
+
vulnerabilityReportIssues: z.object({
|
|
818
|
+
extraData: z.object({
|
|
819
|
+
missing_files: z.string().array().nullish(),
|
|
820
|
+
large_files: z.string().array().nullish(),
|
|
821
|
+
error_files: z.string().array().nullish()
|
|
822
|
+
})
|
|
823
|
+
}).array()
|
|
824
|
+
})
|
|
825
|
+
})
|
|
826
|
+
});
|
|
827
|
+
var ReportFixesQueryZ = z.array(
|
|
828
|
+
z.object({
|
|
829
|
+
id: z.string().uuid(),
|
|
830
|
+
state: z.nativeEnum(Fix_State_Enum),
|
|
831
|
+
isArchived: z.boolean().nullable(),
|
|
832
|
+
confidence: z.number(),
|
|
833
|
+
gitBlameLogin: z.string().nullable(),
|
|
834
|
+
effortToApplyFix: z.nativeEnum(Effort_To_Apply_Fix_Enum).nullable(),
|
|
835
|
+
issueLanguage: z.nativeEnum(IssueLanguage_Enum).nullable(),
|
|
836
|
+
issueType: z.nativeEnum(IssueType_Enum).nullable(),
|
|
837
|
+
vulnerabilitySeverity: z.nativeEnum(Vulnerability_Severity_Enum).nullable().transform((i) => i ?? "low" /* Low */),
|
|
838
|
+
fixReportId: z.string().uuid(),
|
|
839
|
+
filePaths: z.array(
|
|
840
|
+
z.object({
|
|
841
|
+
fileRepoRelativePath: z.string()
|
|
842
|
+
})
|
|
843
|
+
),
|
|
844
|
+
numberOfVulnerabilityIssues: z.number(),
|
|
845
|
+
vulnerabilityReportIssues: z.array(
|
|
846
|
+
z.object({
|
|
847
|
+
issueType: z.string(),
|
|
848
|
+
issueLanguage: z.string()
|
|
849
|
+
})
|
|
850
|
+
),
|
|
851
|
+
scmSubmitFixRequests: ScmSubmitFixRequestsZ,
|
|
852
|
+
fixRatings: z.array(FixRatingZ).default([])
|
|
853
|
+
})
|
|
854
|
+
);
|
|
855
|
+
var ExtraContextInternalZ = z.object({
|
|
856
|
+
key: z.string(),
|
|
857
|
+
value: z.string().or(z.boolean()).or(
|
|
858
|
+
z.object({
|
|
859
|
+
int: z.boolean(),
|
|
860
|
+
integer: z.boolean(),
|
|
861
|
+
string: z.boolean(),
|
|
862
|
+
date: z.boolean()
|
|
863
|
+
})
|
|
864
|
+
)
|
|
865
|
+
});
|
|
866
|
+
var PackageInfoZ = z.object({
|
|
867
|
+
name: z.string(),
|
|
868
|
+
version: z.string(),
|
|
869
|
+
envName: z.string().nullable()
|
|
870
|
+
});
|
|
871
|
+
var ManifestActionRequiredZ = z.object({
|
|
872
|
+
action: z.nativeEnum(ManifestAction),
|
|
873
|
+
language: z.nativeEnum(Language),
|
|
874
|
+
lib: PackageInfoZ,
|
|
875
|
+
typesLib: PackageInfoZ.nullable()
|
|
876
|
+
});
|
|
877
|
+
var FixExtraContextZ = z.object({
|
|
878
|
+
fixDescription: z.string(),
|
|
879
|
+
manifestActionsRequired: z.array(ManifestActionRequiredZ),
|
|
880
|
+
extraContext: z.array(ExtraContextInternalZ)
|
|
881
|
+
});
|
|
882
|
+
var PatchAndQuestionsZ = z.object({
|
|
883
|
+
__typename: z.literal("FixData"),
|
|
884
|
+
patch: z.string(),
|
|
885
|
+
questions: z.array(
|
|
886
|
+
z.object({
|
|
887
|
+
name: z.string(),
|
|
888
|
+
key: z.string(),
|
|
889
|
+
index: z.number(),
|
|
890
|
+
defaultValue: z.string(),
|
|
891
|
+
value: z.string().nullable(),
|
|
892
|
+
extraContext: z.array(ExtraContextInternalZ),
|
|
893
|
+
inputType: z.nativeEnum(FixQuestionInputType),
|
|
894
|
+
options: z.array(z.string())
|
|
895
|
+
})
|
|
896
|
+
),
|
|
897
|
+
extraContext: FixExtraContextZ
|
|
898
|
+
});
|
|
899
|
+
var FixQueryZ = z.object({
|
|
900
|
+
__typename: z.literal("fix").optional(),
|
|
901
|
+
id: z.string().uuid(),
|
|
902
|
+
state: z.nativeEnum(Fix_State_Enum),
|
|
903
|
+
modifiedBy: z.string().nullable(),
|
|
904
|
+
gitBlameLogin: z.string().nullable(),
|
|
905
|
+
issueLanguage: z.nativeEnum(IssueLanguage_Enum).nullable(),
|
|
906
|
+
issueType: z.nativeEnum(IssueType_Enum).nullable(),
|
|
907
|
+
confidence: z.number(),
|
|
908
|
+
fixReportId: z.string().uuid(),
|
|
909
|
+
isExpired: z.boolean().default(false),
|
|
910
|
+
isArchived: z.boolean().nullable(),
|
|
911
|
+
// TODO: remove nullish once the data on the backend is ready
|
|
912
|
+
vulnerabilitySeverity: z.nativeEnum(Vulnerability_Severity_Enum).nullable().transform((i) => i ?? "low" /* Low */),
|
|
913
|
+
fixFiles: z.array(
|
|
914
|
+
z.object({
|
|
915
|
+
fileRepoRelativePath: z.string()
|
|
916
|
+
})
|
|
917
|
+
),
|
|
918
|
+
numberOfVulnerabilityIssues: z.number(),
|
|
919
|
+
vulnerabilityReportIssues: z.array(
|
|
920
|
+
z.object({
|
|
921
|
+
vendorIssueId: z.string(),
|
|
922
|
+
issueType: z.string(),
|
|
923
|
+
issueLanguage: z.string()
|
|
924
|
+
})
|
|
925
|
+
),
|
|
926
|
+
patchAndQuestions: PatchAndQuestionsZ,
|
|
927
|
+
scmSubmitFixRequests: ScmSubmitFixRequestsZ,
|
|
928
|
+
effortToApplyFix: z.nativeEnum(Effort_To_Apply_Fix_Enum).nullable(),
|
|
929
|
+
fixRatings: z.array(FixRatingZ).default([])
|
|
930
|
+
});
|
|
931
|
+
var FixScreenQueryResultZ = z.object({
|
|
932
|
+
fixReport_by_pk: z.object({
|
|
933
|
+
id: z.string().uuid(),
|
|
934
|
+
expirationOn: z.string(),
|
|
935
|
+
createdOn: z.string(),
|
|
936
|
+
state: z.nativeEnum(Fix_Report_State_Enum),
|
|
937
|
+
fixes_aggregate: z.object({
|
|
938
|
+
aggregate: z.object({
|
|
939
|
+
count: z.number()
|
|
940
|
+
})
|
|
941
|
+
}),
|
|
942
|
+
repo: z.object({
|
|
943
|
+
name: z.string().nullable(),
|
|
944
|
+
originalUrl: z.string(),
|
|
945
|
+
reference: z.string(),
|
|
946
|
+
commitSha: z.string()
|
|
947
|
+
}),
|
|
948
|
+
vulnerabilityReport: z.object({
|
|
949
|
+
vendor: z.nativeEnum(Vulnerability_Report_Vendor_Enum),
|
|
950
|
+
vendorReportId: z.string().uuid().nullable(),
|
|
951
|
+
projectId: z.string().uuid(),
|
|
952
|
+
project: z.object({
|
|
953
|
+
organizationId: z.string().uuid()
|
|
954
|
+
}),
|
|
955
|
+
file: z.object({
|
|
956
|
+
id: z.string().uuid(),
|
|
957
|
+
path: z.string()
|
|
958
|
+
}),
|
|
959
|
+
pending: z.object({
|
|
960
|
+
aggregate: z.object({
|
|
961
|
+
count: z.number()
|
|
962
|
+
})
|
|
963
|
+
}),
|
|
964
|
+
supported: z.object({
|
|
965
|
+
aggregate: z.object({
|
|
966
|
+
count: z.number()
|
|
967
|
+
})
|
|
968
|
+
}),
|
|
969
|
+
all: z.object({
|
|
970
|
+
aggregate: z.object({
|
|
971
|
+
count: z.number()
|
|
972
|
+
})
|
|
973
|
+
}),
|
|
974
|
+
fixable: z.object({
|
|
975
|
+
aggregate: z.object({
|
|
976
|
+
count: z.number()
|
|
977
|
+
})
|
|
978
|
+
}),
|
|
979
|
+
errors: z.object({
|
|
980
|
+
aggregate: z.object({
|
|
981
|
+
count: z.number()
|
|
982
|
+
})
|
|
983
|
+
}),
|
|
984
|
+
vulnerabilityReportIssues: z.object({
|
|
985
|
+
extraData: z.object({
|
|
986
|
+
missing_files: z.string().array().nullish(),
|
|
987
|
+
large_files: z.string().array().nullish(),
|
|
988
|
+
error_files: z.string().array().nullish()
|
|
989
|
+
})
|
|
990
|
+
}).array()
|
|
991
|
+
})
|
|
992
|
+
}),
|
|
993
|
+
fix_by_pk: FixQueryZ,
|
|
994
|
+
fixesWithSameIssueType: z.object({
|
|
995
|
+
fix: z.array(z.object({ id: z.string().uuid() }))
|
|
996
|
+
})
|
|
997
|
+
});
|
|
998
|
+
var FixReportByProjectZ = z.object({
|
|
999
|
+
project_by_pk: z.object({
|
|
1000
|
+
vulnerabilityReports: z.array(
|
|
1001
|
+
z.object({
|
|
1002
|
+
fixReport: z.object({ id: z.string().uuid() }).nullable()
|
|
1003
|
+
})
|
|
1004
|
+
)
|
|
1005
|
+
})
|
|
1006
|
+
});
|
|
1007
|
+
var FixPageQueryZ = z.object({
|
|
1008
|
+
data: FixScreenQueryResultZ
|
|
1009
|
+
});
|
|
1010
|
+
var GetReportFixesQueryZ = z.object({
|
|
1011
|
+
fixReport: z.object({
|
|
1012
|
+
fixes: ReportFixesQueryZ,
|
|
1013
|
+
vulnerabilityReport: z.object({
|
|
1014
|
+
vulnerabilityReportIssues_aggregate: z.object({
|
|
1015
|
+
aggregate: z.object({ count: z.number() })
|
|
1016
|
+
})
|
|
1017
|
+
})
|
|
1018
|
+
}).array()
|
|
1019
|
+
}).nullish();
|
|
1020
|
+
var ProjectVulnerabilityReport = z.object({
|
|
1021
|
+
id: z.string().uuid(),
|
|
1022
|
+
name: z.string().nullable(),
|
|
1023
|
+
vendor: z.nativeEnum(Vulnerability_Report_Vendor_Enum).nullable(),
|
|
1024
|
+
fixReport: z.object({
|
|
1025
|
+
id: z.string().uuid(),
|
|
1026
|
+
createdOn: z.string(),
|
|
1027
|
+
fixes_aggregate: z.object({
|
|
1028
|
+
aggregate: z.object({
|
|
1029
|
+
count: z.number()
|
|
1030
|
+
})
|
|
1031
|
+
}),
|
|
1032
|
+
issueTypes: z.record(z.string(), z.number()).nullable(),
|
|
1033
|
+
issueLanguages: z.record(z.nativeEnum(IssueLanguage_Enum), z.number()).nullable(),
|
|
1034
|
+
fixesCountByEffort: z.record(z.nativeEnum(Effort_To_Apply_Fix_Enum), z.number()).nullable(),
|
|
1035
|
+
vulnerabilitySeverities: z.record(z.nativeEnum(Vulnerability_Severity_Enum), z.number()).nullable(),
|
|
1036
|
+
fixesDoneCount: z.number(),
|
|
1037
|
+
fixesInprogressCount: z.number(),
|
|
1038
|
+
fixesReadyCount: z.number(),
|
|
1039
|
+
repo: z.object({
|
|
1040
|
+
originalUrl: z.string(),
|
|
1041
|
+
reference: z.string(),
|
|
1042
|
+
name: z.string()
|
|
1043
|
+
}),
|
|
1044
|
+
createdByUser: z.object({
|
|
1045
|
+
email: z.string()
|
|
1046
|
+
}).nullable(),
|
|
1047
|
+
state: z.nativeEnum(Fix_Report_State_Enum),
|
|
1048
|
+
expirationOn: z.string()
|
|
1049
|
+
})
|
|
1050
|
+
});
|
|
1051
|
+
var ProjectGetProjectZ = z.object({
|
|
1052
|
+
id: z.string().uuid(),
|
|
1053
|
+
name: z.string(),
|
|
1054
|
+
vulnerabilityReports: z.object({
|
|
1055
|
+
vendor: z.nativeEnum(Vulnerability_Report_Vendor_Enum).nullable(),
|
|
1056
|
+
fixReport: z.object({
|
|
1057
|
+
issueLanguages: z.record(z.nativeEnum(IssueLanguage_Enum), z.number()).nullable(),
|
|
1058
|
+
state: z.nativeEnum(Fix_Report_State_Enum),
|
|
1059
|
+
fixes_aggregate: z.object({
|
|
1060
|
+
aggregate: z.object({
|
|
1061
|
+
count: z.number()
|
|
1062
|
+
})
|
|
1063
|
+
}),
|
|
1064
|
+
repo: z.object({
|
|
1065
|
+
originalUrl: z.string(),
|
|
1066
|
+
reference: z.string()
|
|
1067
|
+
}),
|
|
1068
|
+
expirationOn: z.string()
|
|
1069
|
+
})
|
|
1070
|
+
}).array()
|
|
1071
|
+
});
|
|
1072
|
+
var GetProjectsQueryZ = z.array(ProjectGetProjectZ);
|
|
1073
|
+
var ProjectPageQueryResultZ = z.object({
|
|
1074
|
+
name: z.string(),
|
|
1075
|
+
id: z.string().uuid(),
|
|
1076
|
+
isDefault: z.boolean().default(false),
|
|
1077
|
+
organizationId: z.string().uuid(),
|
|
1078
|
+
vulnerabilityReports: z.array(ProjectVulnerabilityReport)
|
|
1079
|
+
});
|
|
1080
|
+
var GetProjectMembersDataZ = z.object({
|
|
1081
|
+
project_by_pk: z.object({
|
|
1082
|
+
name: z.string(),
|
|
1083
|
+
id: z.string(),
|
|
1084
|
+
projectUsers: z.array(
|
|
1085
|
+
z.object({
|
|
1086
|
+
projectToRole: z.object({
|
|
1087
|
+
projectRole: z.object({
|
|
1088
|
+
type: z.nativeEnum(Project_Role_Type_Enum)
|
|
1089
|
+
})
|
|
1090
|
+
}),
|
|
1091
|
+
user: z.object({
|
|
1092
|
+
id: z.string().uuid(),
|
|
1093
|
+
picture: z.string().optional(),
|
|
1094
|
+
name: z.string().nullish(),
|
|
1095
|
+
email: z.string().email()
|
|
1096
|
+
})
|
|
1097
|
+
})
|
|
1098
|
+
)
|
|
1099
|
+
})
|
|
1100
|
+
});
|
|
1101
|
+
var RepoArgs = z.object({
|
|
1102
|
+
originalUrl: z.string().url(),
|
|
1103
|
+
branch: z.string(),
|
|
1104
|
+
commitSha: z.string()
|
|
1105
|
+
});
|
|
1106
|
+
var scmCloudUrl = {
|
|
1107
|
+
GitLab: "https://gitlab.com",
|
|
1108
|
+
GitHub: "https://github.com",
|
|
1109
|
+
Ado: "https://dev.azure.com",
|
|
1110
|
+
Bitbucket: "https://bitbucket.org"
|
|
1111
|
+
};
|
|
1112
|
+
var ScmType = /* @__PURE__ */ ((ScmType2) => {
|
|
1113
|
+
ScmType2["GitHub"] = "GitHub";
|
|
1114
|
+
ScmType2["GitLab"] = "GitLab";
|
|
1115
|
+
ScmType2["Ado"] = "Ado";
|
|
1116
|
+
ScmType2["Bitbucket"] = "Bitbucket";
|
|
1117
|
+
return ScmType2;
|
|
1118
|
+
})(ScmType || {});
|
|
1119
|
+
|
|
1120
|
+
// src/constants.ts
|
|
1121
|
+
var debug = Debug("mobbdev:constants");
|
|
1122
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
1123
|
+
dotenv.config({ path: path.join(__dirname, "../.env") });
|
|
1124
|
+
var scmFriendlyText = {
|
|
1125
|
+
["Ado" /* Ado */]: "Azure DevOps",
|
|
1126
|
+
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
1127
|
+
["GitHub" /* GitHub */]: "GitGub",
|
|
1128
|
+
["GitLab" /* GitLab */]: "GitLab"
|
|
1129
|
+
};
|
|
1130
|
+
var SCANNERS = {
|
|
1131
|
+
Checkmarx: "checkmarx",
|
|
1132
|
+
Codeql: "codeql",
|
|
1133
|
+
Fortify: "fortify",
|
|
1134
|
+
Snyk: "snyk",
|
|
1135
|
+
Sonarqube: "sonarqube"
|
|
1136
|
+
};
|
|
1137
|
+
var SupportedScannersZ = z2.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
1138
|
+
var envVariablesSchema = z2.object({
|
|
1139
|
+
WEB_APP_URL: z2.string(),
|
|
1140
|
+
API_URL: z2.string(),
|
|
1141
|
+
HASURA_ACCESS_KEY: z2.string(),
|
|
1142
|
+
LOCAL_GRAPHQL_ENDPOINT: z2.string()
|
|
1143
|
+
}).required();
|
|
1144
|
+
var envVariables = envVariablesSchema.parse(process.env);
|
|
1145
|
+
debug("config %o", envVariables);
|
|
1146
|
+
var mobbAscii = `
|
|
1147
|
+
..
|
|
1148
|
+
..........
|
|
1149
|
+
.................
|
|
1150
|
+
...........................
|
|
1151
|
+
..............................
|
|
1152
|
+
................................
|
|
1153
|
+
..................................
|
|
1154
|
+
....................................
|
|
1155
|
+
.....................................
|
|
1156
|
+
.............................................
|
|
1157
|
+
.................................................
|
|
1158
|
+
............................... .................
|
|
1159
|
+
.................................. ............
|
|
1160
|
+
.................. ............. ..........
|
|
1161
|
+
......... ........ ......... ......
|
|
1162
|
+
............... ....
|
|
1163
|
+
.... ..
|
|
1164
|
+
|
|
1165
|
+
. ...
|
|
1166
|
+
..............
|
|
1167
|
+
......................
|
|
1168
|
+
...........................
|
|
1169
|
+
................................
|
|
1170
|
+
......................................
|
|
1171
|
+
...............................
|
|
1172
|
+
.................
|
|
1173
|
+
`;
|
|
1174
|
+
var PROJECT_DEFAULT_NAME = "My first project";
|
|
1175
|
+
var WEB_APP_URL = envVariables.WEB_APP_URL;
|
|
1176
|
+
var API_URL = envVariables.API_URL;
|
|
1177
|
+
var HASURA_ACCESS_KEY = envVariables.HASURA_ACCESS_KEY;
|
|
1178
|
+
var LOCAL_GRAPHQL_ENDPOINT = envVariables.LOCAL_GRAPHQL_ENDPOINT;
|
|
1179
|
+
var errorMessages = {
|
|
1180
|
+
missingCxProjectName: `project name ${chalk.bold(
|
|
1181
|
+
"(--cx-project-name)"
|
|
1182
|
+
)} is needed if you're using checkmarx`,
|
|
1183
|
+
missingUrl: `url ${chalk.bold(
|
|
1184
|
+
"(--url)"
|
|
1185
|
+
)} is needed if you're adding an SCM token`,
|
|
1186
|
+
invalidScmType: `SCM type ${chalk.bold(
|
|
1187
|
+
"(--scm-type)"
|
|
1188
|
+
)} is invalid, please use one of: ${Object.values(ScmType).join(", ")}`,
|
|
1189
|
+
missingToken: `SCM token ${chalk.bold(
|
|
1190
|
+
"(--token)"
|
|
1191
|
+
)} is needed if you're adding an SCM token`
|
|
1192
|
+
};
|
|
1193
|
+
var progressMassages = {
|
|
1194
|
+
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
|
|
1195
|
+
processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
|
|
1196
|
+
processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
|
|
1197
|
+
};
|
|
1198
|
+
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 20;
|
|
1199
|
+
|
|
1200
|
+
// src/features/analysis/index.ts
|
|
1201
|
+
import crypto from "node:crypto";
|
|
1202
|
+
import fs3 from "node:fs";
|
|
1203
|
+
import os from "node:os";
|
|
1204
|
+
import path6 from "node:path";
|
|
1205
|
+
import { pipeline } from "node:stream/promises";
|
|
1206
|
+
|
|
1207
|
+
// src/utils/index.ts
|
|
1208
|
+
var utils_exports = {};
|
|
1209
|
+
__export(utils_exports, {
|
|
1210
|
+
CliError: () => CliError,
|
|
1211
|
+
Spinner: () => Spinner,
|
|
1212
|
+
getDirName: () => getDirName,
|
|
1213
|
+
getTopLevelDirName: () => getTopLevelDirName,
|
|
1214
|
+
keypress: () => keypress,
|
|
1215
|
+
sleep: () => sleep
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
// src/utils/dirname.ts
|
|
1219
|
+
import path2 from "node:path";
|
|
1220
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1221
|
+
function getDirName() {
|
|
1222
|
+
return path2.dirname(fileURLToPath2(import.meta.url));
|
|
1223
|
+
}
|
|
1224
|
+
function getTopLevelDirName(fullPath) {
|
|
1225
|
+
return path2.parse(fullPath).name;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
// src/utils/keypress.ts
|
|
1229
|
+
import readline from "node:readline";
|
|
1230
|
+
async function keypress() {
|
|
1231
|
+
const rl = readline.createInterface({
|
|
1232
|
+
input: process.stdin,
|
|
1233
|
+
output: process.stdout
|
|
1234
|
+
});
|
|
1235
|
+
return new Promise((resolve) => {
|
|
1236
|
+
rl.question("", (answer) => {
|
|
1237
|
+
rl.close();
|
|
1238
|
+
process.stderr.moveCursor(0, -1);
|
|
1239
|
+
process.stderr.clearLine(1);
|
|
1240
|
+
resolve(answer);
|
|
1241
|
+
});
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// src/utils/spinner.ts
|
|
1246
|
+
import {
|
|
1247
|
+
createSpinner as _createSpinner
|
|
1248
|
+
} from "nanospinner";
|
|
1249
|
+
var mockSpinner = {
|
|
1250
|
+
success: () => mockSpinner,
|
|
1251
|
+
error: () => mockSpinner,
|
|
1252
|
+
warn: () => mockSpinner,
|
|
1253
|
+
stop: () => mockSpinner,
|
|
1254
|
+
start: () => mockSpinner,
|
|
1255
|
+
update: () => mockSpinner,
|
|
1256
|
+
reset: () => mockSpinner,
|
|
1257
|
+
clear: () => mockSpinner,
|
|
1258
|
+
spin: () => mockSpinner
|
|
1259
|
+
};
|
|
1260
|
+
function Spinner({ ci = false } = {}) {
|
|
1261
|
+
return {
|
|
1262
|
+
createSpinner: (text, options) => ci ? mockSpinner : _createSpinner(text, options)
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
// src/utils/index.ts
|
|
1267
|
+
var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
|
|
1268
|
+
var CliError = class extends Error {
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
// src/features/analysis/index.ts
|
|
1272
|
+
import chalk4 from "chalk";
|
|
1273
|
+
import Configstore from "configstore";
|
|
1274
|
+
import Debug13 from "debug";
|
|
1275
|
+
import extract from "extract-zip";
|
|
1276
|
+
import fetch4 from "node-fetch";
|
|
1277
|
+
import open2 from "open";
|
|
1278
|
+
import semver from "semver";
|
|
1279
|
+
import tmp2 from "tmp";
|
|
1280
|
+
import { z as z19 } from "zod";
|
|
1281
|
+
|
|
1282
|
+
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
1283
|
+
import Debug4 from "debug";
|
|
1284
|
+
|
|
1285
|
+
// src/features/analysis/scm/ado/constants.ts
|
|
1286
|
+
var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
1287
|
+
|
|
1288
|
+
// src/features/analysis/scm/ado/utils.ts
|
|
1289
|
+
import querystring3 from "node:querystring";
|
|
1290
|
+
import * as api from "azure-devops-node-api";
|
|
1291
|
+
import { z as z16 } from "zod";
|
|
1292
|
+
|
|
1293
|
+
// src/features/analysis/scm/env.ts
|
|
1294
|
+
import { z as z3 } from "zod";
|
|
1295
|
+
var EnvVariablesZod = z3.object({
|
|
1296
|
+
GITLAB_API_TOKEN: z3.string().optional(),
|
|
1297
|
+
GITHUB_API_TOKEN: z3.string().optional(),
|
|
1298
|
+
GIT_PROXY_HOST: z3.string()
|
|
1299
|
+
});
|
|
1300
|
+
var { GITLAB_API_TOKEN, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
|
|
1301
|
+
|
|
1302
|
+
// src/features/analysis/scm/scm.ts
|
|
1303
|
+
import { z as z14 } from "zod";
|
|
1304
|
+
|
|
1305
|
+
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
1306
|
+
import querystring from "node:querystring";
|
|
1307
|
+
import bitbucketPkg from "bitbucket";
|
|
1308
|
+
import * as bitbucketPkgNode from "bitbucket";
|
|
1309
|
+
import { z as z10 } from "zod";
|
|
1310
|
+
|
|
1311
|
+
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
1312
|
+
import { z as z5 } from "zod";
|
|
1313
|
+
|
|
1314
|
+
// src/features/analysis/scm/shared/src/fixDetailsData.ts
|
|
1315
|
+
var fixDetailsData = {
|
|
1316
|
+
["PT" /* Pt */]: {
|
|
1317
|
+
issueDescription: "Path Traversal AKA Directory Traversal occurs when a path coming from user input is not properly sanitized, allowing an attacker to navigate through directories beyond the intended scope. Attackers can exploit this to access sensitive files or execute arbitrary code.",
|
|
1318
|
+
fixInstructions: "Sanitize user-supplied paths, ensuring that they are restricted to a predefined directory structure."
|
|
1319
|
+
},
|
|
1320
|
+
["ZIP_SLIP" /* ZipSlip */]: {
|
|
1321
|
+
issueDescription: "Zip Slip is a form of directory traversal that can be exploited by extracting files from an archive. Attackers can manipulate archive files to overwrite sensitive files or execute arbitrary code.",
|
|
1322
|
+
fixInstructions: "Ensure that extracted files are relative and within the intended directory structure."
|
|
1323
|
+
},
|
|
1324
|
+
["XSS" /* Xss */]: {
|
|
1325
|
+
issueDescription: "Cross-Site Scripting (XSS) allows attackers to inject malicious scripts into web pages viewed by other users. This can lead to theft of session cookies, redirection to malicious websites, or defacement of the webpage.",
|
|
1326
|
+
fixInstructions: "Implement input validation and output encoding. This includes sanitizing user input and escaping special characters to prevent execution of injected scripts."
|
|
1327
|
+
},
|
|
1328
|
+
["XXE" /* Xxe */]: {
|
|
1329
|
+
issueDescription: "XML External Entity (XXE) allows attackers to exploit vulnerable XML processors by including external entities, leading to disclosure of confidential data, denial of service, or server-side request forgery.",
|
|
1330
|
+
fixInstructions: "Disable external entity processing in XML parsers or update to versions that mitigate XXE vulnerabilities. Input validation should be implemented to ensure that XML input does not contain external entity references."
|
|
1331
|
+
},
|
|
1332
|
+
["CMDi" /* CmDi */]: {
|
|
1333
|
+
issueDescription: "Command Injection (CMDI) allows attackers inject malicious commands into vulnerable applications, that can result in execution of arbitrary commands on the underlying operating system.",
|
|
1334
|
+
fixInstructions: "Validate or sanitize user input to prevent executing arbitrary commands."
|
|
1335
|
+
},
|
|
1336
|
+
["SQL_Injection" /* SqlInjection */]: {
|
|
1337
|
+
issueDescription: "SQL Injection allows attackers to execute malicious SQL queries by manipulating input data. This can result in unauthorized access to sensitive data, data manipulation, or even complete database compromise.",
|
|
1338
|
+
fixInstructions: "Use parameterized queries or prepared statements to sanitize user input and prevent manipulation of the SQL query."
|
|
1339
|
+
},
|
|
1340
|
+
["SSRF" /* Ssrf */]: {
|
|
1341
|
+
issueDescription: "Server-Side Request Forgery (SSRF) allows attackers to make unauthorized requests from a vulnerable server, potentially accessing internal systems, services, or data.",
|
|
1342
|
+
fixInstructions: "Validate or sanitize user-supplied URLs, ensuring that they are restricted to trusted domains. Implementing proper input validation and using whitelists for acceptable URLs can prevent SSRF attacks."
|
|
1343
|
+
},
|
|
1344
|
+
["LOG_FORGING" /* LogForging */]: {
|
|
1345
|
+
issueDescription: "Log Forging allows attackers to manipulate log files by injecting malicious content. This can be used to obfuscate attack traces or forge log entries to conceal unauthorized activities.",
|
|
1346
|
+
fixInstructions: "Implement proper input sanitization to remove new lines for values going to the log."
|
|
1347
|
+
},
|
|
1348
|
+
["HTTP_ONLY_COOKIE" /* HttpOnlyCookie */]: {
|
|
1349
|
+
issueDescription: "Cookie without the 'HttpOnly' attribute can be accessed by client-side scripts, exposing them to potential XSS attacks.",
|
|
1350
|
+
fixInstructions: "Ensure that sensitive cookies are marked with the 'HttpOnly' attribute to prevent client-side scripts from accessing them."
|
|
1351
|
+
},
|
|
1352
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: {
|
|
1353
|
+
issueDescription: "System Information Leak occurs when sensitive system information is inadvertently disclosed to external entities, potentially aiding attackers in identifying vulnerabilities or targets.",
|
|
1354
|
+
fixInstructions: "Review and restrict the amount of system information exposed through error messages, debug logs, or response headers."
|
|
1355
|
+
},
|
|
1356
|
+
["UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */]: {
|
|
1357
|
+
issueDescription: "Unchecked Loop Condition can lead to infinite loops or unexpected behavior in software applications. Attackers can exploit this vulnerability to cause denial of service or consume excessive system resources.",
|
|
1358
|
+
fixInstructions: "Carefully review loop conditions to ensure that they are properly validated and bounded."
|
|
1359
|
+
},
|
|
1360
|
+
["TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */]: {
|
|
1361
|
+
issueDescription: "Trust Boundary Violation occurs when untrusted data is added to a trusted context, potentially leading to security vulnerabilities. Attackers can exploit this to bypass security controls or execute unauthorized actions.",
|
|
1362
|
+
fixInstructions: "Clearly define and enforce trust boundaries within applications, ensuring that untrusted data is properly validated and sanitized before being used in a trusted context."
|
|
1363
|
+
},
|
|
1364
|
+
["REGEX_INJECTION" /* RegexInjection */]: {
|
|
1365
|
+
issueDescription: "Regex Injection occurs when attackers manipulate regular expressions to perform unintended actions or bypass security controls. This can lead to security vulnerabilities such as denial of service or injection attacks.",
|
|
1366
|
+
fixInstructions: "Avoid constructing regular expressions from user-supplied input whenever possible. If dynamic regular expressions are necessary, input should be properly validated and sanitized to prevent injection attacks."
|
|
1367
|
+
},
|
|
1368
|
+
["ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */]: {
|
|
1369
|
+
issueDescription: "Error Condition Without Action refers to situations where error conditions are identified but not appropriately handled or mitigated. This can lead to unexpected behavior, system crashes, or security vulnerabilities.",
|
|
1370
|
+
fixInstructions: "Implement error handling mechanisms to gracefully handle unexpected conditions and prevent system crashes."
|
|
1371
|
+
},
|
|
1372
|
+
["HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */]: {
|
|
1373
|
+
issueDescription: "HTTP Response Splitting occurs when attackers manipulate HTTP responses to inject additional headers or content. This can lead to security vulnerabilities such as cache poisoning, session fixation, or XSS attacks.",
|
|
1374
|
+
fixInstructions: "Properly sanitize user input before including it in HTTP response headers or content."
|
|
1375
|
+
},
|
|
1376
|
+
["INSECURE_COOKIE" /* InsecureCookie */]: {
|
|
1377
|
+
issueDescription: "Cookies lacking the 'Secure' attribute may be transmitted over unencrypted channels. This makes them vulnerable to interception or manipulation by attackers.",
|
|
1378
|
+
fixInstructions: "Ensure that sensitive cookies are transmitted over secure channels (e.g., HTTPS) and are marked with the 'Secure' attributes."
|
|
1379
|
+
},
|
|
1380
|
+
["CMDi_relative_path_command" /* CmDiRelativePathCommand */]: {
|
|
1381
|
+
issueDescription: "Command Injection via Relative Path may allow attackers to manipulate file paths to execute arbitrary commands on the underlying system.",
|
|
1382
|
+
fixInstructions: "Paths coming from the input should be properly sanitized to ensure that only expected characters and paths are allowed."
|
|
1383
|
+
},
|
|
1384
|
+
["MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */]: {
|
|
1385
|
+
issueDescription: "Missing Check Against Null occurs when null or uninitialized variables are not properly handled, leading to unexpected behavior or security vulnerabilities.",
|
|
1386
|
+
fixInstructions: "Implement proper null checks and error handling mechanisms to prevent null dereference vulnerabilities. Null values should be handled gracefully to avoid unexpected behavior or security issues."
|
|
1387
|
+
},
|
|
1388
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: {
|
|
1389
|
+
issueDescription: "Password in Comment refers to situations where sensitive information such as passwords or API keys are hardcoded or embedded in code comments. This can lead to inadvertent exposure of credentials and potential security breaches if the code is shared or leaked.",
|
|
1390
|
+
fixInstructions: "Remove hardcoded sensitive information from code comments."
|
|
1391
|
+
},
|
|
1392
|
+
["OVERLY_BROAD_CATCH" /* OverlyBroadCatch */]: {
|
|
1393
|
+
issueDescription: "Overly Broad Catch occurs when exceptions are caught indiscriminately without proper handling or logging. This can lead to silent failures, masking potential security issues or allowing attackers to conduct reconnaissance.",
|
|
1394
|
+
fixInstructions: "Implement specific exception handling for different error scenarios to ensure proper diagnosis and mitigation of issues. Catch blocks should log relevant information and handle exceptions gracefully to prevent silent failures."
|
|
1395
|
+
},
|
|
1396
|
+
["USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */]: {
|
|
1397
|
+
issueDescription: "Use of System Output Stream refers to situations where sensitive information is written to standard output streams such as System.out. This can lead to inadvertent exposure of sensitive data, especially in production environments.",
|
|
1398
|
+
fixInstructions: "Avoid writing sensitive information to standard output streams and instead use secure logging mechanisms or dedicated logging frameworks. Output streams should be properly configured to prevent leakage of sensitive data."
|
|
1399
|
+
},
|
|
1400
|
+
["DOS_STRING_BUILDER" /* DosStringBuilder */]: {
|
|
1401
|
+
issueDescription: "Denial of Service (DoS) via String Builder may allow attackers to manipulate string concatenation operations to consume excessive memory or CPU resources. This can lead to degradation of system performance or unresponsiveness.",
|
|
1402
|
+
fixInstructions: "Use StringBuilder or similar efficient data structures for string concatenation operations to minimize memory overhead. Input validation should be performed to limit the size and complexity of input strings, preventing abuse by attackers."
|
|
1403
|
+
},
|
|
1404
|
+
["HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */]: {
|
|
1405
|
+
issueDescription: "HTML Comment in JSP occurs when developers inadvertently expose sensitive information or internal implementation details in HTML comments within JavaServer Pages (JSP) files. This can lead to inadvertent disclosure of credentials, configuration details, or security vulnerabilities.",
|
|
1406
|
+
fixInstructions: "Review JSP files to ensure that sensitive information or internal details are not exposed in HTML comments. Comments containing sensitive information should be removed or replaced with generic placeholders."
|
|
1407
|
+
},
|
|
1408
|
+
["OPEN_REDIRECT" /* OpenRedirect */]: {
|
|
1409
|
+
issueDescription: "Open Redirect vulnerabilities may allow attackers to manipulate URL parameters to redirect users to malicious websites or phishing pages. This can lead to theft of sensitive information or unauthorized access to user accounts.",
|
|
1410
|
+
fixInstructions: "Redirect URLs validation should be performed to ensure that redirect URLs point to trusted domains."
|
|
1411
|
+
},
|
|
1412
|
+
["UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */]: {
|
|
1413
|
+
issueDescription: "Unsafe Target Blank occurs when developers use the target='_blank' attribute without the rel='noopener' attribute in anchor tags. This can lead to security vulnerabilities such as tabnabbing or reverse tabnabbing, allowing attackers to hijack user sessions or perform phishing attacks.",
|
|
1414
|
+
fixInstructions: "Ensure that anchor tags with target='_blank' attribute include the rel='noopener' attribute to prevent potential security vulnerabilities. This prevents the newly opened page from accessing the window.opener property, mitigating the risk of tabnabbing or reverse tabnabbing attacks."
|
|
1415
|
+
},
|
|
1416
|
+
["IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */]: {
|
|
1417
|
+
issueDescription: "IFrame Without Sandbox occurs when <iframe> elements are used without the 'sandbox' attribute, allowing potentially malicious content to execute in the context of the parent page.",
|
|
1418
|
+
fixInstructions: "Use the 'sandbox' attribute to restrict the capabilities of <iframe> elements, isolating potentially untrusted content from the parent page. This helps mitigate the risk of malicious code execution and prevents attacks such as clickjacking."
|
|
1419
|
+
},
|
|
1420
|
+
["JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */]: {
|
|
1421
|
+
issueDescription: "JQuery Deprecated Symbols refers to the use of deprecated or removed functions, methods, or symbols in jQuery libraries. This can lead to compatibility issues, security vulnerabilities, or performance degradation in applications.",
|
|
1422
|
+
fixInstructions: "Replace deprecated symbols with recommended alternatives."
|
|
1423
|
+
},
|
|
1424
|
+
["DEPRECATED_FUNCTION" /* DeprecatedFunction */]: {
|
|
1425
|
+
issueDescription: "Deprecated Function refers to the use of functions, methods, or features that have been deprecated in programming languages or frameworks. This can lead to compatibility issues, security vulnerabilities, or performance degradation in applications.",
|
|
1426
|
+
fixInstructions: "Update code to replace deprecated functions with recommended alternatives provided by the language or framework."
|
|
1427
|
+
},
|
|
1428
|
+
["HARDCODED_SECRETS" /* HardcodedSecrets */]: {
|
|
1429
|
+
issueDescription: "Hardcoded Secrets refers to the practice of embedding sensitive information such as passwords, API keys, or cryptographic keys directly into source code or configuration files. This can lead to inadvertent exposure of credentials and potential security breaches if the code is shared or leaked.",
|
|
1430
|
+
fixInstructions: "Remove hardcoded sensitive information in source code or configuration files. Instead, sensitive data should be stored securely using encryption or secure credential management solutions."
|
|
1431
|
+
},
|
|
1432
|
+
["GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */]: {
|
|
1433
|
+
issueDescription: "GraphQL Depth Limit refers to the lack of restrictions on query depth in GraphQL implementations, allowing attackers to execute complex and resource-intensive queries. This can lead to denial of service or excessive resource consumption.",
|
|
1434
|
+
fixInstructions: "Implement depth limits and query complexity thresholds in GraphQL schemas to restrict the complexity of incoming queries."
|
|
1435
|
+
},
|
|
1436
|
+
["SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */]: {
|
|
1437
|
+
issueDescription: "System Information Leak occurs when sensitive system information is inadvertently disclosed to external entities, potentially aiding attackers in identifying vulnerabilities or targets.",
|
|
1438
|
+
fixInstructions: "Review and restrict the amount of system information exposed to external entities such as third-party APIs or integrations."
|
|
1439
|
+
},
|
|
1440
|
+
["INSECURE_RANDOMNESS" /* InsecureRandomness */]: {
|
|
1441
|
+
issueDescription: "Insecure Randomness refers to the use of insecure or predictable random number generation algorithms, leading to weak cryptographic keys, session tokens, or initialization vectors. This can facilitate brute-force attacks or cryptographic exploits.",
|
|
1442
|
+
fixInstructions: "Use secure random number generation algorithms provided by cryptographic libraries or frameworks."
|
|
1443
|
+
},
|
|
1444
|
+
["TYPE_CONFUSION" /* TypeConfusion */]: {
|
|
1445
|
+
issueDescription: "Type Confusion occurs in programming languages with weak typing systems when an attacker manipulates object types to bypass type checks or exploit memory corruption vulnerabilities. This can lead to arbitrary code execution or unauthorized access to sensitive data.",
|
|
1446
|
+
fixInstructions: "Implement strict type checking and validation to prevent type confusion vulnerabilities."
|
|
1447
|
+
},
|
|
1448
|
+
["INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */]: {
|
|
1449
|
+
issueDescription: "Incomplete URL Sanitization occurs when user-supplied URLs are not properly sanitized, allowing attackers to inject malicious content or bypass security controls. This can lead to security vulnerabilities such as XSS attacks, open redirect, or SSRF.",
|
|
1450
|
+
fixInstructions: "Implement thorough URL validation and/or sanitization to ensure that user-supplied URLs conform to expected formats and do not contain malicious content."
|
|
1451
|
+
},
|
|
1452
|
+
["UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */]: {
|
|
1453
|
+
issueDescription: "Unsafe Deserialization occurs when attackers manipulate serialized objects to execute arbitrary code or bypass security controls. This can lead to remote code execution, privilege escalation, or data tampering.",
|
|
1454
|
+
fixInstructions: "Implement strict validation and integrity checks on serialized objects."
|
|
1455
|
+
},
|
|
1456
|
+
["IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */]: {
|
|
1457
|
+
issueDescription: "Improper Resource Shutdown or Release refers to situations where system resources such as file handles, database connections, or network sockets are not properly closed or released after use. This can lead to resource exhaustion, denial of service, or memory leaks.",
|
|
1458
|
+
fixInstructions: "Ensure that system resources are consistently closed or released after use. Using try-with resources blocks, finalizers, or dedicated resource management libraries can help mitigate the risk of improper resource shutdown or release vulnerabilities."
|
|
1459
|
+
},
|
|
1460
|
+
["IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */]: {
|
|
1461
|
+
issueDescription: "Improper Exception Handling occurs when exceptions are not handled or propagated correctly, leading to unexpected behavior, security vulnerabilities, or application crashes.",
|
|
1462
|
+
fixInstructions: "Implement exception handling to gracefully handle unexpected errors."
|
|
1463
|
+
},
|
|
1464
|
+
["MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */]: {
|
|
1465
|
+
issueDescription: "Missing Anti-Forgery Validation occurs when web applications do not properly validate or enforce anti-forgery tokens, allowing attackers to forge or replay requests from authenticated users.",
|
|
1466
|
+
fixInstructions: "Implement anti-forgery measures to validate the authenticity of user-submitted requests."
|
|
1467
|
+
},
|
|
1468
|
+
["INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */]: {
|
|
1469
|
+
issueDescription: "Insecure Binder Configuration refers to misconfigurations in application frameworks or dependency injection containers, leading to security vulnerabilities such as injection attacks or privilege escalation.",
|
|
1470
|
+
fixInstructions: "Secure binder configurations to prevent injection attacks and enforce least privilege principles. Configurations should be restricted to trusted sources and sanitized to prevent unauthorized access or manipulation."
|
|
1471
|
+
},
|
|
1472
|
+
["NULL_DEREFERENCE" /* NullDereference */]: {
|
|
1473
|
+
issueDescription: "Null Dereference occurs when null or uninitialized pointers are dereferenced, leading to application crashes or security vulnerabilities. Attackers can exploit this to cause denial of service or execute arbitrary code.",
|
|
1474
|
+
fixInstructions: "Implement proper null checks and error handling mechanisms. Null values should be handled gracefully to avoid unexpected behavior or security issues."
|
|
1475
|
+
},
|
|
1476
|
+
["DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */]: {
|
|
1477
|
+
issueDescription: "Dangerous Function Overflow occurs when functions or methods are called with parameters that exceed predefined limits, leading to buffer overflows or memory corruption vulnerabilities.",
|
|
1478
|
+
fixInstructions: "Implement proper input validation and bounds checking to prevent dangerous function overflows. Functions should be designed to handle input within safe limits and gracefully reject or truncate input that exceeds these limits."
|
|
1479
|
+
},
|
|
1480
|
+
["DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */]: {
|
|
1481
|
+
issueDescription: "Default Rights in Object Definition refers to situations where SQL objects are created with default or excessive permissions, leading to security vulnerabilities such as privilege escalation or unauthorized access.",
|
|
1482
|
+
fixInstructions: "Restrict default permissions in object definitions to enforce least privilege principles. Objects should be created with the minimum necessary permissions required for their intended functionality."
|
|
1483
|
+
},
|
|
1484
|
+
["WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */]: {
|
|
1485
|
+
issueDescription: "Weak XML Schema Unbounded Occurrences refers to the lack of restrictions on the maximum number of occurrences for elements or attributes in XML schemas. This can lead to denial of service or resource exhaustion attacks by causing excessive memory consumption or processing overhead.",
|
|
1486
|
+
fixInstructions: "Impose limits on the maximum number of occurrences for elements or attributes in XML schemas to prevent resource exhaustion attacks."
|
|
1487
|
+
},
|
|
1488
|
+
["DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */]: void 0,
|
|
1489
|
+
["LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */]: void 0,
|
|
1490
|
+
["MISSING_HSTS_HEADER" /* MissingHstsHeader */]: void 0,
|
|
1491
|
+
["NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */]: void 0,
|
|
1492
|
+
["PROTOTYPE_POLLUTION" /* PrototypePollution */]: void 0,
|
|
1493
|
+
["RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */]: void 0,
|
|
1494
|
+
["HEADER_MANIPULATION" /* HeaderManipulation */]: void 0,
|
|
1495
|
+
["MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */]: {
|
|
1496
|
+
issueDescription: "Missing equals or hashcode method can lead to unexpected behavior in collections. If two objects are equal, they should have the same hashcode.",
|
|
1497
|
+
fixInstructions: "Add the missing methods to ensure proper behavior in collections."
|
|
1498
|
+
},
|
|
1499
|
+
["VALUE_NEVER_READ" /* ValueNeverRead */]: {
|
|
1500
|
+
issueDescription: "The variable's value is not used. After the assignment, the variable is either assigned another value or goes out of scope.",
|
|
1501
|
+
fixInstructions: "Remove the assignment to the variable."
|
|
1502
|
+
},
|
|
1503
|
+
["WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */]: void 0,
|
|
1504
|
+
["WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */]: void 0,
|
|
1505
|
+
["USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */]: void 0,
|
|
1506
|
+
["INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */]: void 0,
|
|
1507
|
+
["OVERLY_LARGE_RANGE" /* OverlyLargeRange */]: void 0,
|
|
1508
|
+
["PRIVACY_VIOLATION" /* PrivacyViolation */]: void 0,
|
|
1509
|
+
["VALUE_SHADOWING" /* ValueShadowing */]: void 0,
|
|
1510
|
+
["INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */]: void 0,
|
|
1511
|
+
["INSUFFICIENT_LOGGING" /* InsufficientLogging */]: void 0,
|
|
1512
|
+
["NO_EQUIVALENCE_METHOD" /* NoEquivalenceMethod */]: void 0,
|
|
1513
|
+
["INFORMATION_EXPOSURE_VIA_HEADERS" /* InformationExposureViaHeaders */]: void 0,
|
|
1514
|
+
["DEBUG_ENABLED" /* DebugEnabled */]: void 0,
|
|
1515
|
+
["CONFUSING_NAMING" /* ConfusingNaming */]: {
|
|
1516
|
+
issueDescription: "A data member and a function have the same name which can be confusing to the developer.",
|
|
1517
|
+
fixInstructions: "Rename the data member to avoid confusion."
|
|
1518
|
+
},
|
|
1519
|
+
["LEFTOVER_DEBUG_CODE" /* LeftoverDebugCode */]: void 0,
|
|
1520
|
+
["UNVALIDATED_PUBLIC_METHOD_ARGUMENT" /* UnvalidatedPublicMethodArgument */]: void 0,
|
|
1521
|
+
["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: void 0,
|
|
1522
|
+
["POOR_ERROR_HANDLING_EMPTY_CATCH_BLOCK" /* PoorErrorHandlingEmptyCatchBlock */]: void 0,
|
|
1523
|
+
["AUTO_ESCAPE_FALSE" /* AutoEscapeFalse */]: {
|
|
1524
|
+
issueDescription: "Auto Escape False occurs when automatic escaping is disabled in template engines, allowing untrusted data to be rendered without proper encoding. This can lead to Cross-Site Scripting (XSS) vulnerabilities.",
|
|
1525
|
+
fixInstructions: "Set auto escape to true."
|
|
1526
|
+
},
|
|
1527
|
+
["NO_LIMITS_OR_THROTTLING" /* NoLimitsOrThrottling */]: {
|
|
1528
|
+
issueDescription: "The lack of a rate limit can allow denial-of-service attacks, in which an attacker can cause the application to crash or become unresponsive by issuing a large number of requests simultaneously.",
|
|
1529
|
+
fixInstructions: "Use express-rate-limit npm package to set a rate limit."
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
// src/features/analysis/scm/shared/src/getIssueType.ts
|
|
1534
|
+
import { z as z4 } from "zod";
|
|
1535
|
+
var issueTypeMap = {
|
|
1536
|
+
["NO_LIMITS_OR_THROTTLING" /* NoLimitsOrThrottling */]: "Missing Rate Limiting",
|
|
1537
|
+
["SQL_Injection" /* SqlInjection */]: "SQL Injection",
|
|
1538
|
+
["CMDi_relative_path_command" /* CmDiRelativePathCommand */]: "Relative Path Command Injection",
|
|
1539
|
+
["CMDi" /* CmDi */]: "Command Injection",
|
|
1540
|
+
["CONFUSING_NAMING" /* ConfusingNaming */]: "Confusing Naming",
|
|
1541
|
+
["XXE" /* Xxe */]: "XXE",
|
|
1542
|
+
["XSS" /* Xss */]: "XSS",
|
|
1543
|
+
["PT" /* Pt */]: "Path Traversal",
|
|
1544
|
+
["ZIP_SLIP" /* ZipSlip */]: "Zip Slip",
|
|
1545
|
+
["INSECURE_RANDOMNESS" /* InsecureRandomness */]: "Insecure Randomness",
|
|
1546
|
+
["SSRF" /* Ssrf */]: "Server Side Request Forgery",
|
|
1547
|
+
["TYPE_CONFUSION" /* TypeConfusion */]: "Type Confusion",
|
|
1548
|
+
["REGEX_INJECTION" /* RegexInjection */]: "Regular Expression Injection",
|
|
1549
|
+
["INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */]: "Incomplete URL Sanitization",
|
|
1550
|
+
["LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */]: "Locale Dependent Comparison",
|
|
1551
|
+
["LOG_FORGING" /* LogForging */]: "Log Forging",
|
|
1552
|
+
["MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */]: "Missing Check against Null",
|
|
1553
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: "Password in Comment",
|
|
1554
|
+
["OVERLY_BROAD_CATCH" /* OverlyBroadCatch */]: "Poor Error Handling: Overly Broad Catch",
|
|
1555
|
+
["USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */]: "Use of System.out/System.err",
|
|
1556
|
+
["DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */]: "Use of dangerous function",
|
|
1557
|
+
["DOS_STRING_BUILDER" /* DosStringBuilder */]: "Denial of Service: StringBuilder",
|
|
1558
|
+
["OPEN_REDIRECT" /* OpenRedirect */]: "Open Redirect",
|
|
1559
|
+
["WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */]: "Weak XML Schema: Unbounded Occurrences",
|
|
1560
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: "System Information Leak",
|
|
1561
|
+
["SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */]: "External System Information Leak",
|
|
1562
|
+
["HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */]: "HTTP response splitting",
|
|
1563
|
+
["HTTP_ONLY_COOKIE" /* HttpOnlyCookie */]: "Cookie is not HttpOnly",
|
|
1564
|
+
["INSECURE_COOKIE" /* InsecureCookie */]: "Insecure Cookie",
|
|
1565
|
+
["TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */]: "Trust Boundary Violation",
|
|
1566
|
+
["NULL_DEREFERENCE" /* NullDereference */]: "Null Dereference",
|
|
1567
|
+
["UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */]: "Unsafe deserialization",
|
|
1568
|
+
["INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */]: "Insecure Binder Configuration",
|
|
1569
|
+
["UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */]: "Unsafe use of target blank",
|
|
1570
|
+
["IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */]: "Client use of iframe without sandbox",
|
|
1571
|
+
["JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */]: "jQuery deprecated symbols",
|
|
1572
|
+
["MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */]: "Missing Anti-Forgery Validation",
|
|
1573
|
+
["GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */]: "GraphQL Depth Limit",
|
|
1574
|
+
["UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */]: "Unchecked Loop Condition",
|
|
1575
|
+
["IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */]: "Improper Resource Shutdown or Release",
|
|
1576
|
+
["IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */]: "Improper Exception Handling",
|
|
1577
|
+
["DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */]: "Default Definer Rights in Package or Object Definition",
|
|
1578
|
+
["HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */]: "HTML Comment in JSP",
|
|
1579
|
+
["ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */]: "Error Condition Without Action",
|
|
1580
|
+
["DEPRECATED_FUNCTION" /* DeprecatedFunction */]: "Deprecated Function",
|
|
1581
|
+
["HARDCODED_SECRETS" /* HardcodedSecrets */]: "Hardcoded Secrets",
|
|
1582
|
+
["PROTOTYPE_POLLUTION" /* PrototypePollution */]: "Prototype Pollution",
|
|
1583
|
+
["RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */]: "Race Condition Format Flaw",
|
|
1584
|
+
["NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */]: "Non-final Public Static Field",
|
|
1585
|
+
["MISSING_HSTS_HEADER" /* MissingHstsHeader */]: "Missing HSTS Header",
|
|
1586
|
+
["DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */]: "Dead Code: Unused Field",
|
|
1587
|
+
["HEADER_MANIPULATION" /* HeaderManipulation */]: "Header Manipulation",
|
|
1588
|
+
["MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */]: "Missing equals or hashcode method",
|
|
1589
|
+
["WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */]: "WCF Misconfiguration: Insufficient Logging",
|
|
1590
|
+
["WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */]: "WCF Misconfiguration: Throttling Not Enabled",
|
|
1591
|
+
["USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */]: "Useless regular-expression character escape",
|
|
1592
|
+
["INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */]: "Incomplete Hostname Regex",
|
|
1593
|
+
["OVERLY_LARGE_RANGE" /* OverlyLargeRange */]: "Regex: Overly Large Range",
|
|
1594
|
+
["INSUFFICIENT_LOGGING" /* InsufficientLogging */]: "Insufficient Logging of Sensitive Operations",
|
|
1595
|
+
["PRIVACY_VIOLATION" /* PrivacyViolation */]: "Privacy Violation",
|
|
1596
|
+
["INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */]: "Incomplete URL Scheme Check",
|
|
1597
|
+
["VALUE_NEVER_READ" /* ValueNeverRead */]: "Value Never Read",
|
|
1598
|
+
["VALUE_SHADOWING" /* ValueShadowing */]: "Value Shadowing",
|
|
1599
|
+
["NO_EQUIVALENCE_METHOD" /* NoEquivalenceMethod */]: "Class Does Not Implement Equivalence Method",
|
|
1600
|
+
["INFORMATION_EXPOSURE_VIA_HEADERS" /* InformationExposureViaHeaders */]: "Information Exposure via Headers",
|
|
1601
|
+
["DEBUG_ENABLED" /* DebugEnabled */]: "Debug Enabled",
|
|
1602
|
+
["LEFTOVER_DEBUG_CODE" /* LeftoverDebugCode */]: "Leftover Debug Code",
|
|
1603
|
+
["POOR_ERROR_HANDLING_EMPTY_CATCH_BLOCK" /* PoorErrorHandlingEmptyCatchBlock */]: "Poor Error Handling: Empty Catch Block",
|
|
1604
|
+
["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: "Erroneous String Compare",
|
|
1605
|
+
["UNVALIDATED_PUBLIC_METHOD_ARGUMENT" /* UnvalidatedPublicMethodArgument */]: "Unvalidated Public Method Argument",
|
|
1606
|
+
["AUTO_ESCAPE_FALSE" /* AutoEscapeFalse */]: "Auto-escape False"
|
|
1607
|
+
};
|
|
1608
|
+
var issueTypeZ = z4.nativeEnum(IssueType_Enum);
|
|
1609
|
+
var getIssueType = (issueType) => {
|
|
1610
|
+
const issueTypeZParseRes = issueTypeZ.safeParse(issueType);
|
|
1611
|
+
if (!issueTypeZParseRes.success) {
|
|
1612
|
+
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
1613
|
+
}
|
|
1614
|
+
return issueTypeMap[issueTypeZParseRes.data];
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
1618
|
+
function capitalizeFirstLetter(str) {
|
|
1619
|
+
return str?.length ? str[0].toUpperCase() + str.slice(1) : "";
|
|
1620
|
+
}
|
|
1621
|
+
var severityToEmoji = {
|
|
1622
|
+
["critical" /* Critical */]: "\u{1F6A8}",
|
|
1623
|
+
["high" /* High */]: "\u{1F6A9}",
|
|
1624
|
+
["medium" /* Medium */]: "\u{1F7E1}",
|
|
1625
|
+
["low" /* Low */]: "\u{1F7E2}"
|
|
1626
|
+
};
|
|
1627
|
+
var getCommitDescription = ({
|
|
1628
|
+
vendor,
|
|
1629
|
+
issueType,
|
|
1630
|
+
severity,
|
|
1631
|
+
guidances,
|
|
1632
|
+
fixUrl
|
|
1633
|
+
}) => {
|
|
1634
|
+
const parseIssueTypeRes = z5.nativeEnum(IssueType_Enum).safeParse(issueType);
|
|
1635
|
+
if (!parseIssueTypeRes.success) {
|
|
1636
|
+
return "";
|
|
1637
|
+
}
|
|
1638
|
+
if (!issueType)
|
|
1639
|
+
return "";
|
|
1640
|
+
const staticData = fixDetailsData[parseIssueTypeRes.data];
|
|
1641
|
+
if (!staticData) {
|
|
1642
|
+
return "";
|
|
1643
|
+
}
|
|
1644
|
+
const issueTypeString = getIssueType(issueType);
|
|
1645
|
+
let description = `This change fixes a **${severity} severity** (${severityToEmoji[severity]}) **${issueTypeString}** issue reported by **${capitalizeFirstLetter(
|
|
1646
|
+
vendor
|
|
1647
|
+
)}**.
|
|
1648
|
+
|
|
1649
|
+
## Issue description
|
|
1650
|
+
${staticData.issueDescription}
|
|
1651
|
+
|
|
1652
|
+
## Fix instructions
|
|
1653
|
+
${staticData.fixInstructions}
|
|
1654
|
+
|
|
1655
|
+
${guidances.map(({ guidance }) => `## Additional actions required
|
|
1656
|
+
${guidance}
|
|
1657
|
+
`).join("")}
|
|
1658
|
+
`;
|
|
1659
|
+
if (fixUrl) {
|
|
1660
|
+
description += `
|
|
1661
|
+
[More info and fix customization are available in the Mobb platform](${fixUrl})`;
|
|
1662
|
+
}
|
|
1663
|
+
return description;
|
|
1664
|
+
};
|
|
1665
|
+
|
|
1666
|
+
// src/features/analysis/scm/shared/src/guidances.ts
|
|
1667
|
+
import { z as z8 } from "zod";
|
|
1668
|
+
|
|
1669
|
+
// src/features/analysis/scm/shared/src/storedFixData/index.ts
|
|
1670
|
+
import { z as z6 } from "zod";
|
|
1671
|
+
|
|
1672
|
+
// src/features/analysis/scm/shared/src/storedFixData/passwordInComment.ts
|
|
1673
|
+
var passwordInComment = {
|
|
1674
|
+
guidance: () => "Removing sensitive information from the comments is not enough. To ensure the security of your data, you have to rotate passwords and tokens and update all places where they were used."
|
|
1675
|
+
};
|
|
1676
|
+
|
|
1677
|
+
// src/features/analysis/scm/shared/src/storedFixData/csharp/missingAntiForgeryValidation.ts
|
|
1678
|
+
var missingAntiForgeryValidation = {
|
|
1679
|
+
guidance: () => `The \`ValidateAntiForgeryToken\` attribute helps prevent cross-site request forgery (CSRF) attacks. The token is automatically injected into the view by the [FormTagHelper](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-8.0#the-form-tag-helper)
|
|
1680
|
+
and is included when the form is submitted by the user. The token is validated by the \`ValidateAntiForgeryToken\` attribute. The token could be also generated using the [Html.AntiForgeryToken](https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper.antiforgerytoken?view=aspnet-mvc-5.2) helper.
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
***Make sure this controller's client provides the validation token before approving this change.***
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
This is an illustration of how the form will look like:
|
|
1691
|
+
|
|
1692
|
+
|
|
1693
|
+
|
|
1694
|
+
<form method="post" action="/Action">
|
|
1695
|
+
<!-- Input and Submit elements -->
|
|
1696
|
+
<input name="__RequestVerificationToken"
|
|
1697
|
+
type="hidden" value="<removed for brevity>">
|
|
1698
|
+
</form>
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
***Notice the \`__RequestVerificationToken\` parameters.***
|
|
1702
|
+
`
|
|
1703
|
+
};
|
|
1704
|
+
|
|
1705
|
+
// src/features/analysis/scm/shared/src/storedFixData/csharp/index.ts
|
|
1706
|
+
var vulnerabilities = {
|
|
1707
|
+
["MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */]: missingAntiForgeryValidation,
|
|
1708
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: passwordInComment
|
|
1709
|
+
};
|
|
1710
|
+
var csharp_default = vulnerabilities;
|
|
1711
|
+
|
|
1712
|
+
// src/features/analysis/scm/shared/src/storedFixData/java/sqlInjection.ts
|
|
1713
|
+
var sqlInjection = {
|
|
1714
|
+
guidance: ({
|
|
1715
|
+
hasQuestionMarksAfterTaintVar
|
|
1716
|
+
}) => {
|
|
1717
|
+
if (hasQuestionMarksAfterTaintVar) {
|
|
1718
|
+
return "Please make sure to correct the following indices of the setInt()/setString() calls after the new parameter is added.";
|
|
1719
|
+
}
|
|
1720
|
+
return "";
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
|
|
1724
|
+
// src/features/analysis/scm/shared/src/storedFixData/java/systemInformationLeak.ts
|
|
1725
|
+
var systemInformationLeak = {
|
|
1726
|
+
guidance: ({
|
|
1727
|
+
clientMightBeAffected
|
|
1728
|
+
}) => {
|
|
1729
|
+
if (clientMightBeAffected) {
|
|
1730
|
+
return "You should never expose error details to the client. We removed the error details from the response. Ensure the client application code does not rely on the removed information.";
|
|
1731
|
+
}
|
|
1732
|
+
return "";
|
|
1733
|
+
}
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
// src/features/analysis/scm/shared/src/storedFixData/java/index.ts
|
|
1737
|
+
var vulnerabilities2 = {
|
|
1738
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: passwordInComment,
|
|
1739
|
+
["SQL_Injection" /* SqlInjection */]: sqlInjection,
|
|
1740
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: systemInformationLeak
|
|
1741
|
+
};
|
|
1742
|
+
var java_default = vulnerabilities2;
|
|
1743
|
+
|
|
1744
|
+
// src/features/analysis/scm/shared/src/storedFixData/javascript/hardcodedSecrets.ts
|
|
1745
|
+
var hardcodedSecrets = {
|
|
1746
|
+
guidance: ({ questions }) => {
|
|
1747
|
+
const envVarName = questions.find((q) => q.key === "env_var_name")?.value || "the";
|
|
1748
|
+
const keepAsDefault = questions.find(
|
|
1749
|
+
(q) => q.key === "keep_as_default"
|
|
1750
|
+
)?.value;
|
|
1751
|
+
let additionalText = "";
|
|
1752
|
+
if (keepAsDefault === "yes") {
|
|
1753
|
+
additionalText = "\n1. Remove the hardcoded secret from the code.\n";
|
|
1754
|
+
}
|
|
1755
|
+
return `Please follow the steps in this specific order:
|
|
1756
|
+
|
|
1757
|
+
1. Change the secret that was hardcoded. It is essential because even when you commit the changes, the secret will remain in the git history.${additionalText}
|
|
1758
|
+
1. Update the configuration of all your application environments and CI/CD pipelines to set \`${envVarName}\` environment variable.
|
|
1759
|
+
1. Commit the changes.`;
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1762
|
+
|
|
1763
|
+
// src/features/analysis/scm/shared/src/storedFixData/javascript/noLimitsOrThrottling.ts
|
|
1764
|
+
var noLimitsOrThrottling = {
|
|
1765
|
+
guidance: () => "We set the default limit to 60 requests per minute. To customize the rate limit settings, please read the documentation of the [express-rate-limit](https://www.npmjs.com/package/express-rate-limit) package."
|
|
1766
|
+
};
|
|
1767
|
+
|
|
1768
|
+
// src/features/analysis/scm/shared/src/storedFixData/javascript/ssrf.ts
|
|
1769
|
+
var ssrf = {
|
|
1770
|
+
guidance: () => "The server-side validates the domains it has access to, otherwise it throws an error if validation failed. Please make sure you handled the error correctly."
|
|
1771
|
+
};
|
|
1772
|
+
|
|
1773
|
+
// src/features/analysis/scm/shared/src/storedFixData/javascript/index.ts
|
|
1774
|
+
var vulnerabilities3 = {
|
|
1775
|
+
["SSRF" /* Ssrf */]: ssrf,
|
|
1776
|
+
["HARDCODED_SECRETS" /* HardcodedSecrets */]: hardcodedSecrets,
|
|
1777
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: passwordInComment,
|
|
1778
|
+
["NO_LIMITS_OR_THROTTLING" /* NoLimitsOrThrottling */]: noLimitsOrThrottling
|
|
1779
|
+
};
|
|
1780
|
+
var javascript_default = vulnerabilities3;
|
|
1781
|
+
|
|
1782
|
+
// src/features/analysis/scm/shared/src/storedFixData/python/autoEscapeFalse.ts
|
|
1783
|
+
var autoEscapeFalse = {
|
|
1784
|
+
guidance: () => `This fix enables automatic escaping for HTML. When that's enabled, everything is escaped by default except for values explicitly marked as safe. Variables and expressions can be marked as safe either in:
|
|
1785
|
+
|
|
1786
|
+
a. The context dictionary by the application with \`markupsafe.Markup\`
|
|
1787
|
+
|
|
1788
|
+
b. The template, with the \`|safe\` filter.
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
See more information [here](https://jinja.palletsprojects.com/en/3.1.x/templates/#working-with-automatic-escaping) and [here](https://pypi.org/project/MarkupSafe/).
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
***Note: make sure that none of the data you're marking as safe is coming from user input, as this can lead to XSS vulnerabilities!***`
|
|
1799
|
+
};
|
|
1800
|
+
|
|
1801
|
+
// src/features/analysis/scm/shared/src/storedFixData/python/index.ts
|
|
1802
|
+
var vulnerabilities4 = {
|
|
1803
|
+
["AUTO_ESCAPE_FALSE" /* AutoEscapeFalse */]: autoEscapeFalse
|
|
1804
|
+
};
|
|
1805
|
+
var python_default = vulnerabilities4;
|
|
1806
|
+
|
|
1807
|
+
// src/features/analysis/scm/shared/src/storedFixData/sql/defaultRightsInObjDefinition.ts
|
|
1808
|
+
var defaultRightsInObjDefinition = {
|
|
1809
|
+
guidance: () => "***Make sure the user who is supposed to run the procedure has sufficient permissions.***\n\nRead more details about the `EXECUTE AS` statement in [the official Microsoft documentation](https://learn.microsoft.com/en-us/sql/t-sql/statements/execute-as-clause-transact-sql?view=sql-server-ver16&tabs=sqlserver).\n\n`EXECUTE AS CALLER` is the default behavior for SQL Server 2005 and later."
|
|
1810
|
+
};
|
|
1811
|
+
|
|
1812
|
+
// src/features/analysis/scm/shared/src/storedFixData/sql/index.ts
|
|
1813
|
+
var vulnerabilities5 = {
|
|
1814
|
+
["DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */]: defaultRightsInObjDefinition
|
|
1815
|
+
};
|
|
1816
|
+
var sql_default = vulnerabilities5;
|
|
1817
|
+
|
|
1818
|
+
// src/features/analysis/scm/shared/src/storedFixData/xml/index.ts
|
|
1819
|
+
var vulnerabilities6 = {
|
|
1820
|
+
["PASSWORD_IN_COMMENT" /* PasswordInComment */]: passwordInComment
|
|
1821
|
+
};
|
|
1822
|
+
var xml_default = vulnerabilities6;
|
|
1823
|
+
|
|
1824
|
+
// src/features/analysis/scm/shared/src/storedFixData/index.ts
|
|
1825
|
+
var StoredFixDataItemZ = z6.object({
|
|
1826
|
+
guidance: z6.function().returns(z6.string())
|
|
1827
|
+
});
|
|
1828
|
+
var languages = {
|
|
1829
|
+
["Java" /* Java */]: java_default,
|
|
1830
|
+
["JavaScript" /* JavaScript */]: javascript_default,
|
|
1831
|
+
["CSharp" /* CSharp */]: csharp_default,
|
|
1832
|
+
["SQL" /* Sql */]: sql_default,
|
|
1833
|
+
["XML" /* Xml */]: xml_default,
|
|
1834
|
+
["Python" /* Python */]: python_default
|
|
1835
|
+
};
|
|
1836
|
+
|
|
1837
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/index.ts
|
|
1838
|
+
import { z as z7 } from "zod";
|
|
1839
|
+
|
|
1840
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/httpOnlyCookie.ts
|
|
1841
|
+
var httpOnlyCookie = {
|
|
1842
|
+
httpOnlyCookie: {
|
|
1843
|
+
content: () => "Is the cookie value supposed to be exposed to client-side scripting code?",
|
|
1844
|
+
description: () => httpOnlyMessage,
|
|
1845
|
+
guidance: () => ""
|
|
1846
|
+
},
|
|
1847
|
+
cookieVarName: {
|
|
1848
|
+
content: () => "Please define a variable name",
|
|
1849
|
+
description: () => `We need a variable for the new cookie instance`,
|
|
1850
|
+
guidance: () => ""
|
|
1851
|
+
}
|
|
1852
|
+
};
|
|
1853
|
+
var httpOnlyMessage = `\`HttpOnly\` is a security feature for cookies that can be set by a web server
|
|
1854
|
+
when sending a Set-Cookie header in an HTTP response. When the HTTP Only flag is set for a cookie, it means that the cookie can only
|
|
1855
|
+
be accessed and modified by the server, and client-side scripts (like JavaScript) running in the browser are not allowed to access the cookie.
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
***If your client-site application needs to access the value of this cookie, making this change might break the application logic.***
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
`;
|
|
1865
|
+
|
|
1866
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/insecureBinderConfiguration.ts
|
|
1867
|
+
var insecureBinderConfiguration = {
|
|
1868
|
+
bindAttributeParam: {
|
|
1869
|
+
content: ({ func_param_name }) => `Which properties of the model should be included in model binding for \`${func_param_name}\`?`,
|
|
1870
|
+
description: () => "Provide a comma-separated list of valid property names to be included in model binding. See [the official documentation](https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-8.0#bind-attribute) for more details.",
|
|
1871
|
+
guidance: () => ""
|
|
1872
|
+
}
|
|
1873
|
+
};
|
|
1874
|
+
|
|
1875
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/insecureCookie.ts
|
|
1876
|
+
var insecureCookie = {
|
|
1877
|
+
insecureCookie: {
|
|
1878
|
+
content: () => "Will this cookie be used only in encrypted channels (https)?",
|
|
1879
|
+
description: () => `When a cookie is marked as "secure" in a web environment, it means that the cookie should only be sent over secure, encrypted connections, like HTTPS.
|
|
1880
|
+
In environments like local development or test, setting cookies as secure might have some consequences:
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
- Development Convenience: When developing locally, you might not always have HTTPS set up, as it often involves
|
|
1884
|
+
additional configuration and certificates. If cookies are marked as secure,
|
|
1885
|
+
they won't be sent over HTTP, and this could potentially interfere with the normal
|
|
1886
|
+
functioning of your application during development.
|
|
1887
|
+
|
|
1888
|
+
|
|
1889
|
+
- Testing for Secure Environments: If your application relies on secure cookies, you should ensure that your
|
|
1890
|
+
testing environment accurately simulates the production environment's security features.
|
|
1891
|
+
This may involve setting up HTTPS in your local development environment.
|
|
1892
|
+
|
|
1893
|
+
|
|
1894
|
+
- Debugging Challenges: Debugging may be more challenging when using secure cookies in a
|
|
1895
|
+
development environment, especially if you need to inspect or manipulate the cookies during
|
|
1896
|
+
development.`,
|
|
1897
|
+
guidance: () => ""
|
|
1898
|
+
},
|
|
1899
|
+
cookieVarName: {
|
|
1900
|
+
content: () => "Please define a variable name",
|
|
1901
|
+
description: () => `We need a variable for the new cookie instance`,
|
|
1902
|
+
guidance: () => ""
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1906
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/insecureRandomness.ts
|
|
1907
|
+
var insecureRandomness = {
|
|
1908
|
+
isRandomNumberGeneratorAvailable: {
|
|
1909
|
+
content: () => "We use the `RandomNumberGenerator` class from the `System.Security.Cryptography` package. Does this class exist for the .NET version you use?",
|
|
1910
|
+
description: () => "See [the official documentation](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator?view=net-8.0#applies-to) for more details.",
|
|
1911
|
+
guidance: () => ""
|
|
1912
|
+
}
|
|
1913
|
+
};
|
|
1914
|
+
|
|
1915
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/insufficientLogging.ts
|
|
1916
|
+
var insufficientLogging = {
|
|
1917
|
+
logMessage: {
|
|
1918
|
+
content: () => "Enter the message that you want to appear in the log",
|
|
1919
|
+
description: () => "",
|
|
1920
|
+
guidance: () => ""
|
|
1921
|
+
}
|
|
1922
|
+
};
|
|
1923
|
+
|
|
1924
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/logForging.ts
|
|
1925
|
+
var logForging = {
|
|
1926
|
+
isHtmlDisplay: {
|
|
1927
|
+
content: () => "Is the text written to the log going to be displayed as HTML?",
|
|
1928
|
+
description: () => "",
|
|
1929
|
+
guidance: ({ userInputValue }) => {
|
|
1930
|
+
switch (userInputValue) {
|
|
1931
|
+
case "yes":
|
|
1932
|
+
return "We use the `System.Web` `HttpUtility` to decode the HTML";
|
|
1933
|
+
default:
|
|
1934
|
+
return "";
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1939
|
+
|
|
1940
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/overlyBroadCatch.ts
|
|
1941
|
+
var overlyBroadCatch = {
|
|
1942
|
+
defaultExceptionsInWhenFilter: {
|
|
1943
|
+
content: () => "Exceptions to filter",
|
|
1944
|
+
description: () => "Coma separated list of the Fully Qualified Exceptions names",
|
|
1945
|
+
guidance: () => ""
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
|
|
1949
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/pt.ts
|
|
1950
|
+
var pt = {
|
|
1951
|
+
taintedTermType: {
|
|
1952
|
+
content: ({ expression }) => `Does \`${expression}\` represent a file name or a file path?`,
|
|
1953
|
+
description: ({ expression }) => `We replace all illegal file name characters for Unix, Windows, and macOS operation systems, including slashes. Ensure that \`${expression}\` isn't supposed to contain slashes or other illegal file name characters.`,
|
|
1954
|
+
guidance: () => ""
|
|
1955
|
+
},
|
|
1956
|
+
pathTargetDir: {
|
|
1957
|
+
content: () => "Allowed file path",
|
|
1958
|
+
description: () => "Provide the intended file path destination eg: /tmp/testfiles/users/",
|
|
1959
|
+
guidance: () => ""
|
|
1960
|
+
}
|
|
1961
|
+
};
|
|
1962
|
+
|
|
1963
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/ssrf.ts
|
|
1964
|
+
var ssrf2 = {
|
|
1965
|
+
domainsAllowlist: {
|
|
1966
|
+
content: () => "Allowed domains",
|
|
1967
|
+
description: () => "Coma separated list of allowed domains.",
|
|
1968
|
+
guidance: () => ""
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
|
|
1972
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/sysLeak.ts
|
|
1973
|
+
var sysLeak = {
|
|
1974
|
+
errorMessage: {
|
|
1975
|
+
content: () => "Enter the error message that you want to appear in the log",
|
|
1976
|
+
description: () => "",
|
|
1977
|
+
guidance: () => ""
|
|
1978
|
+
},
|
|
1979
|
+
noLoggerAction: {
|
|
1980
|
+
content: () => "Which of the following you want to use instead of the vulnerable code?",
|
|
1981
|
+
description: () => "",
|
|
1982
|
+
guidance: () => ""
|
|
1983
|
+
}
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/trustBoundaryViolation.ts
|
|
1987
|
+
var trustBoundaryViolation = {
|
|
1988
|
+
validationPattern: {
|
|
1989
|
+
content: ({ expression }) => `What is the expected type of \`${expression}\`?`,
|
|
1990
|
+
description: () => "We use regex to validate the input to avoid runtime surprises",
|
|
1991
|
+
guidance: () => ""
|
|
1992
|
+
},
|
|
1993
|
+
otherPatternValue: {
|
|
1994
|
+
content: () => `Enter the regex pattern you would like to use to validate the input`,
|
|
1995
|
+
description: () => "See patterns at [the regex docs](https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference)",
|
|
1996
|
+
guidance: () => ""
|
|
1997
|
+
}
|
|
1998
|
+
};
|
|
1999
|
+
|
|
2000
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/useOfSystemOutputStream.ts
|
|
2001
|
+
var useOfSystemOutputStream = {
|
|
2002
|
+
noLoggerAction: {
|
|
2003
|
+
content: () => "Which of the following you want to use instead of the vulnerable code?",
|
|
2004
|
+
description: () => "",
|
|
2005
|
+
guidance: () => ""
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
2008
|
+
|
|
2009
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/valueShadowing.ts
|
|
2010
|
+
var valueShadowing = {
|
|
2011
|
+
collectionName: {
|
|
2012
|
+
content: () => "Please select the collection to search/index from",
|
|
2013
|
+
description: () => `Accessing the root object eg Request["item"] searches across all available collections and returns the first item that matches. Potentially leading to the correct value being shadowed. Available collections include:
|
|
2014
|
+
- QueryString: The values of variables in the HTTP query string.
|
|
2015
|
+
- Form: The values of form elements in the HTTP request body.
|
|
2016
|
+
- Cookies: The values of cookies sent in the HTTP request.
|
|
2017
|
+
- ClientCertificate: The values of fields stored in the client certificate that is sent in the HTTP request.
|
|
2018
|
+
- ServerVariables: The values of predetermined environment variables.`,
|
|
2019
|
+
guidance: () => `See
|
|
2020
|
+
- https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524948(v=vs.90),
|
|
2021
|
+
- https://learn.microsoft.com/en-us/dotnet/api/system.web.httprequest?view=netframework-4.8.1`
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2024
|
+
|
|
2025
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/wcfMisconfigurationThrottlingNotEnabled.ts
|
|
2026
|
+
var wcfMisconfigurationThrottlingNotEnabled = {
|
|
2027
|
+
maxConcurrentCalls: {
|
|
2028
|
+
content: () => "Please define the maximum concurrent calls",
|
|
2029
|
+
description: () => `A positive integer that limits the number of messages that currently process across a ServiceHost. Calls in excess of the limit are queued. Setting this value to 0 is equivalent to setting it to Int32.MaxValue.`,
|
|
2030
|
+
guidance: () => {
|
|
2031
|
+
return "";
|
|
2032
|
+
}
|
|
2033
|
+
},
|
|
2034
|
+
maxConcurrentInstances: {
|
|
2035
|
+
content: () => "Please define the maximum concurrent instances",
|
|
2036
|
+
description: () => `A positive integer that limits the number of InstanceContext objects that execute at one time across a ServiceHost. Requests to create additional instances are queued and complete when a slot below the limit becomes available.`,
|
|
2037
|
+
guidance: () => {
|
|
2038
|
+
return "";
|
|
2039
|
+
}
|
|
2040
|
+
},
|
|
2041
|
+
maxConcurrentSessions: {
|
|
2042
|
+
content: () => "Please define the maximum concurrent sessions",
|
|
2043
|
+
description: () => `A positive integer that limits the number of sessions a ServiceHost object can accept.`,
|
|
2044
|
+
guidance: () => {
|
|
2045
|
+
return "";
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
};
|
|
2049
|
+
|
|
2050
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/xss.ts
|
|
2051
|
+
var xss = {
|
|
2052
|
+
allowSpecialCharacters: {
|
|
2053
|
+
content: ({ source_value }) => `Does your code allow encodable HTML characters like '&', '<', '"' etc. in: \`${source_value}\`?`,
|
|
2054
|
+
description: () => "",
|
|
2055
|
+
guidance: () => ""
|
|
2056
|
+
},
|
|
2057
|
+
containsHtml: {
|
|
2058
|
+
content: ({ prop_value }) => `Does your code allow having HTML tags in: \`${prop_value}\`?`,
|
|
2059
|
+
description: () => "",
|
|
2060
|
+
guidance: () => ""
|
|
2061
|
+
},
|
|
2062
|
+
netVersionGreaterOrEqual45: {
|
|
2063
|
+
content: () => "Is your target framework .NET 4.5 or greater?",
|
|
2064
|
+
description: () => "",
|
|
2065
|
+
guidance: () => ""
|
|
2066
|
+
},
|
|
2067
|
+
useHTML4NamedEntities: {
|
|
2068
|
+
content: () => "Would you like to use HTML 4.0 Named entities?",
|
|
2069
|
+
description: () => "See [examples](https://www.w3schools.com/charsets/ref_html_entities_4.asp) and [full description](https://www.w3.org/TR/WD-html40-970708/sgml/entities.html)",
|
|
2070
|
+
guidance: () => ""
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
|
|
2074
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/xxe.ts
|
|
2075
|
+
var xxe = {
|
|
2076
|
+
netVersionGreaterOrEqual4: {
|
|
2077
|
+
content: () => "Is your target framework .NET 4.0.0 or greater?",
|
|
2078
|
+
description: () => "",
|
|
2079
|
+
guidance: ({ userInputValue }) => {
|
|
2080
|
+
switch (userInputValue) {
|
|
2081
|
+
case "yes":
|
|
2082
|
+
return "We set `DtdProcessing` to `DtdProcessing.Prohibit` in order to prevent DTD parsing.";
|
|
2083
|
+
default:
|
|
2084
|
+
return "We set `ProhibitDtd` to `true` in order to prevent DTD parsing.";
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
};
|
|
2089
|
+
|
|
2090
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/csharp/index.ts
|
|
2091
|
+
var vulnerabilities7 = {
|
|
2092
|
+
["LOG_FORGING" /* LogForging */]: logForging,
|
|
2093
|
+
["SSRF" /* Ssrf */]: ssrf2,
|
|
2094
|
+
["XXE" /* Xxe */]: xxe,
|
|
2095
|
+
["XSS" /* Xss */]: xss,
|
|
2096
|
+
["USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */]: useOfSystemOutputStream,
|
|
2097
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: sysLeak,
|
|
2098
|
+
["OVERLY_BROAD_CATCH" /* OverlyBroadCatch */]: overlyBroadCatch,
|
|
2099
|
+
["TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */]: trustBoundaryViolation,
|
|
2100
|
+
["PT" /* Pt */]: pt,
|
|
2101
|
+
["HTTP_ONLY_COOKIE" /* HttpOnlyCookie */]: httpOnlyCookie,
|
|
2102
|
+
["INSECURE_COOKIE" /* InsecureCookie */]: insecureCookie,
|
|
2103
|
+
["WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */]: wcfMisconfigurationThrottlingNotEnabled,
|
|
2104
|
+
["INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */]: insecureBinderConfiguration,
|
|
2105
|
+
["VALUE_SHADOWING" /* ValueShadowing */]: valueShadowing,
|
|
2106
|
+
["INSECURE_RANDOMNESS" /* InsecureRandomness */]: insecureRandomness,
|
|
2107
|
+
["INSUFFICIENT_LOGGING" /* InsufficientLogging */]: insufficientLogging
|
|
2108
|
+
};
|
|
2109
|
+
var csharp_default2 = vulnerabilities7;
|
|
2110
|
+
|
|
2111
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/commandInjection.ts
|
|
2112
|
+
var commandInjection = {
|
|
2113
|
+
isUnixShellCommandPart: {
|
|
2114
|
+
content: () => "Is the input part of Unix shell command?",
|
|
2115
|
+
description: () => `For example:
|
|
2116
|
+
|
|
2117
|
+
- \`Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", "ping -t 5 -c 5 " + input});\`
|
|
2118
|
+
- \`Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", "curl " + input + " > file.txt"});\`
|
|
2119
|
+
|
|
2120
|
+
Make sure the input is not:
|
|
2121
|
+
|
|
2122
|
+
1. An executable name:
|
|
2123
|
+
- \`Runtime.getRuntime().exec(input);\`
|
|
2124
|
+
- \`Runtime.getRuntime().exec(new String[] {"/bin/bash", input});\`
|
|
2125
|
+
- \`Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", input + " param"});\`
|
|
2126
|
+
- \`Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", "cat file.txt | " + input});\`
|
|
2127
|
+
- \`Runtime.getRuntime().exec(new String[] {"/usr/bin/git", "--upload-pack", input});\`
|
|
2128
|
+
2. A part of non-unix or cross platform shell command:
|
|
2129
|
+
- \`Runtime.getRuntime().exec(new String[] {"cmd.exe", "/c", "ping " + input});\`
|
|
2130
|
+
3. A part of programming language code:
|
|
2131
|
+
- \`Runtime.getRuntime().exec(new String[] {"php", "-r", "echo '" + input + "';"});\`
|
|
2132
|
+
- \`Runtime.getRuntime().exec(new String[] {"perl", "-e", "print '" + input + "'"});\``,
|
|
2133
|
+
guidance: () => ""
|
|
2134
|
+
},
|
|
2135
|
+
isPlainCommandArgument: {
|
|
2136
|
+
content: () => "Is the input an argument of a plain command?",
|
|
2137
|
+
description: () => `Examples for "yes" answer:
|
|
2138
|
+
|
|
2139
|
+
- \`Runtime.getRuntime().exec("git clone " + input);\`
|
|
2140
|
+
- \`Runtime.getRuntime().exec("curl " + input);\`
|
|
2141
|
+
- \`Runtime.getRuntime().exec("cat " + input);\`
|
|
2142
|
+
|
|
2143
|
+
Examples for "no" answer:
|
|
2144
|
+
|
|
2145
|
+
- \`Runtime.getRuntime().exec("cmd /c " + input);\`
|
|
2146
|
+
- \`Runtime.getRuntime().exec("sh -c " + input);\`
|
|
2147
|
+
- \`Runtime.getRuntime().exec("perl -e " + input);\``,
|
|
2148
|
+
guidance: () => ""
|
|
2149
|
+
},
|
|
2150
|
+
installApacheCommonsText: {
|
|
2151
|
+
content: () => "Is the Apache Commons library (org.apache.commons) included in your project, if not, can you add it?",
|
|
2152
|
+
description: () => "Apache Commons Text is a library focused on algorithms working on strings.",
|
|
2153
|
+
guidance: ({ userInputValue }) => userInputValue === "yes" ? "To add the library, modify your pom.xml or build.gradle to include the library. You can find the latest version here https://mvnrepository.com/artifact/org.apache.commons/commons-text" : ""
|
|
2154
|
+
},
|
|
2155
|
+
cmdAllowlist: {
|
|
2156
|
+
content: () => "Allowed Commands",
|
|
2157
|
+
description: () => "Make sure that the list of commands is separated by commas.",
|
|
2158
|
+
guidance: () => ""
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
|
|
2162
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/confusingNaming.ts
|
|
2163
|
+
var confusingNaming = {
|
|
2164
|
+
newFieldName: {
|
|
2165
|
+
content: () => "Rename the existing field",
|
|
2166
|
+
description: () => "",
|
|
2167
|
+
guidance: () => ""
|
|
2168
|
+
}
|
|
2169
|
+
};
|
|
2170
|
+
|
|
2171
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/erroneousStringCompare.ts
|
|
2172
|
+
var erroneousStringCompare = {
|
|
2173
|
+
javaVersionGreaterOrEqual17: {
|
|
2174
|
+
content: () => "Is `java.util.Objects` package available in your runtime?",
|
|
2175
|
+
description: () => "`java.util.Objects` is supported in Java 1.7 or greater.",
|
|
2176
|
+
guidance: () => ""
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
|
|
2180
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/errorConditionWithoutAction.ts
|
|
2181
|
+
var errorConditionWithoutAction = {
|
|
2182
|
+
errorMessage: {
|
|
2183
|
+
content: () => "Enter the error message that you want to appear in the log",
|
|
2184
|
+
description: () => "",
|
|
2185
|
+
guidance: () => ""
|
|
2186
|
+
}
|
|
2187
|
+
};
|
|
2188
|
+
|
|
2189
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/httpOnlyCookie.ts
|
|
2190
|
+
var httpOnlyCookie2 = {
|
|
2191
|
+
httpOnlyCookie: {
|
|
2192
|
+
content: () => "Is the cookie value supposed to be exposed to client-side scripting code?",
|
|
2193
|
+
description: ({ class_name }) => class_name == "Cookie" ? `${httpOnlyMessage2} ${setHttpOnlyMethodMessage}` : httpOnlyMessage2,
|
|
2194
|
+
guidance: () => ""
|
|
2195
|
+
},
|
|
2196
|
+
cookieVarName: {
|
|
2197
|
+
content: () => "Please define a variable name",
|
|
2198
|
+
description: () => `We need a variable for the new cookie instance`,
|
|
2199
|
+
guidance: () => ""
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
var httpOnlyMessage2 = `\`HttpOnly\` is a security feature for cookies that can be set by a web server
|
|
2203
|
+
when sending a Set-Cookie header in an HTTP response. When the HTTP Only flag is set for a cookie, it means that the cookie can only
|
|
2204
|
+
be accessed and modified by the server, and client-side scripts (like JavaScript) running in the browser are not allowed to access the cookie.
|
|
2205
|
+
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
|
|
2209
|
+
***If your client-site application needs to access the value of this cookie, making this change might break the application logic.***
|
|
2210
|
+
|
|
2211
|
+
|
|
2212
|
+
|
|
2213
|
+
`;
|
|
2214
|
+
var setHttpOnlyMethodMessage = `Beware that if your application is using a version of the javax.servlet-api package < 3.0
|
|
2215
|
+
this change will not work since the method "setHttpOnly" is not present in previous of the package.`;
|
|
2216
|
+
|
|
2217
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/insecureCookie.ts
|
|
2218
|
+
var insecureCookie2 = {
|
|
2219
|
+
insecureCookie: {
|
|
2220
|
+
content: () => "Will this cookie be used only in encrypted channels (https)?",
|
|
2221
|
+
description: () => `When a cookie is marked as "secure" in a web environment, it means that the cookie should only be sent over secure, encrypted connections, like HTTPS.
|
|
2222
|
+
In environments like local development or test, setting cookies as secure might have some consequences:
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
- Development Convenience: When developing locally, you might not always have HTTPS set up, as it often involves
|
|
2226
|
+
additional configuration and certificates. If cookies are marked as secure,
|
|
2227
|
+
they won't be sent over HTTP, and this could potentially interfere with the normal
|
|
2228
|
+
functioning of your application during development.
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
- Testing for Secure Environments: If your application relies on secure cookies, you should ensure that your
|
|
2232
|
+
testing environment accurately simulates the production environment's security features.
|
|
2233
|
+
This may involve setting up HTTPS in your local development environment.
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
- Debugging Challenges: Debugging may be more challenging when using secure cookies in a
|
|
2237
|
+
development environment, especially if you need to inspect or manipulate the cookies during
|
|
2238
|
+
development.`,
|
|
2239
|
+
guidance: () => ""
|
|
2240
|
+
},
|
|
2241
|
+
cookieVarName: {
|
|
2242
|
+
content: () => "Please define a variable name",
|
|
2243
|
+
description: () => `We need a variable for the new cookie instance`,
|
|
2244
|
+
guidance: () => ""
|
|
2245
|
+
}
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2248
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/leftoverDebugCode.ts
|
|
2249
|
+
var leftoverDebugCode = {
|
|
2250
|
+
isCodeUsed: {
|
|
2251
|
+
content: () => "The function seems to be a remnant of debug code. Is it still being used?",
|
|
2252
|
+
description: () => "",
|
|
2253
|
+
guidance: () => ""
|
|
2254
|
+
}
|
|
2255
|
+
};
|
|
2256
|
+
|
|
2257
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/localeDependentComparison.ts
|
|
2258
|
+
var localeDependentComparison = {
|
|
2259
|
+
localeType: {
|
|
2260
|
+
content: ({ variable }) => `Is ${variable} locale dependent?`,
|
|
2261
|
+
description: () => `Select "locale insensitive" for string comparisons that are not dependent on the locale.
|
|
2262
|
+
|
|
2263
|
+
Select "default locale" for string comparisons that uses the default locale.
|
|
2264
|
+
|
|
2265
|
+
Select "custom locale" for string comparisons that are dependent on a specific locale language.`,
|
|
2266
|
+
guidance: () => ""
|
|
2267
|
+
},
|
|
2268
|
+
customLocaleLanguage: {
|
|
2269
|
+
content: () => "What is your locale language?",
|
|
2270
|
+
description: () => "A list of locales can be found [here](https://www.oracle.com/java/technologies/javase/jdk8-jre8-suported-locales.html)",
|
|
2271
|
+
guidance: () => ""
|
|
2272
|
+
},
|
|
2273
|
+
customLocaleCountry: {
|
|
2274
|
+
content: () => "What is your locale country?",
|
|
2275
|
+
description: () => "A list of locales can be found [here](https://www.oracle.com/java/technologies/javase/jdk8-jre8-suported-locales.html)",
|
|
2276
|
+
guidance: () => ""
|
|
2277
|
+
}
|
|
2278
|
+
};
|
|
2279
|
+
|
|
2280
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/logForging.ts
|
|
2281
|
+
var logForging2 = {
|
|
2282
|
+
isHtmlDisplay: {
|
|
2283
|
+
content: () => "Is the text written to the log going to be displayed as HTML?",
|
|
2284
|
+
description: () => "",
|
|
2285
|
+
guidance: () => ""
|
|
2286
|
+
},
|
|
2287
|
+
htmlEscapingLib: {
|
|
2288
|
+
content: () => "Which HTML escaping library would you like to use?",
|
|
2289
|
+
description: () => `
|
|
2290
|
+
- If you use the Spring framework, you likely already have \`org.springframework.web.util.HtmlUtils\`
|
|
2291
|
+
- Another \`option is org.apache.commons.text.StringEscapeUtils\``,
|
|
2292
|
+
guidance: () => ""
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
|
|
2296
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/missingCheckAgainstNull.ts
|
|
2297
|
+
var missingCheckAgainstNull = {
|
|
2298
|
+
preferredAction: {
|
|
2299
|
+
content: ({ tainted_expression }) => `What is expected behavior if \`${tainted_expression}\` returns null?`,
|
|
2300
|
+
description: () => "",
|
|
2301
|
+
guidance: () => ""
|
|
2302
|
+
},
|
|
2303
|
+
javaVersionGreaterOrEqual17: {
|
|
2304
|
+
content: () => "Is `java.util.Objects` package available in your runtime?",
|
|
2305
|
+
description: () => "`java.util.Objects` is supported in Java 1.7 or greater.",
|
|
2306
|
+
guidance: () => ""
|
|
2307
|
+
}
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/overlyBroadCatch.ts
|
|
2311
|
+
var overlyBroadCatch2 = {
|
|
2312
|
+
handleRuntimeExceptions: {
|
|
2313
|
+
content: () => "Does the code intentionally catch `RuntimeException` instances like `ArithmeticException` or `NullPointerException` in the `catch` block?",
|
|
2314
|
+
description: () => "Usually, when catching the general `Exception` class catching of `RuntimeException` is implied and not necessarily the wanted/safe behavior. The application needs to deal with it explicitly in a different way, as the Mobb fix suggests.",
|
|
2315
|
+
guidance: () => ""
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
|
|
2319
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/privacyViolation.ts
|
|
2320
|
+
var privacyViolation = {
|
|
2321
|
+
remediation_option: {
|
|
2322
|
+
content: () => "Preferred fix solution",
|
|
2323
|
+
description: () => `
|
|
2324
|
+
- Completely Remove the log message
|
|
2325
|
+
- Replace the sensitive data with the string [Redacted]
|
|
2326
|
+
- SHA 256 Hash the sensitive information in the log message`,
|
|
2327
|
+
guidance: () => ""
|
|
2328
|
+
}
|
|
2329
|
+
};
|
|
2330
|
+
|
|
2331
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/pt.ts
|
|
2332
|
+
var pt2 = {
|
|
2333
|
+
isPathRelativeOnly: {
|
|
2334
|
+
content: ({ expression }) => `Do you expect \`${expression}\` to be a relative path?`,
|
|
2335
|
+
description: () => "You most likely want to serve files relative to the web server's static files folder in web applications. If so, your answer should be `yes`. In CLI applications, you probably would like to give the user more flexibility and allow them to specify absolute paths to any location on the disk \u2013 your answer should be `no` in such cases.",
|
|
2336
|
+
guidance: () => ""
|
|
2337
|
+
},
|
|
2338
|
+
isFileName: {
|
|
2339
|
+
content: ({ expression }) => `Does \`${expression}\` represent a file name or a file name part?`,
|
|
2340
|
+
description: ({ expression }) => `We replace all illegal file name characters for Unix, Windows, and macOS operation systems, including slashes. Ensure that \`${expression}\` isn't supposed to contain slashes or other illegal file name characters. If \`${expression}\` is supposed to legitimately include such characters, the answer should be "no".`,
|
|
2341
|
+
guidance: () => ""
|
|
2342
|
+
}
|
|
2343
|
+
};
|
|
2344
|
+
|
|
2345
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/relativePathCommand.ts
|
|
2346
|
+
var relativePathCommand = {
|
|
2347
|
+
executableLocationPath: {
|
|
2348
|
+
content: () => "What is the absolute path of the directory containing the executable?",
|
|
2349
|
+
description: () => "We need the absolute path to the executable to protect your application from command injection and ensure malicious actors cannot execute arbitrary commands on your system.",
|
|
2350
|
+
guidance: () => ""
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
|
|
2354
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/sqlInjection.ts
|
|
2355
|
+
function capitalizeFirstLetter2(item) {
|
|
2356
|
+
return item.charAt(0).toUpperCase() + item.slice(1);
|
|
2357
|
+
}
|
|
2358
|
+
var typeToSetMethod = {
|
|
2359
|
+
integer: "setInt",
|
|
2360
|
+
date: "setDate",
|
|
2361
|
+
string: "setString"
|
|
2362
|
+
};
|
|
2363
|
+
var sqlInjection2 = {
|
|
2364
|
+
parameterType: {
|
|
2365
|
+
content: ({ tainted_term }) => `What is the SQL Data Type of the \`${tainted_term}\` parameter?`,
|
|
2366
|
+
description: () => "In order to make sure the statement is built correctly, we must ensure we use the same type that is defined for this parameter in the SQL table. If you are unsure of this type, please consult with your team.",
|
|
2367
|
+
guidance: ({
|
|
2368
|
+
tainted_term,
|
|
2369
|
+
taint_var_type_guidance_required,
|
|
2370
|
+
userInputValue
|
|
2371
|
+
}) => {
|
|
2372
|
+
if (!taint_var_type_guidance_required || !userInputValue) {
|
|
2373
|
+
return "";
|
|
2374
|
+
}
|
|
2375
|
+
if (!taint_var_type_guidance_required[userInputValue]) {
|
|
2376
|
+
return "";
|
|
2377
|
+
}
|
|
2378
|
+
return `Make sure to convert \`${tainted_term}\` to \`${capitalizeFirstLetter2(
|
|
2379
|
+
userInputValue
|
|
2380
|
+
)}\` which is the type expected by the new setter method: \`${typeToSetMethod[userInputValue]}\``;
|
|
2381
|
+
}
|
|
2382
|
+
},
|
|
2383
|
+
varName: {
|
|
2384
|
+
content: () => "Name the new PreparedStatement variable",
|
|
2385
|
+
description: () => "We needed to create a new variable for this fix. We actually like the name we picked, but maybe you follow different naming conventions, so you can change it here.",
|
|
2386
|
+
guidance: () => ""
|
|
2387
|
+
},
|
|
2388
|
+
taintIndex: {
|
|
2389
|
+
content: ({ tainted_term }) => `What is the index of \`\`\`${tainted_term}\`\`\` in the query?`,
|
|
2390
|
+
description: () => "When constructing a query, we need to know exactly where to insert this parameter. If the query has more than one parameter, the index gives us this information. Leave the value as 1 if there is only one parameter.",
|
|
2391
|
+
guidance: () => ""
|
|
2392
|
+
},
|
|
2393
|
+
statementAfterQuery: {
|
|
2394
|
+
content: ({ var_name }) => `Is the \`Statement\` variable \`${var_name}\` declared after constructing the query string?`,
|
|
2395
|
+
description: () => "When creating the `PreparedStatement` parameter, we need to give it the constructed query. Currently, Mobb doesn't support the case where the query string is defined after the statement in your code.",
|
|
2396
|
+
guidance: ({ userInputValue }) => userInputValue === "no" ? "You should move the code creating the query so it is executed before being used by the prepared statement" : ""
|
|
2397
|
+
},
|
|
2398
|
+
statementBeforeQuery: {
|
|
2399
|
+
content: ({ var_name }) => `Is the query string variable declared after the \`Statement\` variable \`${var_name}\`?`,
|
|
2400
|
+
description: ({ enquote_func_name }) => `We need to have the \`Statement\` object defined before using the \`${enquote_func_name}()\` method. Currently, Mobb doesn't support the case where the query string is defined before the statement in your code.`,
|
|
2401
|
+
guidance: ({
|
|
2402
|
+
userInputValue,
|
|
2403
|
+
enquote_func_name
|
|
2404
|
+
}) => userInputValue === "no" ? `You should move the code creating the query so it is executed after creating the \`Statement\` object as we need to have the \`Statement\` object defined before using the \`${enquote_func_name}()\` method.` : ""
|
|
2405
|
+
},
|
|
2406
|
+
containsControlCharacters: {
|
|
2407
|
+
content: ({ tainted_term }) => `Does \`\`\`${tainted_term}\`\`\` represent a single SQL parameter value?`,
|
|
2408
|
+
description: () => `This should be 'no' only in the rare cases where the input variable itself does not represent a single SQL parameter value but rather other parts of a SQL query such as a table name, a column name, a list of values, a complete or partial inner SQL statement, etc.
|
|
2409
|
+
|
|
2410
|
+
It may be confusing a bit, so here are some examples:
|
|
2411
|
+
|
|
2412
|
+
* A SQL identifier \`\`\`(SELECT * FROM \${tableName})\`\`\`
|
|
2413
|
+
|
|
2414
|
+
* A SQL statement \`\`\`(SELECT * FROM users ORDER BY id \${order})\`\`\``,
|
|
2415
|
+
guidance: () => ""
|
|
2416
|
+
},
|
|
2417
|
+
javaVersionGreaterOrEqual19: {
|
|
2418
|
+
content: ({ enquote_func_name }) => `Is \`java.sql.Statement.${enquote_func_name}\` method available in your runtime?`,
|
|
2419
|
+
description: ({ enquote_func_name }) => `\`java.sql.Statement.${enquote_func_name}\` is supported in Java 1.9 or greater.`,
|
|
2420
|
+
guidance: () => ""
|
|
2421
|
+
},
|
|
2422
|
+
queryParameterName: {
|
|
2423
|
+
content: () => "What should be the name of the query parameter?",
|
|
2424
|
+
description: () => "",
|
|
2425
|
+
guidance: () => ""
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
|
|
2429
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/ssrf.ts
|
|
2430
|
+
var ssrf3 = {
|
|
2431
|
+
domainsAllowlist: {
|
|
2432
|
+
content: () => "Allowed URL prefixes",
|
|
2433
|
+
description: () => `The security risk of this issue is the ability of an attacker to provide input that shoots HTTP requests from your server to arbitrary URLs, including internal ones, like \`https://admin.mycompany.com\`
|
|
2434
|
+
|
|
2435
|
+
To eliminate the risk and fix the issue, check out your app logic and make a whitelist of URLs this API should be allowed to call.`,
|
|
2436
|
+
guidance: () => ""
|
|
2437
|
+
}
|
|
2438
|
+
};
|
|
2439
|
+
|
|
2440
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/sysLeak.ts
|
|
2441
|
+
var sysLeak2 = {
|
|
2442
|
+
errorMessage: {
|
|
2443
|
+
content: () => "Enter the error message that you want to appear in the log",
|
|
2444
|
+
description: () => "",
|
|
2445
|
+
guidance: () => ""
|
|
2446
|
+
},
|
|
2447
|
+
noLoggerAction: {
|
|
2448
|
+
content: () => "Which of the following you want to use instead of the vulnerable code?",
|
|
2449
|
+
description: () => "",
|
|
2450
|
+
guidance: () => ""
|
|
2451
|
+
}
|
|
2452
|
+
};
|
|
2453
|
+
|
|
2454
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/trustBoundaryViolation.ts
|
|
2455
|
+
var trustBoundaryViolation2 = {
|
|
2456
|
+
validationPattern: {
|
|
2457
|
+
content: ({ expression }) => `What is the expected type of \`${expression}\`?`,
|
|
2458
|
+
description: () => "We use regex to validate the input to avoid runtime surprises",
|
|
2459
|
+
guidance: () => ""
|
|
2460
|
+
},
|
|
2461
|
+
otherPatternValue: {
|
|
2462
|
+
content: () => `Enter the regex pattern you would like to use to validate the input`,
|
|
2463
|
+
description: () => "See patterns at [the regex javadoc](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html)",
|
|
2464
|
+
guidance: () => ""
|
|
2465
|
+
}
|
|
2466
|
+
};
|
|
2467
|
+
|
|
2468
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/uncheckedLoopCondition.ts
|
|
2469
|
+
var uncheckedLoopCondition = {
|
|
2470
|
+
loopLimit: {
|
|
2471
|
+
content: () => "Please define a maximum loop limit",
|
|
2472
|
+
description: () => `Setting this number to a reasonable value will prevent the vulnerability`,
|
|
2473
|
+
guidance: () => ""
|
|
2474
|
+
},
|
|
2475
|
+
varName: {
|
|
2476
|
+
content: () => "Please define a variable name",
|
|
2477
|
+
description: () => `We need to define a variable to be used as a counter to limit the loop`,
|
|
2478
|
+
guidance: () => ""
|
|
2479
|
+
}
|
|
2480
|
+
};
|
|
2481
|
+
|
|
2482
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/useOfSystemOutputStream.ts
|
|
2483
|
+
var useOfSystemOutputStream2 = {
|
|
2484
|
+
noLoggerAction: {
|
|
2485
|
+
content: () => "Which of the following you want to use instead of the vulnerable code?",
|
|
2486
|
+
description: () => "",
|
|
2487
|
+
guidance: () => ""
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
|
|
2491
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/xss.ts
|
|
2492
|
+
var xss2 = {
|
|
2493
|
+
isHtmlOrSafeAttribute: {
|
|
2494
|
+
content: ({ tainted_variable }) => `Where is \`${tainted_variable}\` written to?`,
|
|
2495
|
+
description: () => `Answer examples:
|
|
2496
|
+
|
|
2497
|
+
- a text in an HTML tag or a value of a safe HTML attribute:
|
|
2498
|
+
- \`<li><%= name %></li>\`
|
|
2499
|
+
- \`<div>Name: <%= name %></div>\`
|
|
2500
|
+
- \`<input value="<%= name %>" name="name"/>\`
|
|
2501
|
+
- \`<div data-name="<%= name %>"></div>\`
|
|
2502
|
+
- a JavaScript code block:
|
|
2503
|
+
- \`<script>const name = "<%= name %>";</script>\`
|
|
2504
|
+
- an event attribute of an HTML tag:
|
|
2505
|
+
- \`<a onclick="alert('<%= name %>')">click me</a>\`
|
|
2506
|
+
- \`<img onmouseover="alert('<%= name %>')"/>\`
|
|
2507
|
+
- a src-like attribute of an HTML tag:
|
|
2508
|
+
- \`<a href="/user/<%= name %>">me</a>\`
|
|
2509
|
+
- \`<img src="/img/<%= name %>"/>\`
|
|
2510
|
+
- \`<form action="<%= name %>"></form>\`
|
|
2511
|
+
- \`<iframe srcdoc="<%= name %>"/>\`
|
|
2512
|
+
- a part of an HTML tag attributes list:
|
|
2513
|
+
- \`<a <%= name %>>text</a>\`
|
|
2514
|
+
|
|
2515
|
+
See more details about safe and unsafe HTML attributes:
|
|
2516
|
+
- [PortSwigger cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
|
2517
|
+
- [DOMPurify attributes filter implementation](https://github.com/cure53/DOMPurify/blob/c29aa900a1c286b82ee4f48a7ffab96cab3e84fa/src/attrs.js)
|
|
2518
|
+
`,
|
|
2519
|
+
guidance: () => ""
|
|
2520
|
+
},
|
|
2521
|
+
isHtmlEncoded: {
|
|
2522
|
+
content: () => "Is the user input already encoded as HTML text?",
|
|
2523
|
+
description: () => "If you are unsure, we will decode the user input and encode it again to ensure it is safe and the data is kept the same.",
|
|
2524
|
+
guidance: () => ""
|
|
2525
|
+
},
|
|
2526
|
+
htmlEscapingLib: {
|
|
2527
|
+
content: () => "Which HTML escaping library would you like to use?",
|
|
2528
|
+
description: () => `
|
|
2529
|
+
- If you use the Spring framework, you likely already have \`org.springframework.web.util.HtmlUtils\`
|
|
2530
|
+
- Another \`option is org.apache.commons.text.StringEscapeUtils\``,
|
|
2531
|
+
guidance: () => ""
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
|
|
2535
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/xxe.ts
|
|
2536
|
+
var xxe2 = {
|
|
2537
|
+
factoryVarName: {
|
|
2538
|
+
content: () => "Name the new Factory variable",
|
|
2539
|
+
description: () => "We needed to create a new variable for this fix. We actually like the name we picked, but maybe you follow different naming conventions, so you can change it here.",
|
|
2540
|
+
guidance: () => ""
|
|
2541
|
+
}
|
|
2542
|
+
};
|
|
2543
|
+
|
|
2544
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/java/index.ts
|
|
2545
|
+
var vulnerabilities8 = {
|
|
2546
|
+
["SQL_Injection" /* SqlInjection */]: sqlInjection2,
|
|
2547
|
+
["CMDi_relative_path_command" /* CmDiRelativePathCommand */]: relativePathCommand,
|
|
2548
|
+
["CMDi" /* CmDi */]: commandInjection,
|
|
2549
|
+
["CONFUSING_NAMING" /* ConfusingNaming */]: confusingNaming,
|
|
2550
|
+
["ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */]: errorConditionWithoutAction,
|
|
2551
|
+
["XXE" /* Xxe */]: xxe2,
|
|
2552
|
+
["XSS" /* Xss */]: xss2,
|
|
2553
|
+
["PRIVACY_VIOLATION" /* PrivacyViolation */]: privacyViolation,
|
|
2554
|
+
["PT" /* Pt */]: pt2,
|
|
2555
|
+
["SSRF" /* Ssrf */]: ssrf3,
|
|
2556
|
+
["LOG_FORGING" /* LogForging */]: logForging2,
|
|
2557
|
+
["LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */]: localeDependentComparison,
|
|
2558
|
+
["MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */]: missingCheckAgainstNull,
|
|
2559
|
+
["OVERLY_BROAD_CATCH" /* OverlyBroadCatch */]: overlyBroadCatch2,
|
|
2560
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: sysLeak2,
|
|
2561
|
+
["USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */]: useOfSystemOutputStream2,
|
|
2562
|
+
["HTTP_ONLY_COOKIE" /* HttpOnlyCookie */]: httpOnlyCookie2,
|
|
2563
|
+
["UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */]: uncheckedLoopCondition,
|
|
2564
|
+
["INSECURE_COOKIE" /* InsecureCookie */]: insecureCookie2,
|
|
2565
|
+
["TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */]: trustBoundaryViolation2,
|
|
2566
|
+
["LEFTOVER_DEBUG_CODE" /* LeftoverDebugCode */]: leftoverDebugCode,
|
|
2567
|
+
["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: erroneousStringCompare
|
|
2568
|
+
};
|
|
2569
|
+
var java_default2 = vulnerabilities8;
|
|
2570
|
+
|
|
2571
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/commandInjection.ts
|
|
2572
|
+
var commandInjection2 = {
|
|
2573
|
+
isCommandExecutable: {
|
|
2574
|
+
content: () => "Commands can be intrinsically unsafe if they call out to other executables or run arbitary code",
|
|
2575
|
+
description: () => `Does the command fall into one of the following categories:
|
|
2576
|
+
|
|
2577
|
+
1. An executable name:
|
|
2578
|
+
- \`exec(input);\`
|
|
2579
|
+
- \`exec("/bin/bash " + input);\`
|
|
2580
|
+
- \`exec("/bin/sh -c" + input + " param");\`
|
|
2581
|
+
- \`exec("/bin/bash -c cat file.txt | " + input);\`
|
|
2582
|
+
- \`exec("/usr/bin/git --upload-pack " + input);\`
|
|
2583
|
+
2. A part of non-unix or cross platform shell command:
|
|
2584
|
+
- \`exec("cmd.exe /c ping " + input);\`
|
|
2585
|
+
3. A part of programming language code:
|
|
2586
|
+
- \`exec("php -r echo '" + input + "';");\`
|
|
2587
|
+
- \`exec("perl -e print '" + input + "'");\``,
|
|
2588
|
+
guidance: () => ""
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
|
|
2592
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/graphqlDepthLimit.ts
|
|
2593
|
+
var graphqlDepthLimit = {
|
|
2594
|
+
depthLimit: {
|
|
2595
|
+
content: () => "Please define a maximum query depth",
|
|
2596
|
+
description: () => `Setting this number to a reasonable value will prevent the attack.
|
|
2597
|
+
Make sure to pick a value large enough to allowed the nessecary amount of nested queries.`,
|
|
2598
|
+
guidance: () => {
|
|
2599
|
+
return "We use `graphql-depth-limit` npm package to limit the depth of nested queries. Please make sure you install the package using `npm install graphql-depth-limit`.";
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
};
|
|
2603
|
+
|
|
2604
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/hardcodedSecrets.ts
|
|
2605
|
+
var hardcodedSecrets2 = {
|
|
2606
|
+
envVarName: {
|
|
2607
|
+
content: () => "Please define an environment variable name",
|
|
2608
|
+
description: () => `We will use this environment variable instead of the hardcoded secret`,
|
|
2609
|
+
guidance: () => ""
|
|
2610
|
+
},
|
|
2611
|
+
keepAsDefault: {
|
|
2612
|
+
content: () => "Do you want to keep the hardcoded secret in the code for now?",
|
|
2613
|
+
description: () => 'Answer "yes" if you cannot set the environment variable in all environments right away.',
|
|
2614
|
+
guidance: () => ""
|
|
2615
|
+
}
|
|
2616
|
+
};
|
|
2617
|
+
|
|
2618
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/iframeWithoutSandbox.ts
|
|
2619
|
+
var iframeWithoutSandbox = {
|
|
2620
|
+
iframeRestrictions: {
|
|
2621
|
+
content: () => "Please define a comma-separated list of iframe sandbox restrictions (optional)",
|
|
2622
|
+
description: () => `Possible values:
|
|
2623
|
+
- allow-downloads
|
|
2624
|
+
- allow-forms
|
|
2625
|
+
- allow-modals
|
|
2626
|
+
- allow-orientation-lock
|
|
2627
|
+
- allow-pointer-lock
|
|
2628
|
+
- allow-popups
|
|
2629
|
+
- allow-popups-to-escape-sandbox
|
|
2630
|
+
- allow-presentation
|
|
2631
|
+
- allow-same-origin
|
|
2632
|
+
- allow-scripts
|
|
2633
|
+
- allow-storage-access-by-user-activation
|
|
2634
|
+
- allow-top-navigation
|
|
2635
|
+
- allow-top-navigation-by-user-activation
|
|
2636
|
+
- allow-top-navigation-to-custom-protocols
|
|
2637
|
+
|
|
2638
|
+
See more info [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox).`,
|
|
2639
|
+
guidance: () => ""
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
|
|
2643
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/incompleteUrlSanitization.ts
|
|
2644
|
+
var incompleteUrlSanitization = {
|
|
2645
|
+
allowedRootDomain: {
|
|
2646
|
+
content: () => "The root domain of your application",
|
|
2647
|
+
description: () => "We needed to strengthen the security check by ensuring that the url is under the root domain of your application.",
|
|
2648
|
+
guidance: () => ""
|
|
2649
|
+
}
|
|
2650
|
+
};
|
|
2651
|
+
|
|
2652
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/insecureRandomness.ts
|
|
2653
|
+
var insecureRandomness2 = {
|
|
2654
|
+
isGetRandomValuesSupported: {
|
|
2655
|
+
content: () => "Is getRandomValues() function supported by your JavaScript engine?",
|
|
2656
|
+
description: () => "[getRandomValues()](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) is supported by [more than 97% of browsers](https://caniuse.com/?search=getRandomValues) and [Node.js >= 15.0.0](https://nodejs.org/api/webcrypto.html#cryptogetrandomvaluestypedarray).",
|
|
2657
|
+
guidance: () => ""
|
|
2658
|
+
}
|
|
2659
|
+
};
|
|
2660
|
+
|
|
2661
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/logForging.ts
|
|
2662
|
+
var logForging3 = {
|
|
2663
|
+
isHtmlDisplay: {
|
|
2664
|
+
content: () => "Is the text written to the log going to be displayed as HTML?",
|
|
2665
|
+
description: () => "",
|
|
2666
|
+
guidance: () => ""
|
|
2667
|
+
}
|
|
2668
|
+
};
|
|
2669
|
+
|
|
2670
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/missingHSTSHeader.ts
|
|
2671
|
+
var headerMaxAge = {
|
|
2672
|
+
headerMaxAge: {
|
|
2673
|
+
content: () => "Please provide the maximum age of the header",
|
|
2674
|
+
description: () => `This is the time, in seconds, that the browser should remember that the site is only to be accessed using \`HTTPS\`.
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
Setting the \`max-age\` to \`0\` (over an https connection) will immediately expire the Strict-Transport-Security header, allowing access via \`HTTP\`.
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
|
|
2681
|
+
|
|
2682
|
+
The HTTP Strict-Transport-Security response header (\`HSTS\`) informs browsers that the site
|
|
2683
|
+
should only be accessed using HTTPS, and that any future attempts to access it using HTTP should automatically
|
|
2684
|
+
be converted to HTTPS.
|
|
2685
|
+
|
|
2686
|
+
|
|
2687
|
+
|
|
2688
|
+
|
|
2689
|
+
If a website accepts a connection through \`HTTP\` and redirects to \`HTTPS\`, visitors may initially communicate with
|
|
2690
|
+
the non-encrypted version of the site before being redirected, if, for example, the visitor
|
|
2691
|
+
types \`http://www.example.com\` or even just \`example.com\`. This creates an opportunity for a man-in-the-middle attack.
|
|
2692
|
+
The redirect could be exploited to direct visitors to a malicious site instead of the secure version of the original site.
|
|
2693
|
+
|
|
2694
|
+
|
|
2695
|
+
|
|
2696
|
+
The \`HTTP\` Strict Transport Security header informs the browser that it should never load a site using \`HTTP\`
|
|
2697
|
+
and should automatically convert all attempts to access the site using \`HTTP\` to \`HTTPS\` requests instead.`,
|
|
2698
|
+
guidance: () => ``
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/noLimitsOrThrottling.ts
|
|
2703
|
+
var noLimitsOrThrottling2 = {
|
|
2704
|
+
setGlobalLimiter: {
|
|
2705
|
+
content: () => "Would you like to use a global rate limit for all your endpoints within the same file?",
|
|
2706
|
+
description: () => "",
|
|
2707
|
+
guidance: () => ""
|
|
2708
|
+
}
|
|
2709
|
+
};
|
|
2710
|
+
|
|
2711
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/openRedirect.ts
|
|
2712
|
+
var openRedirect = {
|
|
2713
|
+
isExternal: {
|
|
2714
|
+
content: () => "Does the redirect go to an external site",
|
|
2715
|
+
description: () => "",
|
|
2716
|
+
guidance: () => ""
|
|
2717
|
+
},
|
|
2718
|
+
allowlist: {
|
|
2719
|
+
content: () => "Allowed domains/paths",
|
|
2720
|
+
description: () => "If external, provide a coma separated list of allowed domains. If internal, provide a coma seperated list of allowed paths",
|
|
2721
|
+
guidance: () => ""
|
|
2722
|
+
}
|
|
637
2723
|
};
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
2724
|
+
|
|
2725
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/pt.ts
|
|
2726
|
+
var pt3 = {
|
|
2727
|
+
taintedTermType: {
|
|
2728
|
+
content: ({ expression }) => `Does \`${expression}\` represent a file name, a relative path or an absolute path?`,
|
|
2729
|
+
description: ({ expression }) => `We replace all illegal file name characters for Unix, Windows, and macOS operation systems, including slashes. Ensure that \`${expression}\` isn't supposed to contain slashes or other illegal file name characters.`,
|
|
2730
|
+
guidance: () => ""
|
|
2731
|
+
}
|
|
2732
|
+
};
|
|
2733
|
+
|
|
2734
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/ssrf.ts
|
|
2735
|
+
var ssrf4 = {
|
|
2736
|
+
domainsAllowlist: {
|
|
2737
|
+
content: () => "List of allowed domain names",
|
|
2738
|
+
description: () => `The security risk of this issue is the ability of an attacker to provide input that shoots HTTP requests from your server to arbitrary domains.
|
|
2739
|
+
|
|
2740
|
+
|
|
2741
|
+
To eliminate the risk and fix the issue, check out your app logic and make a whitelist of domains the server should be allowed to call.`,
|
|
2742
|
+
guidance: () => ""
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
|
|
2746
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/sysLeak.ts
|
|
2747
|
+
var sysLeak3 = {
|
|
2748
|
+
errorMessage: {
|
|
2749
|
+
content: () => "Enter the error message that you want to appear in the log",
|
|
2750
|
+
description: () => "",
|
|
2751
|
+
guidance: () => ""
|
|
2752
|
+
},
|
|
2753
|
+
noLoggerAction: {
|
|
2754
|
+
content: () => "Which of the following you want to use instead of the vulnerable code?",
|
|
2755
|
+
description: () => "",
|
|
2756
|
+
guidance: () => ""
|
|
2757
|
+
}
|
|
2758
|
+
};
|
|
2759
|
+
|
|
2760
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/sysLeakExternal.ts
|
|
2761
|
+
var sysLeakExternal = {
|
|
2762
|
+
errorMessage: {
|
|
2763
|
+
content: () => "Enter the error message that you want to appear to the user",
|
|
2764
|
+
description: () => "",
|
|
2765
|
+
guidance: () => ""
|
|
2766
|
+
}
|
|
2767
|
+
};
|
|
2768
|
+
|
|
2769
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/typeConfusion.ts
|
|
2770
|
+
var typeConfusion = {
|
|
2771
|
+
argumentType: {
|
|
2772
|
+
content: () => "What is the type of the HTTP argument?",
|
|
2773
|
+
description: () => "What is the type of the HTTP argument?",
|
|
2774
|
+
guidance: () => ""
|
|
2775
|
+
}
|
|
2776
|
+
};
|
|
2777
|
+
|
|
2778
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/uncheckedLoopCondition.ts
|
|
2779
|
+
var uncheckedLoopCondition2 = {
|
|
2780
|
+
loopLimit: {
|
|
2781
|
+
content: () => "Please define a maximum loop limit",
|
|
2782
|
+
description: () => `Setting this number to a reasonable value will prevent the vulnerability`,
|
|
2783
|
+
guidance: () => ""
|
|
2784
|
+
},
|
|
2785
|
+
varName: {
|
|
2786
|
+
content: () => "Please define a variable name",
|
|
2787
|
+
description: () => `We need to define a variable to be used as a counter to limit the loop`,
|
|
2788
|
+
guidance: () => ""
|
|
2789
|
+
}
|
|
2790
|
+
};
|
|
2791
|
+
|
|
2792
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/xss.ts
|
|
2793
|
+
var xss3 = {
|
|
2794
|
+
containsHtml: {
|
|
2795
|
+
content: () => "Does the element or variable contain HTML formatting",
|
|
2796
|
+
description: () => "",
|
|
2797
|
+
guidance: () => ""
|
|
2798
|
+
},
|
|
2799
|
+
isParamTypeString: {
|
|
2800
|
+
content: () => "Is the parameter passed to the $() function a string",
|
|
2801
|
+
description: () => "",
|
|
2802
|
+
guidance: () => ""
|
|
2803
|
+
}
|
|
2804
|
+
};
|
|
2805
|
+
|
|
2806
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/js/index.ts
|
|
2807
|
+
var vulnerabilities9 = {
|
|
2808
|
+
["CMDi" /* CmDi */]: commandInjection2,
|
|
2809
|
+
["GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */]: graphqlDepthLimit,
|
|
2810
|
+
["INSECURE_RANDOMNESS" /* InsecureRandomness */]: insecureRandomness2,
|
|
2811
|
+
["SSRF" /* Ssrf */]: ssrf4,
|
|
2812
|
+
["TYPE_CONFUSION" /* TypeConfusion */]: typeConfusion,
|
|
2813
|
+
["INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */]: incompleteUrlSanitization,
|
|
2814
|
+
["LOG_FORGING" /* LogForging */]: logForging3,
|
|
2815
|
+
["XSS" /* Xss */]: xss3,
|
|
2816
|
+
["OPEN_REDIRECT" /* OpenRedirect */]: openRedirect,
|
|
2817
|
+
["SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */]: sysLeak3,
|
|
2818
|
+
["SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */]: sysLeakExternal,
|
|
2819
|
+
["IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */]: iframeWithoutSandbox,
|
|
2820
|
+
["PT" /* Pt */]: pt3,
|
|
2821
|
+
["HARDCODED_SECRETS" /* HardcodedSecrets */]: hardcodedSecrets2,
|
|
2822
|
+
["MISSING_HSTS_HEADER" /* MissingHstsHeader */]: headerMaxAge,
|
|
2823
|
+
["UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */]: uncheckedLoopCondition2,
|
|
2824
|
+
["NO_LIMITS_OR_THROTTLING" /* NoLimitsOrThrottling */]: noLimitsOrThrottling2
|
|
2825
|
+
};
|
|
2826
|
+
var js_default = vulnerabilities9;
|
|
2827
|
+
|
|
2828
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/xml/unboundedOccurrences.ts
|
|
2829
|
+
var unboundedOccurrences = {
|
|
2830
|
+
maxOccursLimit: {
|
|
2831
|
+
content: () => "The number of allowed repetitions of the element.",
|
|
2832
|
+
description: () => "",
|
|
2833
|
+
guidance: () => `Setting this number to a reasonable value will prevent the attack.
|
|
2834
|
+
A value too low will prevent valid XMLs from being processed.
|
|
2835
|
+
A value too high will cause performance issues up to and including denial of service.`
|
|
643
2836
|
}
|
|
644
|
-
return issueTypeMap[issueTypeZParseRes.data];
|
|
645
2837
|
};
|
|
646
2838
|
|
|
2839
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/xml/index.ts
|
|
2840
|
+
var vulnerabilities10 = {
|
|
2841
|
+
["WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */]: unboundedOccurrences
|
|
2842
|
+
};
|
|
2843
|
+
var xml_default2 = vulnerabilities10;
|
|
2844
|
+
|
|
2845
|
+
// src/features/analysis/scm/shared/src/storedQuestionData/index.ts
|
|
2846
|
+
var StoredQuestionDataItemZ = z7.object({
|
|
2847
|
+
content: z7.function().args(z7.any()).returns(z7.string()),
|
|
2848
|
+
description: z7.function().args(z7.any()).returns(z7.string()),
|
|
2849
|
+
guidance: z7.function().args(z7.any()).returns(z7.string())
|
|
2850
|
+
});
|
|
2851
|
+
var languages2 = {
|
|
2852
|
+
["Java" /* Java */]: java_default2,
|
|
2853
|
+
["JavaScript" /* JavaScript */]: js_default,
|
|
2854
|
+
["XML" /* Xml */]: xml_default2,
|
|
2855
|
+
["CSharp" /* CSharp */]: csharp_default2
|
|
2856
|
+
};
|
|
2857
|
+
var storedQuestionData_default = languages2;
|
|
2858
|
+
|
|
2859
|
+
// src/features/analysis/scm/shared/src/guidances.ts
|
|
2860
|
+
function toQuestion(userInput) {
|
|
2861
|
+
const { key, defaultValue } = userInput;
|
|
2862
|
+
const value = userInput.value || defaultValue;
|
|
2863
|
+
return { ...userInput, defaultValue, value, key, error: false };
|
|
2864
|
+
}
|
|
2865
|
+
function getQuestionInformation({
|
|
2866
|
+
fixQuestionData,
|
|
2867
|
+
issueType,
|
|
2868
|
+
language
|
|
2869
|
+
}) {
|
|
2870
|
+
const { name } = fixQuestionData;
|
|
2871
|
+
const storedQuestionDataItem = storedQuestionData_default[language]?.[issueType]?.[name] ?? {
|
|
2872
|
+
content: () => "",
|
|
2873
|
+
description: () => "",
|
|
2874
|
+
guidance: () => ""
|
|
2875
|
+
};
|
|
2876
|
+
return StoredQuestionDataItemZ.parse(storedQuestionDataItem);
|
|
2877
|
+
}
|
|
2878
|
+
function curriedQuestionInformationByQuestion({
|
|
2879
|
+
issueType,
|
|
2880
|
+
language
|
|
2881
|
+
}) {
|
|
2882
|
+
return (fixQuestionData) => getQuestionInformation({
|
|
2883
|
+
issueType,
|
|
2884
|
+
language,
|
|
2885
|
+
fixQuestionData
|
|
2886
|
+
});
|
|
2887
|
+
}
|
|
2888
|
+
function getPackageFixGuidance(actionsRequired) {
|
|
2889
|
+
const actionRequiredStrings = actionsRequired.map((action) => {
|
|
2890
|
+
if (action.language === "JS" /* Js */) {
|
|
2891
|
+
if (action.action === "add" /* Add */) {
|
|
2892
|
+
let actionRequired = `We use \`${action.lib.name}\` package to sanitize user input. Please make sure you add the latest [\`${action.lib.name}\`](https://www.npmjs.com/package/${action.lib.name}) to your \`package.json\` file.`;
|
|
2893
|
+
if (action.typesLib) {
|
|
2894
|
+
actionRequired += ` For TypeScript users, consider adding [\`${action.typesLib.name}\`](https://www.npmjs.com/package/${action.typesLib.name}) to your \`package.json\` as well`;
|
|
2895
|
+
}
|
|
2896
|
+
return actionRequired;
|
|
2897
|
+
}
|
|
2898
|
+
if (action.action === "relock" /* Relock */) {
|
|
2899
|
+
const actionRequired = `A lock file was detected, please make sure to relock the lock file using your package manager.`;
|
|
2900
|
+
return actionRequired;
|
|
2901
|
+
}
|
|
2902
|
+
if (action.action === "upgrade" /* Upgrade */) {
|
|
2903
|
+
return `We use \`${action.lib.name}\` package to sanitize user input. Please make sure you upgrade the package [\`${action.lib.name}\`](https://www.npmjs.com/package/${action.lib.name}) to the latest version in your \`package.json\` file.`;
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
if (action.language === "JAVA" /* Java */) {
|
|
2907
|
+
const names = action.lib.name.split(":");
|
|
2908
|
+
const groupId = names[0];
|
|
2909
|
+
const artifactId = names[1];
|
|
2910
|
+
if (action.action === "add" /* Add */) {
|
|
2911
|
+
return `We use \`${artifactId}\` package in the fix. Please make sure you add the latest [\`${artifactId}\`](https://mvnrepository.com/artifact/${groupId}/${artifactId}) to your pom file.`;
|
|
2912
|
+
}
|
|
2913
|
+
if (action.action === "upgrade" /* Upgrade */) {
|
|
2914
|
+
return `We use \`${artifactId}\` package in the fix. Please make sure you upgrade the package [\`${artifactId}\`](https://mvnrepository.com/artifact/${groupId}/${artifactId}) to the latest version in your pom file.`;
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
return void 0;
|
|
2918
|
+
});
|
|
2919
|
+
return actionRequiredStrings.filter((action) => !!action);
|
|
2920
|
+
}
|
|
2921
|
+
function getFixGuidances({
|
|
2922
|
+
issueType,
|
|
2923
|
+
issueLanguage,
|
|
2924
|
+
fixExtraContext,
|
|
2925
|
+
questions
|
|
2926
|
+
}) {
|
|
2927
|
+
const storedFixGuidanceDataItem = languages[issueLanguage || ""]?.[issueType || ""] ?? {};
|
|
2928
|
+
const storeFixResult = StoredFixDataItemZ.safeParse(storedFixGuidanceDataItem);
|
|
2929
|
+
const libGuidances = getPackageFixGuidance(
|
|
2930
|
+
fixExtraContext.manifestActionsRequired
|
|
2931
|
+
);
|
|
2932
|
+
const extraContext = fixExtraContext.extraContext.reduce(
|
|
2933
|
+
(acc, obj) => {
|
|
2934
|
+
acc[obj.key] = obj.value;
|
|
2935
|
+
return acc;
|
|
2936
|
+
},
|
|
2937
|
+
{}
|
|
2938
|
+
);
|
|
2939
|
+
const fixGuidance = storeFixResult.success ? [storeFixResult.data.guidance({ questions, ...extraContext })] : [];
|
|
2940
|
+
return libGuidances.concat(fixGuidance).filter((guidance) => !!guidance);
|
|
2941
|
+
}
|
|
2942
|
+
function getGuidances({
|
|
2943
|
+
questions,
|
|
2944
|
+
issueType,
|
|
2945
|
+
issueLanguage,
|
|
2946
|
+
fixExtraContext
|
|
2947
|
+
}) {
|
|
2948
|
+
const fixGuidances = getFixGuidances({
|
|
2949
|
+
issueType,
|
|
2950
|
+
issueLanguage,
|
|
2951
|
+
fixExtraContext,
|
|
2952
|
+
questions
|
|
2953
|
+
}).map((guidance, index) => ({ guidance, key: `fixGuidance_index_${index}` }));
|
|
2954
|
+
return questions.map((question) => {
|
|
2955
|
+
let questionGuidance = question.guidance;
|
|
2956
|
+
if (!questionGuidance && issueType && issueLanguage) {
|
|
2957
|
+
const getFixInformation = curriedQuestionInformationByQuestion({
|
|
2958
|
+
issueType: z8.nativeEnum(IssueType_Enum).parse(issueType),
|
|
2959
|
+
language: z8.nativeEnum(IssueLanguage_Enum).parse(issueLanguage)
|
|
2960
|
+
});
|
|
2961
|
+
const { guidance } = getFixInformation(question);
|
|
2962
|
+
questionGuidance = guidance({
|
|
2963
|
+
userInputValue: question.value
|
|
2964
|
+
});
|
|
2965
|
+
}
|
|
2966
|
+
return {
|
|
2967
|
+
...question,
|
|
2968
|
+
guidance: questionGuidance
|
|
2969
|
+
};
|
|
2970
|
+
}).filter(({ guidance }) => !!guidance).map(({ guidance, key }) => ({ guidance, key })).concat(fixGuidances);
|
|
2971
|
+
}
|
|
2972
|
+
|
|
647
2973
|
// src/features/analysis/scm/shared/src/urlParser/urlParser.ts
|
|
648
|
-
import { z as
|
|
2974
|
+
import { z as z9 } from "zod";
|
|
649
2975
|
function detectAdoUrl(args) {
|
|
650
2976
|
const { pathname, hostname, scmType } = args;
|
|
651
2977
|
const hostnameParts = hostname.split(".");
|
|
@@ -660,7 +2986,7 @@ function detectAdoUrl(args) {
|
|
|
660
2986
|
scmType: "Ado" /* Ado */,
|
|
661
2987
|
organization,
|
|
662
2988
|
// project has single repo - repoName === projectName
|
|
663
|
-
projectName:
|
|
2989
|
+
projectName: z9.string().parse(projectName),
|
|
664
2990
|
repoName: projectName,
|
|
665
2991
|
prefixPath
|
|
666
2992
|
};
|
|
@@ -671,7 +2997,7 @@ function detectAdoUrl(args) {
|
|
|
671
2997
|
return {
|
|
672
2998
|
scmType: "Ado" /* Ado */,
|
|
673
2999
|
organization,
|
|
674
|
-
projectName:
|
|
3000
|
+
projectName: z9.string().parse(projectName),
|
|
675
3001
|
repoName,
|
|
676
3002
|
prefixPath
|
|
677
3003
|
};
|
|
@@ -685,7 +3011,7 @@ function detectAdoUrl(args) {
|
|
|
685
3011
|
scmType: "Ado" /* Ado */,
|
|
686
3012
|
organization,
|
|
687
3013
|
// project has only one repo - repoName === projectName
|
|
688
|
-
projectName:
|
|
3014
|
+
projectName: z9.string().parse(repoName),
|
|
689
3015
|
repoName,
|
|
690
3016
|
prefixPath
|
|
691
3017
|
};
|
|
@@ -695,7 +3021,7 @@ function detectAdoUrl(args) {
|
|
|
695
3021
|
return {
|
|
696
3022
|
scmType: "Ado" /* Ado */,
|
|
697
3023
|
organization,
|
|
698
|
-
projectName:
|
|
3024
|
+
projectName: z9.string().parse(projectName),
|
|
699
3025
|
repoName,
|
|
700
3026
|
prefixPath
|
|
701
3027
|
};
|
|
@@ -803,6 +3129,17 @@ var parseScmURL = (scmURL, scmType) => {
|
|
|
803
3129
|
}
|
|
804
3130
|
};
|
|
805
3131
|
|
|
3132
|
+
// src/features/analysis/scm/shared/src/utils.ts
|
|
3133
|
+
function getFixUrl({
|
|
3134
|
+
appBaseUrl,
|
|
3135
|
+
fixId,
|
|
3136
|
+
projectId,
|
|
3137
|
+
organizationId,
|
|
3138
|
+
analysisId
|
|
3139
|
+
}) {
|
|
3140
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
3141
|
+
}
|
|
3142
|
+
|
|
806
3143
|
// src/features/analysis/scm/shared/src/index.ts
|
|
807
3144
|
var NAME_REGEX = /[a-z0-9\-_.+]+/i;
|
|
808
3145
|
var ADO_PREFIX_PATH = "tfs";
|
|
@@ -844,15 +3181,6 @@ function getFixUrlWithRedirect(params) {
|
|
|
844
3181
|
analysisId
|
|
845
3182
|
})}?${searchParams.toString()}`;
|
|
846
3183
|
}
|
|
847
|
-
function getFixUrl({
|
|
848
|
-
appBaseUrl,
|
|
849
|
-
fixId,
|
|
850
|
-
projectId,
|
|
851
|
-
organizationId,
|
|
852
|
-
analysisId
|
|
853
|
-
}) {
|
|
854
|
-
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
855
|
-
}
|
|
856
3184
|
function getCommitUrl(params) {
|
|
857
3185
|
const {
|
|
858
3186
|
fixId,
|
|
@@ -918,25 +3246,25 @@ var sanityRepoURL = (scmURL) => {
|
|
|
918
3246
|
|
|
919
3247
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
920
3248
|
var BITBUCKET_HOSTNAME = "bitbucket.org";
|
|
921
|
-
var TokenExpiredErrorZ =
|
|
922
|
-
status:
|
|
923
|
-
error:
|
|
924
|
-
type:
|
|
925
|
-
error:
|
|
926
|
-
message:
|
|
3249
|
+
var TokenExpiredErrorZ = z10.object({
|
|
3250
|
+
status: z10.number(),
|
|
3251
|
+
error: z10.object({
|
|
3252
|
+
type: z10.string(),
|
|
3253
|
+
error: z10.object({
|
|
3254
|
+
message: z10.string()
|
|
927
3255
|
})
|
|
928
3256
|
})
|
|
929
3257
|
});
|
|
930
3258
|
var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
|
|
931
|
-
var BitbucketAuthResultZ =
|
|
932
|
-
access_token:
|
|
933
|
-
token_type:
|
|
934
|
-
refresh_token:
|
|
3259
|
+
var BitbucketAuthResultZ = z10.object({
|
|
3260
|
+
access_token: z10.string(),
|
|
3261
|
+
token_type: z10.string(),
|
|
3262
|
+
refresh_token: z10.string()
|
|
935
3263
|
});
|
|
936
|
-
var BitbucketParseResultZ =
|
|
937
|
-
organization:
|
|
938
|
-
repoName:
|
|
939
|
-
hostname:
|
|
3264
|
+
var BitbucketParseResultZ = z10.object({
|
|
3265
|
+
organization: z10.string(),
|
|
3266
|
+
repoName: z10.string(),
|
|
3267
|
+
hostname: z10.literal(BITBUCKET_HOSTNAME)
|
|
940
3268
|
});
|
|
941
3269
|
function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
|
|
942
3270
|
const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
|
|
@@ -1015,7 +3343,7 @@ function getBitbucketSdk(params) {
|
|
|
1015
3343
|
if (!res.data.values) {
|
|
1016
3344
|
return [];
|
|
1017
3345
|
}
|
|
1018
|
-
return res.data.values.filter((branch) => !!branch.name).map((branch) =>
|
|
3346
|
+
return res.data.values.filter((branch) => !!branch.name).map((branch) => z10.string().parse(branch.name));
|
|
1019
3347
|
},
|
|
1020
3348
|
async getIsUserCollaborator(params2) {
|
|
1021
3349
|
const { repoUrl } = params2;
|
|
@@ -1130,7 +3458,7 @@ function getBitbucketSdk(params) {
|
|
|
1130
3458
|
return GetRefererenceResultZ.parse({
|
|
1131
3459
|
sha: tagRes.data.target?.hash,
|
|
1132
3460
|
type: "TAG" /* TAG */,
|
|
1133
|
-
date: new Date(
|
|
3461
|
+
date: new Date(z10.string().parse(tagRes.data.target?.date))
|
|
1134
3462
|
});
|
|
1135
3463
|
},
|
|
1136
3464
|
async getBranchRef(params2) {
|
|
@@ -1138,7 +3466,7 @@ function getBitbucketSdk(params) {
|
|
|
1138
3466
|
return GetRefererenceResultZ.parse({
|
|
1139
3467
|
sha: getBranchRes.target?.hash,
|
|
1140
3468
|
type: "BRANCH" /* BRANCH */,
|
|
1141
|
-
date: new Date(
|
|
3469
|
+
date: new Date(z10.string().parse(getBranchRes.target?.date))
|
|
1142
3470
|
});
|
|
1143
3471
|
},
|
|
1144
3472
|
async getCommitRef(params2) {
|
|
@@ -1146,13 +3474,13 @@ function getBitbucketSdk(params) {
|
|
|
1146
3474
|
return GetRefererenceResultZ.parse({
|
|
1147
3475
|
sha: getCommitRes.hash,
|
|
1148
3476
|
type: "COMMIT" /* COMMIT */,
|
|
1149
|
-
date: new Date(
|
|
3477
|
+
date: new Date(z10.string().parse(getCommitRes.date))
|
|
1150
3478
|
});
|
|
1151
3479
|
},
|
|
1152
3480
|
async getDownloadUrl({ url, sha }) {
|
|
1153
3481
|
this.getReferenceData({ ref: sha, url });
|
|
1154
3482
|
const repoRes = await this.getRepo({ repoUrl: url });
|
|
1155
|
-
const parsedRepoUrl =
|
|
3483
|
+
const parsedRepoUrl = z10.string().url().parse(repoRes.links?.html?.href);
|
|
1156
3484
|
return `${parsedRepoUrl}/get/${sha}.zip`;
|
|
1157
3485
|
},
|
|
1158
3486
|
async getPullRequest(params2) {
|
|
@@ -1195,7 +3523,7 @@ async function validateBitbucketParams(params) {
|
|
|
1195
3523
|
}
|
|
1196
3524
|
async function getUsersworkspacesSlugs(bitbucketClient) {
|
|
1197
3525
|
const res = await bitbucketClient.workspaces.getWorkspaces({});
|
|
1198
|
-
return res.data.values?.map((v) =>
|
|
3526
|
+
return res.data.values?.map((v) => z10.string().parse(v.slug));
|
|
1199
3527
|
}
|
|
1200
3528
|
async function getllUsersrepositories(bitbucketClient) {
|
|
1201
3529
|
const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
|
|
@@ -1735,11 +4063,11 @@ import {
|
|
|
1735
4063
|
import { ProxyAgent as ProxyAgent2 } from "undici";
|
|
1736
4064
|
|
|
1737
4065
|
// src/features/analysis/scm/gitlab/types.ts
|
|
1738
|
-
import { z as
|
|
1739
|
-
var GitlabAuthResultZ =
|
|
1740
|
-
access_token:
|
|
1741
|
-
token_type:
|
|
1742
|
-
refresh_token:
|
|
4066
|
+
import { z as z11 } from "zod";
|
|
4067
|
+
var GitlabAuthResultZ = z11.object({
|
|
4068
|
+
access_token: z11.string(),
|
|
4069
|
+
token_type: z11.string(),
|
|
4070
|
+
refresh_token: z11.string()
|
|
1743
4071
|
});
|
|
1744
4072
|
|
|
1745
4073
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
@@ -2032,83 +4360,83 @@ initGitlabFetchMock();
|
|
|
2032
4360
|
// src/features/analysis/scm/scmSubmit/index.ts
|
|
2033
4361
|
import fs from "node:fs/promises";
|
|
2034
4362
|
import parseDiff from "parse-diff";
|
|
2035
|
-
import
|
|
4363
|
+
import path3 from "path";
|
|
2036
4364
|
import { simpleGit } from "simple-git";
|
|
2037
4365
|
import tmp from "tmp";
|
|
2038
|
-
import { z as
|
|
4366
|
+
import { z as z13 } from "zod";
|
|
2039
4367
|
|
|
2040
4368
|
// src/features/analysis/scm/scmSubmit/types.ts
|
|
2041
|
-
import { z as
|
|
2042
|
-
var BaseSubmitToScmMessageZ =
|
|
2043
|
-
submitFixRequestId:
|
|
2044
|
-
fixes:
|
|
2045
|
-
|
|
2046
|
-
fixId:
|
|
2047
|
-
patches:
|
|
4369
|
+
import { z as z12 } from "zod";
|
|
4370
|
+
var BaseSubmitToScmMessageZ = z12.object({
|
|
4371
|
+
submitFixRequestId: z12.string().uuid(),
|
|
4372
|
+
fixes: z12.array(
|
|
4373
|
+
z12.object({
|
|
4374
|
+
fixId: z12.string().uuid(),
|
|
4375
|
+
patches: z12.array(z12.string())
|
|
2048
4376
|
})
|
|
2049
4377
|
),
|
|
2050
|
-
commitHash:
|
|
2051
|
-
repoUrl:
|
|
2052
|
-
mobbUserEmail:
|
|
2053
|
-
extraHeaders:
|
|
4378
|
+
commitHash: z12.string(),
|
|
4379
|
+
repoUrl: z12.string(),
|
|
4380
|
+
mobbUserEmail: z12.string(),
|
|
4381
|
+
extraHeaders: z12.record(z12.string(), z12.string()).default({})
|
|
2054
4382
|
});
|
|
2055
4383
|
var submitToScmMessageType = {
|
|
2056
4384
|
commitToSameBranch: "commitToSameBranch",
|
|
2057
4385
|
submitFixesForDifferentBranch: "submitFixesForDifferentBranch"
|
|
2058
4386
|
};
|
|
2059
4387
|
var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
|
|
2060
|
-
|
|
2061
|
-
type:
|
|
2062
|
-
branch:
|
|
2063
|
-
commitMessage:
|
|
2064
|
-
commitDescription:
|
|
2065
|
-
githubCommentId:
|
|
4388
|
+
z12.object({
|
|
4389
|
+
type: z12.literal(submitToScmMessageType.commitToSameBranch),
|
|
4390
|
+
branch: z12.string(),
|
|
4391
|
+
commitMessage: z12.string(),
|
|
4392
|
+
commitDescription: z12.string().nullish(),
|
|
4393
|
+
githubCommentId: z12.number().nullish()
|
|
2066
4394
|
})
|
|
2067
4395
|
);
|
|
2068
|
-
var SubmitFixesToDifferentBranchParamsZ =
|
|
2069
|
-
type:
|
|
2070
|
-
submitBranch:
|
|
2071
|
-
baseBranch:
|
|
4396
|
+
var SubmitFixesToDifferentBranchParamsZ = z12.object({
|
|
4397
|
+
type: z12.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
4398
|
+
submitBranch: z12.string(),
|
|
4399
|
+
baseBranch: z12.string()
|
|
2072
4400
|
}).merge(BaseSubmitToScmMessageZ);
|
|
2073
|
-
var SubmitFixesMessageZ =
|
|
4401
|
+
var SubmitFixesMessageZ = z12.union([
|
|
2074
4402
|
CommitToSameBranchParamsZ,
|
|
2075
4403
|
SubmitFixesToDifferentBranchParamsZ
|
|
2076
4404
|
]);
|
|
2077
|
-
var FixResponseArrayZ =
|
|
2078
|
-
|
|
2079
|
-
fixId:
|
|
4405
|
+
var FixResponseArrayZ = z12.array(
|
|
4406
|
+
z12.object({
|
|
4407
|
+
fixId: z12.string().uuid()
|
|
2080
4408
|
})
|
|
2081
4409
|
);
|
|
2082
|
-
var SubmitFixesBaseResponseMessageZ =
|
|
2083
|
-
mobbUserEmail:
|
|
2084
|
-
submitFixRequestId:
|
|
2085
|
-
submitBranches:
|
|
2086
|
-
|
|
2087
|
-
branchName:
|
|
4410
|
+
var SubmitFixesBaseResponseMessageZ = z12.object({
|
|
4411
|
+
mobbUserEmail: z12.string(),
|
|
4412
|
+
submitFixRequestId: z12.string().uuid(),
|
|
4413
|
+
submitBranches: z12.array(
|
|
4414
|
+
z12.object({
|
|
4415
|
+
branchName: z12.string(),
|
|
2088
4416
|
fixes: FixResponseArrayZ
|
|
2089
4417
|
})
|
|
2090
4418
|
),
|
|
2091
|
-
error:
|
|
2092
|
-
type:
|
|
4419
|
+
error: z12.object({
|
|
4420
|
+
type: z12.enum([
|
|
2093
4421
|
"InitialRepoAccessError",
|
|
2094
4422
|
"PushBranchError",
|
|
2095
4423
|
"UnknownError"
|
|
2096
4424
|
]),
|
|
2097
|
-
info:
|
|
2098
|
-
message:
|
|
2099
|
-
pushBranchName:
|
|
4425
|
+
info: z12.object({
|
|
4426
|
+
message: z12.string(),
|
|
4427
|
+
pushBranchName: z12.string().optional()
|
|
2100
4428
|
})
|
|
2101
4429
|
}).optional()
|
|
2102
4430
|
});
|
|
2103
|
-
var SubmitFixesToSameBranchResponseMessageZ =
|
|
2104
|
-
type:
|
|
2105
|
-
githubCommentId:
|
|
4431
|
+
var SubmitFixesToSameBranchResponseMessageZ = z12.object({
|
|
4432
|
+
type: z12.literal(submitToScmMessageType.commitToSameBranch),
|
|
4433
|
+
githubCommentId: z12.number().nullish()
|
|
2106
4434
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2107
|
-
var SubmitFixesToDifferentBranchResponseMessageZ =
|
|
2108
|
-
type:
|
|
2109
|
-
githubCommentId:
|
|
4435
|
+
var SubmitFixesToDifferentBranchResponseMessageZ = z12.object({
|
|
4436
|
+
type: z12.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
4437
|
+
githubCommentId: z12.number().optional()
|
|
2110
4438
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2111
|
-
var SubmitFixesResponseMessageZ =
|
|
4439
|
+
var SubmitFixesResponseMessageZ = z12.discriminatedUnion("type", [
|
|
2112
4440
|
SubmitFixesToSameBranchResponseMessageZ,
|
|
2113
4441
|
SubmitFixesToDifferentBranchResponseMessageZ
|
|
2114
4442
|
]);
|
|
@@ -2126,21 +4454,21 @@ var isValidBranchName = async (branchName) => {
|
|
|
2126
4454
|
return false;
|
|
2127
4455
|
}
|
|
2128
4456
|
};
|
|
2129
|
-
var FixesZ =
|
|
2130
|
-
|
|
2131
|
-
fixId:
|
|
2132
|
-
patches:
|
|
4457
|
+
var FixesZ = z13.array(
|
|
4458
|
+
z13.object({
|
|
4459
|
+
fixId: z13.string(),
|
|
4460
|
+
patches: z13.array(z13.string())
|
|
2133
4461
|
})
|
|
2134
4462
|
).nonempty();
|
|
2135
4463
|
|
|
2136
4464
|
// src/features/analysis/scm/scm.ts
|
|
2137
4465
|
function isBrokerUrl(url) {
|
|
2138
|
-
return
|
|
4466
|
+
return z14.string().uuid().safeParse(new URL(url).host).success;
|
|
2139
4467
|
}
|
|
2140
|
-
var GetRefererenceResultZ =
|
|
2141
|
-
date:
|
|
2142
|
-
sha:
|
|
2143
|
-
type:
|
|
4468
|
+
var GetRefererenceResultZ = z14.object({
|
|
4469
|
+
date: z14.date().optional(),
|
|
4470
|
+
sha: z14.string(),
|
|
4471
|
+
type: z14.nativeEnum(ReferenceType)
|
|
2144
4472
|
});
|
|
2145
4473
|
function getCloudScmLibTypeFromUrl(url) {
|
|
2146
4474
|
if (!url) {
|
|
@@ -2181,7 +4509,7 @@ var scmTypeToScmLibScmType = {
|
|
|
2181
4509
|
["Bitbucket" /* Bitbucket */]: "BITBUCKET" /* BITBUCKET */
|
|
2182
4510
|
};
|
|
2183
4511
|
function getScmLibTypeFromScmType(scmType) {
|
|
2184
|
-
const parsedScmType =
|
|
4512
|
+
const parsedScmType = z14.nativeEnum(ScmType).parse(scmType);
|
|
2185
4513
|
return scmTypeToScmLibScmType[parsedScmType];
|
|
2186
4514
|
}
|
|
2187
4515
|
function getScmConfig({
|
|
@@ -2395,7 +4723,7 @@ var SCMLib = class {
|
|
|
2395
4723
|
if (e instanceof InvalidRepoUrlError && url) {
|
|
2396
4724
|
throw new RepoNoTokenAccessError(
|
|
2397
4725
|
"no access to repo",
|
|
2398
|
-
scmLibScmTypeToScmType[
|
|
4726
|
+
scmLibScmTypeToScmType[z14.nativeEnum(ScmLibScmType).parse(scmType)]
|
|
2399
4727
|
);
|
|
2400
4728
|
}
|
|
2401
4729
|
console.error(`error validating scm: ${scmType} `, e);
|
|
@@ -2806,7 +5134,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2806
5134
|
owner,
|
|
2807
5135
|
repo
|
|
2808
5136
|
});
|
|
2809
|
-
return
|
|
5137
|
+
return z14.string().parse(prRes.data);
|
|
2810
5138
|
}
|
|
2811
5139
|
async getRepoList(_scmOrg) {
|
|
2812
5140
|
this._validateAccessToken();
|
|
@@ -2997,7 +5325,7 @@ var StubSCMLib = class extends SCMLib {
|
|
|
2997
5325
|
};
|
|
2998
5326
|
function getUserAndPassword(token) {
|
|
2999
5327
|
const [username, password] = token.split(":");
|
|
3000
|
-
const safePasswordAndUsername =
|
|
5328
|
+
const safePasswordAndUsername = z14.object({ username: z14.string(), password: z14.string() }).parse({ username, password });
|
|
3001
5329
|
return {
|
|
3002
5330
|
username: safePasswordAndUsername.username,
|
|
3003
5331
|
password: safePasswordAndUsername.password
|
|
@@ -3033,7 +5361,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3033
5361
|
return { username, password, authType };
|
|
3034
5362
|
}
|
|
3035
5363
|
case "token": {
|
|
3036
|
-
return { authType, token:
|
|
5364
|
+
return { authType, token: z14.string().parse(this.accessToken) };
|
|
3037
5365
|
}
|
|
3038
5366
|
case "public":
|
|
3039
5367
|
return { authType };
|
|
@@ -3045,7 +5373,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3045
5373
|
...params,
|
|
3046
5374
|
repoUrl: this.url
|
|
3047
5375
|
});
|
|
3048
|
-
return String(
|
|
5376
|
+
return String(z14.number().parse(pullRequestRes.id));
|
|
3049
5377
|
}
|
|
3050
5378
|
async validateParams() {
|
|
3051
5379
|
return validateBitbucketParams({
|
|
@@ -3117,7 +5445,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3117
5445
|
async getUsername() {
|
|
3118
5446
|
this._validateAccessToken();
|
|
3119
5447
|
const res = await this.bitbucketSdk.getUser();
|
|
3120
|
-
return
|
|
5448
|
+
return z14.string().parse(res.username);
|
|
3121
5449
|
}
|
|
3122
5450
|
async getSubmitRequestStatus(_scmSubmitRequestId) {
|
|
3123
5451
|
this._validateAccessTokenAndUrl();
|
|
@@ -3146,7 +5474,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3146
5474
|
async getRepoDefaultBranch() {
|
|
3147
5475
|
this._validateUrl();
|
|
3148
5476
|
const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
|
|
3149
|
-
return
|
|
5477
|
+
return z14.string().parse(repoRes.mainbranch?.name);
|
|
3150
5478
|
}
|
|
3151
5479
|
getPrUrl(prNumber) {
|
|
3152
5480
|
this._validateUrl();
|
|
@@ -3168,33 +5496,33 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3168
5496
|
};
|
|
3169
5497
|
|
|
3170
5498
|
// src/features/analysis/scm/ado/validation.ts
|
|
3171
|
-
import { z as
|
|
3172
|
-
var ValidPullRequestStatusZ =
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
5499
|
+
import { z as z15 } from "zod";
|
|
5500
|
+
var ValidPullRequestStatusZ = z15.union([
|
|
5501
|
+
z15.literal(1 /* Active */),
|
|
5502
|
+
z15.literal(2 /* Abandoned */),
|
|
5503
|
+
z15.literal(3 /* Completed */)
|
|
3176
5504
|
]);
|
|
3177
|
-
var AdoAuthResultZ =
|
|
3178
|
-
access_token:
|
|
3179
|
-
token_type:
|
|
3180
|
-
refresh_token:
|
|
5505
|
+
var AdoAuthResultZ = z15.object({
|
|
5506
|
+
access_token: z15.string().min(1),
|
|
5507
|
+
token_type: z15.string().min(1),
|
|
5508
|
+
refresh_token: z15.string().min(1)
|
|
3181
5509
|
});
|
|
3182
|
-
var profileZ =
|
|
3183
|
-
displayName:
|
|
3184
|
-
publicAlias:
|
|
3185
|
-
emailAddress:
|
|
3186
|
-
coreRevision:
|
|
3187
|
-
timeStamp:
|
|
3188
|
-
id:
|
|
3189
|
-
revision:
|
|
5510
|
+
var profileZ = z15.object({
|
|
5511
|
+
displayName: z15.string(),
|
|
5512
|
+
publicAlias: z15.string().min(1),
|
|
5513
|
+
emailAddress: z15.string(),
|
|
5514
|
+
coreRevision: z15.number(),
|
|
5515
|
+
timeStamp: z15.string(),
|
|
5516
|
+
id: z15.string(),
|
|
5517
|
+
revision: z15.number()
|
|
3190
5518
|
});
|
|
3191
|
-
var accountsZ =
|
|
3192
|
-
count:
|
|
3193
|
-
value:
|
|
3194
|
-
|
|
3195
|
-
accountId:
|
|
3196
|
-
accountUri:
|
|
3197
|
-
accountName:
|
|
5519
|
+
var accountsZ = z15.object({
|
|
5520
|
+
count: z15.number(),
|
|
5521
|
+
value: z15.array(
|
|
5522
|
+
z15.object({
|
|
5523
|
+
accountId: z15.string(),
|
|
5524
|
+
accountUri: z15.string(),
|
|
5525
|
+
accountName: z15.string()
|
|
3198
5526
|
})
|
|
3199
5527
|
)
|
|
3200
5528
|
});
|
|
@@ -3267,7 +5595,7 @@ async function getAdoConnectData({
|
|
|
3267
5595
|
oauthToken: adoTokenInfo.accessToken
|
|
3268
5596
|
});
|
|
3269
5597
|
return {
|
|
3270
|
-
org:
|
|
5598
|
+
org: z16.string().parse(org),
|
|
3271
5599
|
origin: DEFUALT_ADO_ORIGIN
|
|
3272
5600
|
};
|
|
3273
5601
|
}
|
|
@@ -3353,7 +5681,7 @@ async function getAdoClientParams(params) {
|
|
|
3353
5681
|
return {
|
|
3354
5682
|
tokenType: "PAT" /* PAT */,
|
|
3355
5683
|
accessToken: adoTokenInfo.accessToken,
|
|
3356
|
-
patTokenOrg:
|
|
5684
|
+
patTokenOrg: z16.string().parse(tokenOrg).toLowerCase(),
|
|
3357
5685
|
origin: origin2,
|
|
3358
5686
|
orgName: org.toLowerCase()
|
|
3359
5687
|
};
|
|
@@ -3707,175 +6035,10 @@ async function getAdoRepoList({
|
|
|
3707
6035
|
// src/features/analysis/scm/constants.ts
|
|
3708
6036
|
var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
|
|
3709
6037
|
|
|
3710
|
-
// src/constants.ts
|
|
3711
|
-
var debug = Debug("mobbdev:constants");
|
|
3712
|
-
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
3713
|
-
dotenv.config({ path: path2.join(__dirname, "../.env") });
|
|
3714
|
-
var scmFriendlyText = {
|
|
3715
|
-
["Ado" /* Ado */]: "Azure DevOps",
|
|
3716
|
-
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
3717
|
-
["GitHub" /* GitHub */]: "GitGub",
|
|
3718
|
-
["GitLab" /* GitLab */]: "GitLab"
|
|
3719
|
-
};
|
|
3720
|
-
var SCANNERS = {
|
|
3721
|
-
Checkmarx: "checkmarx",
|
|
3722
|
-
Codeql: "codeql",
|
|
3723
|
-
Fortify: "fortify",
|
|
3724
|
-
Snyk: "snyk",
|
|
3725
|
-
Sonarqube: "sonarqube"
|
|
3726
|
-
};
|
|
3727
|
-
var SupportedScannersZ = z11.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
3728
|
-
var envVariablesSchema = z11.object({
|
|
3729
|
-
WEB_APP_URL: z11.string(),
|
|
3730
|
-
API_URL: z11.string(),
|
|
3731
|
-
HASURA_ACCESS_KEY: z11.string(),
|
|
3732
|
-
LOCAL_GRAPHQL_ENDPOINT: z11.string()
|
|
3733
|
-
}).required();
|
|
3734
|
-
var envVariables = envVariablesSchema.parse(process.env);
|
|
3735
|
-
debug("config %o", envVariables);
|
|
3736
|
-
var mobbAscii = `
|
|
3737
|
-
..
|
|
3738
|
-
..........
|
|
3739
|
-
.................
|
|
3740
|
-
...........................
|
|
3741
|
-
..............................
|
|
3742
|
-
................................
|
|
3743
|
-
..................................
|
|
3744
|
-
....................................
|
|
3745
|
-
.....................................
|
|
3746
|
-
.............................................
|
|
3747
|
-
.................................................
|
|
3748
|
-
............................... .................
|
|
3749
|
-
.................................. ............
|
|
3750
|
-
.................. ............. ..........
|
|
3751
|
-
......... ........ ......... ......
|
|
3752
|
-
............... ....
|
|
3753
|
-
.... ..
|
|
3754
|
-
|
|
3755
|
-
. ...
|
|
3756
|
-
..............
|
|
3757
|
-
......................
|
|
3758
|
-
...........................
|
|
3759
|
-
................................
|
|
3760
|
-
......................................
|
|
3761
|
-
...............................
|
|
3762
|
-
.................
|
|
3763
|
-
`;
|
|
3764
|
-
var PROJECT_DEFAULT_NAME = "My first project";
|
|
3765
|
-
var WEB_APP_URL = envVariables.WEB_APP_URL;
|
|
3766
|
-
var API_URL = envVariables.API_URL;
|
|
3767
|
-
var HASURA_ACCESS_KEY = envVariables.HASURA_ACCESS_KEY;
|
|
3768
|
-
var LOCAL_GRAPHQL_ENDPOINT = envVariables.LOCAL_GRAPHQL_ENDPOINT;
|
|
3769
|
-
var errorMessages = {
|
|
3770
|
-
missingCxProjectName: `project name ${chalk.bold(
|
|
3771
|
-
"(--cx-project-name)"
|
|
3772
|
-
)} is needed if you're using checkmarx`,
|
|
3773
|
-
missingUrl: `url ${chalk.bold(
|
|
3774
|
-
"(--url)"
|
|
3775
|
-
)} is needed if you're adding an SCM token`,
|
|
3776
|
-
invalidScmType: `SCM type ${chalk.bold(
|
|
3777
|
-
"(--scm-type)"
|
|
3778
|
-
)} is invalid, please use one of: ${Object.values(ScmType).join(", ")}`,
|
|
3779
|
-
missingToken: `SCM token ${chalk.bold(
|
|
3780
|
-
"(--token)"
|
|
3781
|
-
)} is needed if you're adding an SCM token`
|
|
3782
|
-
};
|
|
3783
|
-
var progressMassages = {
|
|
3784
|
-
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
|
|
3785
|
-
processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
|
|
3786
|
-
processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
|
|
3787
|
-
};
|
|
3788
|
-
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 20;
|
|
3789
|
-
|
|
3790
|
-
// src/features/analysis/index.ts
|
|
3791
|
-
import crypto from "node:crypto";
|
|
3792
|
-
import fs3 from "node:fs";
|
|
3793
|
-
import os from "node:os";
|
|
3794
|
-
import path6 from "node:path";
|
|
3795
|
-
import { pipeline } from "node:stream/promises";
|
|
3796
|
-
|
|
3797
|
-
// src/utils/index.ts
|
|
3798
|
-
var utils_exports = {};
|
|
3799
|
-
__export(utils_exports, {
|
|
3800
|
-
CliError: () => CliError,
|
|
3801
|
-
Spinner: () => Spinner,
|
|
3802
|
-
getDirName: () => getDirName,
|
|
3803
|
-
getTopLevelDirName: () => getTopLevelDirName,
|
|
3804
|
-
keypress: () => keypress,
|
|
3805
|
-
sleep: () => sleep
|
|
3806
|
-
});
|
|
3807
|
-
|
|
3808
|
-
// src/utils/dirname.ts
|
|
3809
|
-
import path3 from "node:path";
|
|
3810
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3811
|
-
function getDirName() {
|
|
3812
|
-
return path3.dirname(fileURLToPath2(import.meta.url));
|
|
3813
|
-
}
|
|
3814
|
-
function getTopLevelDirName(fullPath) {
|
|
3815
|
-
return path3.parse(fullPath).name;
|
|
3816
|
-
}
|
|
3817
|
-
|
|
3818
|
-
// src/utils/keypress.ts
|
|
3819
|
-
import readline from "node:readline";
|
|
3820
|
-
async function keypress() {
|
|
3821
|
-
const rl = readline.createInterface({
|
|
3822
|
-
input: process.stdin,
|
|
3823
|
-
output: process.stdout
|
|
3824
|
-
});
|
|
3825
|
-
return new Promise((resolve) => {
|
|
3826
|
-
rl.question("", (answer) => {
|
|
3827
|
-
rl.close();
|
|
3828
|
-
process.stderr.moveCursor(0, -1);
|
|
3829
|
-
process.stderr.clearLine(1);
|
|
3830
|
-
resolve(answer);
|
|
3831
|
-
});
|
|
3832
|
-
});
|
|
3833
|
-
}
|
|
3834
|
-
|
|
3835
|
-
// src/utils/spinner.ts
|
|
3836
|
-
import {
|
|
3837
|
-
createSpinner as _createSpinner
|
|
3838
|
-
} from "nanospinner";
|
|
3839
|
-
var mockSpinner = {
|
|
3840
|
-
success: () => mockSpinner,
|
|
3841
|
-
error: () => mockSpinner,
|
|
3842
|
-
warn: () => mockSpinner,
|
|
3843
|
-
stop: () => mockSpinner,
|
|
3844
|
-
start: () => mockSpinner,
|
|
3845
|
-
update: () => mockSpinner,
|
|
3846
|
-
reset: () => mockSpinner,
|
|
3847
|
-
clear: () => mockSpinner,
|
|
3848
|
-
spin: () => mockSpinner
|
|
3849
|
-
};
|
|
3850
|
-
function Spinner({ ci = false } = {}) {
|
|
3851
|
-
return {
|
|
3852
|
-
createSpinner: (text, options) => ci ? mockSpinner : _createSpinner(text, options)
|
|
3853
|
-
};
|
|
3854
|
-
}
|
|
3855
|
-
|
|
3856
|
-
// src/utils/index.ts
|
|
3857
|
-
var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
|
|
3858
|
-
var CliError = class extends Error {
|
|
3859
|
-
};
|
|
3860
|
-
|
|
3861
|
-
// src/features/analysis/index.ts
|
|
3862
|
-
import chalk4 from "chalk";
|
|
3863
|
-
import Configstore from "configstore";
|
|
3864
|
-
import Debug13 from "debug";
|
|
3865
|
-
import extract from "extract-zip";
|
|
3866
|
-
import fetch4 from "node-fetch";
|
|
3867
|
-
import open2 from "open";
|
|
3868
|
-
import semver from "semver";
|
|
3869
|
-
import tmp2 from "tmp";
|
|
3870
|
-
import { z as z14 } from "zod";
|
|
3871
|
-
|
|
3872
|
-
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
3873
|
-
import Debug4 from "debug";
|
|
3874
|
-
|
|
3875
6038
|
// src/features/analysis/add_fix_comments_for_pr/utils.ts
|
|
3876
6039
|
import Debug3 from "debug";
|
|
3877
6040
|
import parseDiff2 from "parse-diff";
|
|
3878
|
-
import { z as
|
|
6041
|
+
import { z as z17 } from "zod";
|
|
3879
6042
|
|
|
3880
6043
|
// src/features/analysis/utils/by_key.ts
|
|
3881
6044
|
function keyBy(array, keyBy2) {
|
|
@@ -4052,10 +6215,23 @@ Refresh the page in order to see the changes.`,
|
|
|
4052
6215
|
redirectUrl: commentRes.data.html_url,
|
|
4053
6216
|
commentId
|
|
4054
6217
|
});
|
|
4055
|
-
const scanerString = scannerToFriendlyString[scanner];
|
|
4056
6218
|
const issueType = getIssueType(fix.issueType ?? null);
|
|
4057
6219
|
const title = `# ${MobbIconMarkdown} ${issueType} fix is ready`;
|
|
4058
|
-
const
|
|
6220
|
+
const patchAndQuestions = await PatchAndQuestionsZ.parseAsync(
|
|
6221
|
+
fix.patchAndQuestions
|
|
6222
|
+
);
|
|
6223
|
+
const subTitle = getCommitDescription({
|
|
6224
|
+
issueType: fix.issueType,
|
|
6225
|
+
vendor: scanner,
|
|
6226
|
+
severity: fix.vulnerabilitySeverity,
|
|
6227
|
+
issueLanguage: fix.issueLanguage,
|
|
6228
|
+
guidances: getGuidances({
|
|
6229
|
+
questions: patchAndQuestions.questions.map(toQuestion),
|
|
6230
|
+
issueType: fix.issueType,
|
|
6231
|
+
issueLanguage: fix.issueLanguage,
|
|
6232
|
+
fixExtraContext: patchAndQuestions.extraContext
|
|
6233
|
+
})
|
|
6234
|
+
});
|
|
4059
6235
|
const diff = `\`\`\`diff
|
|
4060
6236
|
${patch}
|
|
4061
6237
|
\`\`\``;
|
|
@@ -4107,7 +6283,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
|
|
|
4107
6283
|
});
|
|
4108
6284
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
4109
6285
|
const fileFilter = {
|
|
4110
|
-
path:
|
|
6286
|
+
path: z17.string().parse(file.to),
|
|
4111
6287
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
4112
6288
|
endLine,
|
|
4113
6289
|
startLine
|
|
@@ -4452,30 +6628,30 @@ function subscribe(query, variables, callback, wsClientOptions) {
|
|
|
4452
6628
|
}
|
|
4453
6629
|
|
|
4454
6630
|
// src/features/analysis/graphql/types.ts
|
|
4455
|
-
import { z as
|
|
4456
|
-
var VulnerabilityReportIssueCodeNodeZ =
|
|
4457
|
-
vulnerabilityReportIssueId:
|
|
4458
|
-
path:
|
|
4459
|
-
startLine:
|
|
4460
|
-
vulnerabilityReportIssue:
|
|
4461
|
-
fixId:
|
|
6631
|
+
import { z as z18 } from "zod";
|
|
6632
|
+
var VulnerabilityReportIssueCodeNodeZ = z18.object({
|
|
6633
|
+
vulnerabilityReportIssueId: z18.string(),
|
|
6634
|
+
path: z18.string(),
|
|
6635
|
+
startLine: z18.number(),
|
|
6636
|
+
vulnerabilityReportIssue: z18.object({
|
|
6637
|
+
fixId: z18.string()
|
|
4462
6638
|
})
|
|
4463
6639
|
});
|
|
4464
|
-
var GetVulByNodesMetadataZ =
|
|
4465
|
-
vulnerabilityReportIssueCodeNodes:
|
|
4466
|
-
nonFixablePrVuls:
|
|
4467
|
-
aggregate:
|
|
4468
|
-
count:
|
|
6640
|
+
var GetVulByNodesMetadataZ = z18.object({
|
|
6641
|
+
vulnerabilityReportIssueCodeNodes: z18.array(VulnerabilityReportIssueCodeNodeZ),
|
|
6642
|
+
nonFixablePrVuls: z18.object({
|
|
6643
|
+
aggregate: z18.object({
|
|
6644
|
+
count: z18.number()
|
|
4469
6645
|
})
|
|
4470
6646
|
}),
|
|
4471
|
-
fixablePrVuls:
|
|
4472
|
-
aggregate:
|
|
4473
|
-
count:
|
|
6647
|
+
fixablePrVuls: z18.object({
|
|
6648
|
+
aggregate: z18.object({
|
|
6649
|
+
count: z18.number()
|
|
4474
6650
|
})
|
|
4475
6651
|
}),
|
|
4476
|
-
totalScanVulnerabilities:
|
|
4477
|
-
aggregate:
|
|
4478
|
-
count:
|
|
6652
|
+
totalScanVulnerabilities: z18.object({
|
|
6653
|
+
aggregate: z18.object({
|
|
6654
|
+
count: z18.number()
|
|
4479
6655
|
})
|
|
4480
6656
|
})
|
|
4481
6657
|
});
|
|
@@ -5465,7 +7641,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5465
7641
|
spinner: mobbSpinner,
|
|
5466
7642
|
submitVulnerabilityReportVariables: {
|
|
5467
7643
|
fixReportId: reportUploadInfo.fixReportId,
|
|
5468
|
-
repoUrl:
|
|
7644
|
+
repoUrl: z19.string().parse(repo),
|
|
5469
7645
|
reference,
|
|
5470
7646
|
projectId,
|
|
5471
7647
|
vulnerabilityReportFileName: "report.json",
|
|
@@ -5704,9 +7880,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5704
7880
|
}
|
|
5705
7881
|
});
|
|
5706
7882
|
if (command === "review") {
|
|
5707
|
-
const params2 =
|
|
5708
|
-
repo:
|
|
5709
|
-
githubActionToken:
|
|
7883
|
+
const params2 = z19.object({
|
|
7884
|
+
repo: z19.string().url(),
|
|
7885
|
+
githubActionToken: z19.string()
|
|
5710
7886
|
}).parse({ repo, githubActionToken });
|
|
5711
7887
|
const scm = await SCMLib.init(
|
|
5712
7888
|
{
|
|
@@ -5728,7 +7904,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5728
7904
|
analysisId,
|
|
5729
7905
|
gqlClient,
|
|
5730
7906
|
scm,
|
|
5731
|
-
scanner:
|
|
7907
|
+
scanner: z19.nativeEnum(SCANNERS).parse(scanner)
|
|
5732
7908
|
});
|
|
5733
7909
|
},
|
|
5734
7910
|
callbackStates: ["Finished" /* Finished */]
|
|
@@ -5955,7 +8131,7 @@ var scmTokenOption = {
|
|
|
5955
8131
|
// src/args/validation.ts
|
|
5956
8132
|
import chalk6 from "chalk";
|
|
5957
8133
|
import path8 from "path";
|
|
5958
|
-
import { z as
|
|
8134
|
+
import { z as z20 } from "zod";
|
|
5959
8135
|
function throwRepoUrlErrorMessage({
|
|
5960
8136
|
error,
|
|
5961
8137
|
repoUrl,
|
|
@@ -5972,13 +8148,13 @@ Example:
|
|
|
5972
8148
|
)}`;
|
|
5973
8149
|
throw new CliError(formattedErrorMessage);
|
|
5974
8150
|
}
|
|
5975
|
-
var UrlZ =
|
|
8151
|
+
var UrlZ = z20.string({
|
|
5976
8152
|
invalid_type_error: `is not a valid ${Object.values(ScmType).join("/ ")} URL`
|
|
5977
8153
|
}).refine((data) => !!sanityRepoURL(data), {
|
|
5978
8154
|
message: `is not a valid ${Object.values(ScmType).join(" / ")} URL`
|
|
5979
8155
|
});
|
|
5980
8156
|
function validateOrganizationId(organizationId) {
|
|
5981
|
-
const orgIdValidation =
|
|
8157
|
+
const orgIdValidation = z20.string().uuid().nullish().safeParse(organizationId);
|
|
5982
8158
|
if (!orgIdValidation.success) {
|
|
5983
8159
|
throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
|
|
5984
8160
|
}
|