"use strict"; /** * FuzzingEngine — orchestrates fuzzing strategies for form inputs. * Implements IFuzzingPlugin so ExplorationEngine doesn't need to import it directly. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FuzzingEngine = void 0; const crypto = __importStar(require("crypto")); const InputTypeDetector_1 = require("./InputTypeDetector"); const EmptyValueStrategy_1 = require("./strategies/EmptyValueStrategy"); const OversizedStringStrategy_1 = require("./strategies/OversizedStringStrategy"); const SpecialCharsStrategy_1 = require("./strategies/SpecialCharsStrategy"); const TypeMismatchStrategy_1 = require("./strategies/TypeMismatchStrategy"); const BoundaryValueStrategy_1 = require("./strategies/BoundaryValueStrategy"); /** Regex to match basic input elements in an HTML string */ const INPUT_RE = /<(input|textarea|select)[^>]*>/gi; const ATTR_RE = (name) => new RegExp(`${name}="([^"]*)"`, 'i'); function extractFields(domSnapshot) { const fields = []; let match; while ((match = INPUT_RE.exec(domSnapshot)) !== null) { const tag = match[0] ?? ''; const tagName = match[1] ?? 'input'; const idMatch = ATTR_RE('id').exec(tag); const nameMatch = ATTR_RE('name').exec(tag); const typeMatch = ATTR_RE('type').exec(tag); const placeholderMatch = ATTR_RE('placeholder').exec(tag); const ariaMatch = ATTR_RE('aria-label').exec(tag); const selector = idMatch?.[1] ? `#${idMatch[1]}` : nameMatch?.[1] ? `[name="${nameMatch[1]}"]` : tagName; fields.push({ selector, tagName, inputType: typeMatch?.[1], name: nameMatch?.[1], placeholder: placeholderMatch?.[1], ariaLabel: ariaMatch?.[1], }); } return fields; } class FuzzingEngine { constructor(config) { this.intensity = config.intensity; this.seed = config.seed; } /** IFuzzingPlugin implementation — parses fields from DOM snapshot */ generateFuzzActions(domSnapshot, state) { const fields = extractFields(domSnapshot); return this.generateFuzzActionsForFields(fields, state); } /** Generate fuzz actions from explicit field descriptors */ generateFuzzActionsForFields(fields, state) { const actions = []; const now = Date.now(); const strategies = this.selectStrategies(); for (const field of fields) { const detectedType = (0, InputTypeDetector_1.detectInputType)({ tagName: field.tagName, inputType: field.inputType, name: field.name, placeholder: field.placeholder, ariaLabel: field.ariaLabel, }); for (const strategy of strategies) { const values = this.getValuesFromStrategy(strategy, detectedType); for (const value of values) { actions.push({ id: crypto.randomUUID(), type: 'fill', selector: field.selector, value, timestamp: now, seed: this.seed, stateId: state.id, }); } } } return actions; } selectStrategies() { const empty = new EmptyValueStrategy_1.EmptyValueStrategy(); const typeMismatch = new TypeMismatchStrategy_1.TypeMismatchStrategy(); const oversized = new OversizedStringStrategy_1.OversizedStringStrategy(this.intensity); const boundary = new BoundaryValueStrategy_1.BoundaryValueStrategy(); const special = new SpecialCharsStrategy_1.SpecialCharsStrategy(); switch (this.intensity) { case 'low': return [empty, typeMismatch]; case 'medium': return [empty, typeMismatch, oversized, boundary]; case 'high': return [empty, typeMismatch, oversized, boundary, special]; } } getValuesFromStrategy(strategy, type) { if (!strategy.appliesTo(type)) return []; return strategy.values(type); } } exports.FuzzingEngine = FuzzingEngine;