(config: Config)
| 399 | }; |
| 400 | |
| 401 | const performSecurityValidation = (config: Config): void => { |
| 402 | if (config.authentication) { |
| 403 | const auth = config.authentication; |
| 404 | |
| 405 | // Check login_url for dangerous patterns (AJV's "uri" format allows javascript: per RFC 3986) |
| 406 | if (auth.login_url) { |
| 407 | for (const pattern of DANGEROUS_PATTERNS) { |
| 408 | if (pattern.test(auth.login_url)) { |
| 409 | throw new PentestError( |
| 410 | `authentication.login_url contains potentially dangerous pattern: ${pattern.source}`, |
| 411 | 'config', |
| 412 | false, |
| 413 | { field: 'login_url', pattern: pattern.source }, |
| 414 | ErrorCode.CONFIG_VALIDATION_FAILED, |
| 415 | ); |
| 416 | } |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | if (auth.credentials) { |
| 421 | for (const pattern of DANGEROUS_PATTERNS) { |
| 422 | if (pattern.test(auth.credentials.username)) { |
| 423 | throw new PentestError( |
| 424 | `authentication.credentials.username contains potentially dangerous pattern: ${pattern.source}`, |
| 425 | 'config', |
| 426 | false, |
| 427 | { field: 'credentials.username', pattern: pattern.source }, |
| 428 | ErrorCode.CONFIG_VALIDATION_FAILED, |
| 429 | ); |
| 430 | } |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | if (auth.login_flow) { |
| 435 | auth.login_flow.forEach((step, index) => { |
| 436 | for (const pattern of DANGEROUS_PATTERNS) { |
| 437 | if (pattern.test(step)) { |
| 438 | throw new PentestError( |
| 439 | `authentication.login_flow[${index}] contains potentially dangerous pattern: ${pattern.source}`, |
| 440 | 'config', |
| 441 | false, |
| 442 | { field: `login_flow[${index}]`, pattern: pattern.source }, |
| 443 | ErrorCode.CONFIG_VALIDATION_FAILED, |
| 444 | ); |
| 445 | } |
| 446 | } |
| 447 | }); |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | if (config.rules) { |
| 452 | validateRulesSecurity(config.rules.avoid, 'avoid'); |
| 453 | validateRulesSecurity(config.rules.focus, 'focus'); |
| 454 | |
| 455 | checkForDuplicates(config.rules.avoid || [], 'avoid'); |
| 456 | checkForDuplicates(config.rules.focus || [], 'focus'); |
| 457 | checkForConflicts(config.rules.avoid, config.rules.focus); |
| 458 | } |
no test coverage detected