@auth0/auth0-checkmate 1.4.0
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/.github/CODEOWNERS +1 -0
- package/.github/workflows/npm-release.yml +77 -0
- package/.github/workflows/sca_scan.yml +10 -0
- package/.github/workflows/test.yml +48 -0
- package/AUTHORS +5 -0
- package/LICENSE +203 -0
- package/README.md +166 -0
- package/THIRD-PARTY-NOTICES +226 -0
- package/analyzer/lib/actions/checkActionsHardCodedValues.js +151 -0
- package/analyzer/lib/actions/checkActionsRuntime.js +105 -0
- package/analyzer/lib/actions/checkDependencies.js +111 -0
- package/analyzer/lib/attack_protection/checkBotDetectionSetting.js +76 -0
- package/analyzer/lib/attack_protection/checkBreachedPassword.js +140 -0
- package/analyzer/lib/attack_protection/checkBruteForce.js +89 -0
- package/analyzer/lib/attack_protection/checkSuspiciousIPThrottling.js +89 -0
- package/analyzer/lib/canonical_domain/checkCanonicalDomain.js +63 -0
- package/analyzer/lib/clients/checkAllowedCallbacks.js +122 -0
- package/analyzer/lib/clients/checkAllowedLogoutUrl.js +124 -0
- package/analyzer/lib/clients/checkApplicationLoginUri.js +125 -0
- package/analyzer/lib/clients/checkCrossOriginAuthentication.js +91 -0
- package/analyzer/lib/clients/checkGrantTypes.js +138 -0
- package/analyzer/lib/clients/checkJWTSignAlg.js +118 -0
- package/analyzer/lib/clients/checkRefreshToken.js +108 -0
- package/analyzer/lib/clients/checkWebOrigins.js +55 -0
- package/analyzer/lib/constants.js +63 -0
- package/analyzer/lib/custom_domain/checkCustomDomain.js +53 -0
- package/analyzer/lib/databases/checkAuthenticationMethods.js +98 -0
- package/analyzer/lib/databases/checkDASHardCodedValues.js +163 -0
- package/analyzer/lib/databases/checkEmailAttributeVerification.js +114 -0
- package/analyzer/lib/databases/checkEnabledDatabaseCustomization.js +83 -0
- package/analyzer/lib/databases/checkPasswordComplexity.js +100 -0
- package/analyzer/lib/databases/checkPasswordHistory.js +92 -0
- package/analyzer/lib/databases/checkPasswordNoPersonalInfo.js +91 -0
- package/analyzer/lib/databases/checkPasswordPolicy.js +95 -0
- package/analyzer/lib/databases/checkPromotedDBConnection.js +96 -0
- package/analyzer/lib/email_provider/checkEmailProvider.js +37 -0
- package/analyzer/lib/email_templates/checkEmailTemplates.js +71 -0
- package/analyzer/lib/error_page_template/checkErrorPageTemplate.js +153 -0
- package/analyzer/lib/event_streams/checkEventStreams.js +71 -0
- package/analyzer/lib/executeCheck.js +12 -0
- package/analyzer/lib/hooks/checkHooks.js +43 -0
- package/analyzer/lib/listOfAnalyser.js +24 -0
- package/analyzer/lib/log_streams/checkLogStream.js +60 -0
- package/analyzer/lib/logger.js +16 -0
- package/analyzer/lib/multifactor/checkGuardianFactors.js +72 -0
- package/analyzer/lib/multifactor/checkGuardianPolicy.js +40 -0
- package/analyzer/lib/network_acl/checkNetworkACL.js +35 -0
- package/analyzer/lib/rules/checkRules.js +102 -0
- package/analyzer/lib/tenant_settings/checkDefaultAudience.js +53 -0
- package/analyzer/lib/tenant_settings/checkDefaultDirectory.js +48 -0
- package/analyzer/lib/tenant_settings/checkEnabledDynamicClientRegistration.js +60 -0
- package/analyzer/lib/tenant_settings/checkSandboxVersion.js +37 -0
- package/analyzer/lib/tenant_settings/checkSessionLifetime.js +95 -0
- package/analyzer/lib/tenant_settings/checkSupportEmail.js +61 -0
- package/analyzer/lib/tenant_settings/checkSupportUrl.js +61 -0
- package/analyzer/lib/tenant_settings/checkTenantLoginUrl.js +71 -0
- package/analyzer/lib/tenant_settings/checkTenantLogoutUrl.js +60 -0
- package/analyzer/report.js +404 -0
- package/analyzer/tools/auth0.js +443 -0
- package/analyzer/tools/helpers.js +71 -0
- package/analyzer/tools/summary.js +84 -0
- package/analyzer/tools/utils.js +72 -0
- package/bin/index.js +393 -0
- package/eslint.config.mjs +16 -0
- package/images/auth0.png +0 -0
- package/images/okta.png +0 -0
- package/locales/en.json +1417 -0
- package/package.json +66 -0
- package/tests/actions/checkActionsHardCodedValues.test.js +106 -0
- package/tests/actions/checkActionsRuntime.test.js +102 -0
- package/tests/actions/checkDependencies.test.js +131 -0
- package/tests/attack_protection/checkBreachedPassword.test.js +253 -0
- package/tests/attack_protection/checkBruteForce.test.js +181 -0
- package/tests/attack_protection/checkSuspiciousIPThrottling.test.js +222 -0
- package/tests/canonical_domain/checkCanonicalDomain.test.js +94 -0
- package/tests/clients/checkAllowedCallbacks.test.js +149 -0
- package/tests/clients/checkAllowedLogoutUrl.test.js +149 -0
- package/tests/clients/checkApplicationLoginUri.test.js +180 -0
- package/tests/clients/checkCrossOriginAuthentication.test.js +99 -0
- package/tests/clients/checkGrantTypes.test.js +154 -0
- package/tests/clients/checkJWTSignAlg.test.js +121 -0
- package/tests/clients/checkRefreshToken.test.js +63 -0
- package/tests/clients/checkWebOrigins.test.js +140 -0
- package/tests/custom_domain/checkCustomDomain.test.js +73 -0
- package/tests/databases/checkAuthenticationMethods.test.js +124 -0
- package/tests/databases/checkDASHardCodedValues.test.js +77 -0
- package/tests/databases/checkEmailAttributeVerification.test.js +79 -0
- package/tests/databases/checkEnabledDatabaseCustomization.test.js +68 -0
- package/tests/databases/checkPasswordComplexity.test.js +127 -0
- package/tests/databases/checkPasswordHistory.test.js +100 -0
- package/tests/databases/checkPasswordNoPersonalInfo.test.js +94 -0
- package/tests/databases/checkPasswordPolicy.test.js +161 -0
- package/tests/databases/checkPromotedDBConnection.test.js +62 -0
- package/tests/email_provider/checkEmailProvider.test.js +58 -0
- package/tests/email_templates/checkEmailTemplates.test.js +120 -0
- package/tests/error_page_template/checkErrorPageTemplate.test.js +315 -0
- package/tests/event_streams/checkEventStreams.test.js +118 -0
- package/tests/hooks/checkHooks.test.js +112 -0
- package/tests/log_streams/checkLogStream.test.js +140 -0
- package/tests/multifactor/checkGuardianFactors.test.js +94 -0
- package/tests/multifactor/checkGuardianPolicy.test.js +49 -0
- package/tests/rules/checkRules.test.js +102 -0
- package/tests/tenant_settings/checkDefaultAudience.test.js +62 -0
- package/tests/tenant_settings/checkDefaultDirectory.test.js +62 -0
- package/tests/tenant_settings/checkEnabledDynamicClientRegistration.test.js +97 -0
- package/tests/tenant_settings/checkSandboxVersion.test.js +50 -0
- package/tests/tenant_settings/checkSessionLifetime.test.js +108 -0
- package/tests/tenant_settings/checkSupportEmail.test.js +77 -0
- package/tests/tenant_settings/checkSupportUrl.test.js +77 -0
- package/tests/tenant_settings/checkTenantLoginUri.test.js +82 -0
- package/tests/tenant_settings/checkTenantLogoutUrl.test.js +108 -0
- package/tests/tools/auth0.test.js +833 -0
- package/tests/tools/helpers.test.js +692 -0
- package/views/pdf_cli_report.handlebars +571 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
const { expect } = require("chai");
|
|
2
|
+
const checkBruteForce = require("../../analyzer/lib/attack_protection/checkBruteForce");
|
|
3
|
+
const CONSTANTS = require("../../analyzer/lib/constants");
|
|
4
|
+
|
|
5
|
+
describe("checkBruteForce", function () {
|
|
6
|
+
it("should return success when brute force protection is enabled and correctly configured", function () {
|
|
7
|
+
const options = {
|
|
8
|
+
attackProtection: {
|
|
9
|
+
bruteForceProtection: {
|
|
10
|
+
enabled: true,
|
|
11
|
+
shields: ["block", "user_notification"],
|
|
12
|
+
mode: "count_per_identifier_and_ip",
|
|
13
|
+
allowlist: [],
|
|
14
|
+
max_attempts: 3,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
checkBruteForce(options, (report) => {
|
|
20
|
+
// Check if the report contains expected success statuses
|
|
21
|
+
expect(report).to.deep.include({
|
|
22
|
+
field: "enabled",
|
|
23
|
+
status: CONSTANTS.SUCCESS,
|
|
24
|
+
});
|
|
25
|
+
expect(report).to.deep.include({
|
|
26
|
+
field: "shieldsConfigured",
|
|
27
|
+
status: CONSTANTS.SUCCESS,
|
|
28
|
+
});
|
|
29
|
+
expect(report).to.deep.include({
|
|
30
|
+
field: "allowlistEmpty",
|
|
31
|
+
status: CONSTANTS.SUCCESS,
|
|
32
|
+
});
|
|
33
|
+
expect(report).to.deep.include({
|
|
34
|
+
field: "stageMaxAttempts",
|
|
35
|
+
status: CONSTANTS.SUCCESS,
|
|
36
|
+
value: 3,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should return failure when brute force protection is disabled", function () {
|
|
42
|
+
const options = {
|
|
43
|
+
attackProtection: {
|
|
44
|
+
bruteForceProtection: {
|
|
45
|
+
enabled: false,
|
|
46
|
+
shields: ["block"],
|
|
47
|
+
mode: "count_per_identifier_and_ip",
|
|
48
|
+
allowlist: [],
|
|
49
|
+
max_attempts: 3,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
checkBruteForce(options, (report) => {
|
|
55
|
+
expect(report).to.deep.include({
|
|
56
|
+
field: "disabled",
|
|
57
|
+
status: CONSTANTS.FAIL,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should return failure when shields have missing values", function () {
|
|
63
|
+
const options = {
|
|
64
|
+
attackProtection: {
|
|
65
|
+
bruteForceProtection: {
|
|
66
|
+
enabled: true,
|
|
67
|
+
shields: ["block"], // Missing "user_notification"
|
|
68
|
+
mode: "count_per_identifier_and_ip",
|
|
69
|
+
allowlist: [],
|
|
70
|
+
max_attempts: 3,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
checkBruteForce(options, (report) => {
|
|
76
|
+
expect(report).to.deep.include({
|
|
77
|
+
field: "shieldsMissing",
|
|
78
|
+
status: CONSTANTS.FAIL,
|
|
79
|
+
value: "user_notification",
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("should return failure when allowlist is not empty", function () {
|
|
85
|
+
const options = {
|
|
86
|
+
attackProtection: {
|
|
87
|
+
bruteForceProtection: {
|
|
88
|
+
enabled: true,
|
|
89
|
+
shields: ["block", "user_notification"],
|
|
90
|
+
mode: "count_per_identifier_and_ip",
|
|
91
|
+
allowlist: ["127.0.0.1"],
|
|
92
|
+
max_attempts: 3,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
checkBruteForce(options, (report) => {
|
|
98
|
+
expect(report).to.deep.include({
|
|
99
|
+
field: "allowlistPresent",
|
|
100
|
+
status: CONSTANTS.FAIL,
|
|
101
|
+
value: "127.0.0.1",
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should return failure when max_attempts is less than or equal to 0", function () {
|
|
107
|
+
const options = {
|
|
108
|
+
attackProtection: {
|
|
109
|
+
bruteForceProtection: {
|
|
110
|
+
enabled: true,
|
|
111
|
+
shields: ["block", "user_notification"],
|
|
112
|
+
mode: "count_per_identifier_and_ip",
|
|
113
|
+
allowlist: [],
|
|
114
|
+
max_attempts: 0, // Invalid value
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
checkBruteForce(options, (report) => {
|
|
120
|
+
expect(report).to.deep.include({
|
|
121
|
+
field: "stageMaxAttemptsInvalid",
|
|
122
|
+
status: CONSTANTS.FAIL,
|
|
123
|
+
value: 0,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should return failure when rate is less than or equal to 0", function () {
|
|
129
|
+
const options = {
|
|
130
|
+
attackProtection: {
|
|
131
|
+
bruteForceProtection: {
|
|
132
|
+
enabled: true,
|
|
133
|
+
shields: ["block", "user_notification"],
|
|
134
|
+
mode: "count_per_identifier_and_ip",
|
|
135
|
+
allowlist: [],
|
|
136
|
+
max_attempts: 3,
|
|
137
|
+
stage: {
|
|
138
|
+
"pre-user-registration": {
|
|
139
|
+
rate: 0, // Invalid value
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
checkBruteForce(options, (report) => {
|
|
147
|
+
expect(report).to.deep.include({
|
|
148
|
+
field: "stageRateInvalid",
|
|
149
|
+
status: CONSTANTS.FAIL,
|
|
150
|
+
value: 0,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("should return success when rate is valid", function () {
|
|
156
|
+
const options = {
|
|
157
|
+
attackProtection: {
|
|
158
|
+
bruteForceProtection: {
|
|
159
|
+
enabled: true,
|
|
160
|
+
shields: ["block", "user_notification"],
|
|
161
|
+
mode: "count_per_identifier_and_ip",
|
|
162
|
+
allowlist: [],
|
|
163
|
+
max_attempts: 3,
|
|
164
|
+
stage: {
|
|
165
|
+
"pre-user-registration": {
|
|
166
|
+
rate: 5, // Valid value
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
checkBruteForce(options, (report) => {
|
|
174
|
+
expect(report).to.deep.include({
|
|
175
|
+
field: "stageRate",
|
|
176
|
+
status: CONSTANTS.SUCCESS,
|
|
177
|
+
value: 5,
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
const { expect } = require("chai");
|
|
2
|
+
const checkSuspiciousIPThrottling = require("../../analyzer/lib/attack_protection/checkSuspiciousIPThrottling");
|
|
3
|
+
const CONSTANTS = require("../../analyzer/lib/constants");
|
|
4
|
+
|
|
5
|
+
describe("checkSuspiciousIPThrottling", function () {
|
|
6
|
+
it("should return success when suspicious IP throttling is enabled and correctly configured", function () {
|
|
7
|
+
const options = {
|
|
8
|
+
attackProtection: {
|
|
9
|
+
suspiciousIpThrottling: {
|
|
10
|
+
enabled: true,
|
|
11
|
+
shields: ["admin_notification", "block"],
|
|
12
|
+
allowlist: [],
|
|
13
|
+
stage: {
|
|
14
|
+
"pre-login": {
|
|
15
|
+
max_attempts: 100,
|
|
16
|
+
rate: 864000,
|
|
17
|
+
},
|
|
18
|
+
"pre-user-registration": {
|
|
19
|
+
max_attempts: 50,
|
|
20
|
+
rate: 1200,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
28
|
+
// Check if the report contains expected success statuses
|
|
29
|
+
expect(report).to.deep.include({
|
|
30
|
+
field: "enabled",
|
|
31
|
+
status: CONSTANTS.SUCCESS,
|
|
32
|
+
});
|
|
33
|
+
expect(report).to.deep.include({
|
|
34
|
+
field: "shieldsConfigured",
|
|
35
|
+
status: CONSTANTS.SUCCESS,
|
|
36
|
+
});
|
|
37
|
+
expect(report).to.deep.include({
|
|
38
|
+
field: "allowlistEmpty",
|
|
39
|
+
status: CONSTANTS.SUCCESS,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should return failure when suspicious IP throttling is disabled", function () {
|
|
45
|
+
const options = {
|
|
46
|
+
attackProtection: {
|
|
47
|
+
suspiciousIpThrottling: {
|
|
48
|
+
enabled: false,
|
|
49
|
+
shields: ["block"],
|
|
50
|
+
allowlist: [],
|
|
51
|
+
stage: {
|
|
52
|
+
"pre-login": {
|
|
53
|
+
max_attempts: 100,
|
|
54
|
+
rate: 864000,
|
|
55
|
+
},
|
|
56
|
+
"pre-user-registration": {
|
|
57
|
+
max_attempts: 50,
|
|
58
|
+
rate: 1200,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
66
|
+
expect(report).to.deep.include({
|
|
67
|
+
field: "disabled",
|
|
68
|
+
status: CONSTANTS.FAIL,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should return failure when shields are missing values", function () {
|
|
74
|
+
const options = {
|
|
75
|
+
attackProtection: {
|
|
76
|
+
suspiciousIpThrottling: {
|
|
77
|
+
enabled: true,
|
|
78
|
+
shields: ["block"], // Missing "admin_notification"
|
|
79
|
+
allowlist: [],
|
|
80
|
+
stage: {
|
|
81
|
+
"pre-login": {
|
|
82
|
+
max_attempts: 100,
|
|
83
|
+
rate: 864000,
|
|
84
|
+
},
|
|
85
|
+
"pre-user-registration": {
|
|
86
|
+
max_attempts: 50,
|
|
87
|
+
rate: 1200,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
95
|
+
expect(report).to.deep.include({
|
|
96
|
+
field: "shieldsMissing",
|
|
97
|
+
status: CONSTANTS.FAIL,
|
|
98
|
+
value: "admin_notification",
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("should return failure when allowlist is not empty", function () {
|
|
104
|
+
const options = {
|
|
105
|
+
attackProtection: {
|
|
106
|
+
suspiciousIpThrottling: {
|
|
107
|
+
enabled: true,
|
|
108
|
+
shields: ["block", "admin_notification"],
|
|
109
|
+
allowlist: ["192.168.0.1"],
|
|
110
|
+
stage: {
|
|
111
|
+
"pre-login": {
|
|
112
|
+
max_attempts: 100,
|
|
113
|
+
rate: 864000,
|
|
114
|
+
},
|
|
115
|
+
"pre-user-registration": {
|
|
116
|
+
max_attempts: 50,
|
|
117
|
+
rate: 1200,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
125
|
+
expect(report).to.deep.include({
|
|
126
|
+
field: "allowlistPresent",
|
|
127
|
+
status: CONSTANTS.FAIL,
|
|
128
|
+
value: "192.168.0.1",
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("should return failure when max_attempts is less than or equal to 0", function () {
|
|
134
|
+
const options = {
|
|
135
|
+
attackProtection: {
|
|
136
|
+
suspiciousIpThrottling: {
|
|
137
|
+
enabled: true,
|
|
138
|
+
shields: ["block", "admin_notification"],
|
|
139
|
+
allowlist: [],
|
|
140
|
+
stage: {
|
|
141
|
+
"pre-login": {
|
|
142
|
+
max_attempts: 0, // Invalid value
|
|
143
|
+
rate: 864000,
|
|
144
|
+
},
|
|
145
|
+
"pre-user-registration": {
|
|
146
|
+
max_attempts: 50,
|
|
147
|
+
rate: 1200,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
155
|
+
expect(report).to.deep.include({
|
|
156
|
+
field: "stageMaxAttemptsInvalid",
|
|
157
|
+
status: CONSTANTS.FAIL,
|
|
158
|
+
value: 0,
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("should return failure when rate is less than or equal to 0", function () {
|
|
164
|
+
const options = {
|
|
165
|
+
attackProtection: {
|
|
166
|
+
suspiciousIpThrottling: {
|
|
167
|
+
enabled: true,
|
|
168
|
+
shields: ["block", "admin_notification"],
|
|
169
|
+
allowlist: [],
|
|
170
|
+
stage: {
|
|
171
|
+
"pre-login": {
|
|
172
|
+
max_attempts: 100,
|
|
173
|
+
rate: 0, // Invalid value
|
|
174
|
+
},
|
|
175
|
+
"pre-user-registration": {
|
|
176
|
+
max_attempts: 50,
|
|
177
|
+
rate: 1200,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
185
|
+
expect(report).to.deep.include({
|
|
186
|
+
field: "stageRateInvalid",
|
|
187
|
+
status: CONSTANTS.FAIL,
|
|
188
|
+
value: 0,
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("should return success when rate is valid", function () {
|
|
194
|
+
const options = {
|
|
195
|
+
attackProtection: {
|
|
196
|
+
suspiciousIpThrottling: {
|
|
197
|
+
enabled: true,
|
|
198
|
+
shields: ["block", "admin_notification"],
|
|
199
|
+
allowlist: [],
|
|
200
|
+
stage: {
|
|
201
|
+
"pre-login": {
|
|
202
|
+
max_attempts: 100,
|
|
203
|
+
rate: 864000, // Valid value
|
|
204
|
+
},
|
|
205
|
+
"pre-user-registration": {
|
|
206
|
+
max_attempts: 50,
|
|
207
|
+
rate: 1200,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
checkSuspiciousIPThrottling(options, (report) => {
|
|
215
|
+
expect(report).to.deep.include({
|
|
216
|
+
field: "stageRate",
|
|
217
|
+
status: CONSTANTS.SUCCESS,
|
|
218
|
+
value: 864000,
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const chai = require("chai");
|
|
2
|
+
const expect = chai.expect;
|
|
3
|
+
const checkCanonicalDomain = require("../../analyzer/lib/canonical_domain/checkCanonicalDomain");
|
|
4
|
+
const CONSTANTS = require("../../analyzer/lib/constants");
|
|
5
|
+
|
|
6
|
+
describe("checkCanonicalDomain", function () {
|
|
7
|
+
it("should add the hostname to report if logs are not empty but customDomains is empty", function () {
|
|
8
|
+
const options = {
|
|
9
|
+
customDomains: [], // Empty customDomains
|
|
10
|
+
logs: [
|
|
11
|
+
{
|
|
12
|
+
type: "s",
|
|
13
|
+
hostname: "contoso.us.auth0.com",
|
|
14
|
+
_id: "90020250210004837491441000000000000001223372036874609060",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
checkCanonicalDomain(options, (report) => {
|
|
20
|
+
// Check that the report contains the hostname from logs
|
|
21
|
+
expect(report).to.have.lengthOf(1);
|
|
22
|
+
expect(report[0].field).to.equal("canonical_domain_used");
|
|
23
|
+
expect(report[0].value).to.equal(
|
|
24
|
+
"log_id: 90020250210004837491441000000000000001223372036874609060",
|
|
25
|
+
);
|
|
26
|
+
expect(report[0].status).to.equal(CONSTANTS.FAIL);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should add the hostname to report if no match is found in customDomains", function () {
|
|
31
|
+
const options = {
|
|
32
|
+
customDomains: [
|
|
33
|
+
{
|
|
34
|
+
domain: "different.com",
|
|
35
|
+
primary: true,
|
|
36
|
+
status: "ready",
|
|
37
|
+
tls_policy: "recommended",
|
|
38
|
+
type: "auth0_managed_certs",
|
|
39
|
+
verification: {},
|
|
40
|
+
},
|
|
41
|
+
], // Custom domain is different
|
|
42
|
+
logs: [
|
|
43
|
+
{
|
|
44
|
+
type: "s",
|
|
45
|
+
hostname: "contoso.us.auth0.com",
|
|
46
|
+
_id: "90020250210004837491441000000000000001223372036874609060",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
checkCanonicalDomain(options, (report) => {
|
|
52
|
+
// Check that the report contains the hostname from logs because there is no match
|
|
53
|
+
expect(report).to.have.lengthOf(1);
|
|
54
|
+
expect(report[0].field).to.equal("canonical_domain_used");
|
|
55
|
+
expect(report[0].value).to.equal(
|
|
56
|
+
"log_id: 90020250210004837491441000000000000001223372036874609060",
|
|
57
|
+
);
|
|
58
|
+
expect(report[0].status).to.equal(CONSTANTS.FAIL);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should return an empty report if logs are empty", function () {
|
|
63
|
+
const options = {
|
|
64
|
+
customDomains: [
|
|
65
|
+
{
|
|
66
|
+
domain: "contoso.com",
|
|
67
|
+
primary: true,
|
|
68
|
+
status: "ready",
|
|
69
|
+
tls_policy: "recommended",
|
|
70
|
+
type: "auth0_managed_certs",
|
|
71
|
+
verification: {},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
logs: [], // No logs
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
checkCanonicalDomain(options, (report) => {
|
|
78
|
+
// Check that the report is empty
|
|
79
|
+
expect(report).to.be.an("array").that.is.empty;
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should not add anything to the report if customDomains are empty and no logs exist", function () {
|
|
84
|
+
const options = {
|
|
85
|
+
customDomains: [], // No custom domains
|
|
86
|
+
logs: [], // No logs
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
checkCanonicalDomain(options, (report) => {
|
|
90
|
+
// Check that the report is empty
|
|
91
|
+
expect(report).to.be.an("array").that.is.empty;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const chai = require("chai");
|
|
2
|
+
const expect = chai.expect;
|
|
3
|
+
|
|
4
|
+
const checkAllowedCallbacks = require("../../analyzer/lib/clients/checkAllowedCallbacks");
|
|
5
|
+
const CONSTANTS = require("../../analyzer/lib/constants");
|
|
6
|
+
|
|
7
|
+
describe("checkAllowedCallbacks", function () {
|
|
8
|
+
it("should return an empty report when there are no clients", function () {
|
|
9
|
+
const options = {
|
|
10
|
+
clients: [], // No clients
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
checkAllowedCallbacks(options, (reports) => {
|
|
14
|
+
expect(reports).to.deep.equal([]); // No reports expected
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should return a fail report when client has no callbacks and app_type is not non_interactive", function () {
|
|
19
|
+
const options = {
|
|
20
|
+
clients: [
|
|
21
|
+
{
|
|
22
|
+
name: "Test App",
|
|
23
|
+
client_id: "client_id",
|
|
24
|
+
app_type: "spa", // Not non_interactive
|
|
25
|
+
callbacks: [], // No callbacks
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
checkAllowedCallbacks(options, (reports) => {
|
|
31
|
+
expect(reports).to.deep.equal([
|
|
32
|
+
{
|
|
33
|
+
name: "Test App",
|
|
34
|
+
report: [
|
|
35
|
+
{
|
|
36
|
+
name: "Test App",
|
|
37
|
+
client_id: "client_id",
|
|
38
|
+
field: "missing_callbacks",
|
|
39
|
+
url: "",
|
|
40
|
+
status: CONSTANTS.FAIL,
|
|
41
|
+
app_type: "spa",
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should return a fail report when client has insecure callbacks (http://localhost)", function () {
|
|
50
|
+
const options = {
|
|
51
|
+
clients: [
|
|
52
|
+
{
|
|
53
|
+
name: "Test App",
|
|
54
|
+
client_id: "client_id",
|
|
55
|
+
callbacks: ["http://localhost:3000"], // Insecure callback URL
|
|
56
|
+
app_type: "spa",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
checkAllowedCallbacks(options, (reports) => {
|
|
62
|
+
expect(reports).to.deep.equal([
|
|
63
|
+
{
|
|
64
|
+
name: "Test App",
|
|
65
|
+
report: [
|
|
66
|
+
{
|
|
67
|
+
name: "Test App",
|
|
68
|
+
client_id: "client_id",
|
|
69
|
+
field: "insecure_callbacks",
|
|
70
|
+
url: "http://localhost:3000",
|
|
71
|
+
status: CONSTANTS.FAIL,
|
|
72
|
+
app_type: "spa",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should return a success report when client has secure callbacks (https://contoso.com)", function () {
|
|
81
|
+
const options = {
|
|
82
|
+
clients: [
|
|
83
|
+
{
|
|
84
|
+
name: "Test App",
|
|
85
|
+
client_id: "client_id",
|
|
86
|
+
callbacks: ["https://contoso.com"], // Secure callback URL
|
|
87
|
+
app_type: "spa",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
checkAllowedCallbacks(options, (reports) => {
|
|
93
|
+
expect(reports).to.deep.equal([
|
|
94
|
+
{
|
|
95
|
+
name: "Test App",
|
|
96
|
+
report: [
|
|
97
|
+
{
|
|
98
|
+
name: "Test App",
|
|
99
|
+
client_id: "client_id",
|
|
100
|
+
field: "secure_callbacks",
|
|
101
|
+
status: CONSTANTS.SUCCESS,
|
|
102
|
+
url: "https://contoso.com",
|
|
103
|
+
app_type: "spa",
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
]);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should return both fail and success reports when client has both insecure and secure callbacks", function () {
|
|
112
|
+
const options = {
|
|
113
|
+
clients: [
|
|
114
|
+
{
|
|
115
|
+
name: "Test App",
|
|
116
|
+
client_id: "client_id",
|
|
117
|
+
callbacks: ["http://localhost:3000", "https://contoso.com"], // Mix of insecure and secure URLs
|
|
118
|
+
app_type: "spa",
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
checkAllowedCallbacks(options, (reports) => {
|
|
124
|
+
expect(reports).to.deep.equal([
|
|
125
|
+
{
|
|
126
|
+
name: "Test App",
|
|
127
|
+
report: [
|
|
128
|
+
{
|
|
129
|
+
name: "Test App",
|
|
130
|
+
client_id: "client_id",
|
|
131
|
+
field: "insecure_callbacks",
|
|
132
|
+
url: "http://localhost:3000",
|
|
133
|
+
status: CONSTANTS.FAIL,
|
|
134
|
+
app_type: "spa",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "Test App",
|
|
138
|
+
client_id: "client_id",
|
|
139
|
+
field: "secure_callbacks",
|
|
140
|
+
status: CONSTANTS.SUCCESS,
|
|
141
|
+
url: "https://contoso.com",
|
|
142
|
+
app_type: "spa",
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|