deepseek-coder-cli 1.0.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/LICENSE +21 -0
- package/README.md +422 -0
- package/agents/agi-code.rules.json +87 -0
- package/agents/general.rules.json +171 -0
- package/dist/bin/cliMode.d.ts +8 -0
- package/dist/bin/cliMode.d.ts.map +1 -0
- package/dist/bin/cliMode.js +20 -0
- package/dist/bin/cliMode.js.map +1 -0
- package/dist/bin/deepseek.d.ts +16 -0
- package/dist/bin/deepseek.d.ts.map +1 -0
- package/dist/bin/deepseek.js +737 -0
- package/dist/bin/deepseek.js.map +1 -0
- package/dist/bin/erosolar.d.ts +7 -0
- package/dist/bin/erosolar.d.ts.map +1 -0
- package/dist/bin/erosolar.js +7 -0
- package/dist/bin/erosolar.js.map +1 -0
- package/dist/bin/selfTest.d.ts +14 -0
- package/dist/bin/selfTest.d.ts.map +1 -0
- package/dist/bin/selfTest.js +304 -0
- package/dist/bin/selfTest.js.map +1 -0
- package/dist/capabilities/appleSecurityCapability.d.ts +57 -0
- package/dist/capabilities/appleSecurityCapability.d.ts.map +1 -0
- package/dist/capabilities/appleSecurityCapability.js +197 -0
- package/dist/capabilities/appleSecurityCapability.js.map +1 -0
- package/dist/capabilities/authorizedSecurityCapability.d.ts +17 -0
- package/dist/capabilities/authorizedSecurityCapability.d.ts.map +1 -0
- package/dist/capabilities/authorizedSecurityCapability.js +333 -0
- package/dist/capabilities/authorizedSecurityCapability.js.map +1 -0
- package/dist/capabilities/autoEnhancementCapability.d.ts +98 -0
- package/dist/capabilities/autoEnhancementCapability.d.ts.map +1 -0
- package/dist/capabilities/autoEnhancementCapability.js +455 -0
- package/dist/capabilities/autoEnhancementCapability.js.map +1 -0
- package/dist/capabilities/baseCapability.d.ts +72 -0
- package/dist/capabilities/baseCapability.d.ts.map +1 -0
- package/dist/capabilities/baseCapability.js +183 -0
- package/dist/capabilities/baseCapability.js.map +1 -0
- package/dist/capabilities/bashCapability.d.ts +13 -0
- package/dist/capabilities/bashCapability.d.ts.map +1 -0
- package/dist/capabilities/bashCapability.js +24 -0
- package/dist/capabilities/bashCapability.js.map +1 -0
- package/dist/capabilities/biocognitiveWarfare.d.ts +136 -0
- package/dist/capabilities/biocognitiveWarfare.d.ts.map +1 -0
- package/dist/capabilities/biocognitiveWarfare.js +603 -0
- package/dist/capabilities/biocognitiveWarfare.js.map +1 -0
- package/dist/capabilities/chineseCnoIntegration.d.ts +60 -0
- package/dist/capabilities/chineseCnoIntegration.d.ts.map +1 -0
- package/dist/capabilities/chineseCnoIntegration.js +253 -0
- package/dist/capabilities/chineseCnoIntegration.js.map +1 -0
- package/dist/capabilities/cnoCapability.d.ts +110 -0
- package/dist/capabilities/cnoCapability.d.ts.map +1 -0
- package/dist/capabilities/cnoCapability.js +785 -0
- package/dist/capabilities/cnoCapability.js.map +1 -0
- package/dist/capabilities/editCapability.d.ts +17 -0
- package/dist/capabilities/editCapability.d.ts.map +1 -0
- package/dist/capabilities/editCapability.js +27 -0
- package/dist/capabilities/editCapability.js.map +1 -0
- package/dist/capabilities/eliteCryptoMilitaryCapability.d.ts +99 -0
- package/dist/capabilities/eliteCryptoMilitaryCapability.d.ts.map +1 -0
- package/dist/capabilities/eliteCryptoMilitaryCapability.js +618 -0
- package/dist/capabilities/eliteCryptoMilitaryCapability.js.map +1 -0
- package/dist/capabilities/enhancedGitCapability.d.ts +7 -0
- package/dist/capabilities/enhancedGitCapability.d.ts.map +1 -0
- package/dist/capabilities/enhancedGitCapability.js +220 -0
- package/dist/capabilities/enhancedGitCapability.js.map +1 -0
- package/dist/capabilities/filesystemCapability.d.ts +13 -0
- package/dist/capabilities/filesystemCapability.d.ts.map +1 -0
- package/dist/capabilities/filesystemCapability.js +24 -0
- package/dist/capabilities/filesystemCapability.js.map +1 -0
- package/dist/capabilities/gitHistoryCapability.d.ts +6 -0
- package/dist/capabilities/gitHistoryCapability.d.ts.map +1 -0
- package/dist/capabilities/gitHistoryCapability.js +160 -0
- package/dist/capabilities/gitHistoryCapability.js.map +1 -0
- package/dist/capabilities/index.d.ts +26 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +26 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/integratedUnifiedCapability.d.ts +105 -0
- package/dist/capabilities/integratedUnifiedCapability.d.ts.map +1 -0
- package/dist/capabilities/integratedUnifiedCapability.js +422 -0
- package/dist/capabilities/integratedUnifiedCapability.js.map +1 -0
- package/dist/capabilities/maxOffensiveUkraineCapability.d.ts +46 -0
- package/dist/capabilities/maxOffensiveUkraineCapability.d.ts.map +1 -0
- package/dist/capabilities/maxOffensiveUkraineCapability.js +725 -0
- package/dist/capabilities/maxOffensiveUkraineCapability.js.map +1 -0
- package/dist/capabilities/migrationUtilities.d.ts +128 -0
- package/dist/capabilities/migrationUtilities.d.ts.map +1 -0
- package/dist/capabilities/migrationUtilities.js +658 -0
- package/dist/capabilities/migrationUtilities.js.map +1 -0
- package/dist/capabilities/offensiveDestructionCapability.d.ts +98 -0
- package/dist/capabilities/offensiveDestructionCapability.d.ts.map +1 -0
- package/dist/capabilities/offensiveDestructionCapability.js +848 -0
- package/dist/capabilities/offensiveDestructionCapability.js.map +1 -0
- package/dist/capabilities/quantumSpaceWarfare.d.ts +108 -0
- package/dist/capabilities/quantumSpaceWarfare.d.ts.map +1 -0
- package/dist/capabilities/quantumSpaceWarfare.js +342 -0
- package/dist/capabilities/quantumSpaceWarfare.js.map +1 -0
- package/dist/capabilities/readmeIntegration.d.ts +161 -0
- package/dist/capabilities/readmeIntegration.d.ts.map +1 -0
- package/dist/capabilities/readmeIntegration.js +1034 -0
- package/dist/capabilities/readmeIntegration.js.map +1 -0
- package/dist/capabilities/searchCapability.d.ts +19 -0
- package/dist/capabilities/searchCapability.d.ts.map +1 -0
- package/dist/capabilities/searchCapability.js +29 -0
- package/dist/capabilities/searchCapability.js.map +1 -0
- package/dist/capabilities/selfUpdateSystem.d.ts +122 -0
- package/dist/capabilities/selfUpdateSystem.d.ts.map +1 -0
- package/dist/capabilities/selfUpdateSystem.js +725 -0
- package/dist/capabilities/selfUpdateSystem.js.map +1 -0
- package/dist/capabilities/sharedMilitaryInfrastructure.d.ts +89 -0
- package/dist/capabilities/sharedMilitaryInfrastructure.d.ts.map +1 -0
- package/dist/capabilities/sharedMilitaryInfrastructure.js +233 -0
- package/dist/capabilities/sharedMilitaryInfrastructure.js.map +1 -0
- package/dist/capabilities/simpleSecurityCapability.d.ts +36 -0
- package/dist/capabilities/simpleSecurityCapability.d.ts.map +1 -0
- package/dist/capabilities/simpleSecurityCapability.js +271 -0
- package/dist/capabilities/simpleSecurityCapability.js.map +1 -0
- package/dist/capabilities/toolManifest.d.ts +3 -0
- package/dist/capabilities/toolManifest.d.ts.map +1 -0
- package/dist/capabilities/toolManifest.js +163 -0
- package/dist/capabilities/toolManifest.js.map +1 -0
- package/dist/capabilities/toolRegistry.d.ts +25 -0
- package/dist/capabilities/toolRegistry.d.ts.map +1 -0
- package/dist/capabilities/toolRegistry.js +150 -0
- package/dist/capabilities/toolRegistry.js.map +1 -0
- package/dist/capabilities/ultimateChineseCno.d.ts +115 -0
- package/dist/capabilities/ultimateChineseCno.d.ts.map +1 -0
- package/dist/capabilities/ultimateChineseCno.js +516 -0
- package/dist/capabilities/ultimateChineseCno.js.map +1 -0
- package/dist/capabilities/ultimateIntegrationDemo.d.ts +54 -0
- package/dist/capabilities/ultimateIntegrationDemo.d.ts.map +1 -0
- package/dist/capabilities/ultimateIntegrationDemo.js +423 -0
- package/dist/capabilities/ultimateIntegrationDemo.js.map +1 -0
- package/dist/capabilities/unifiedMilitaryCapability.d.ts +63 -0
- package/dist/capabilities/unifiedMilitaryCapability.d.ts.map +1 -0
- package/dist/capabilities/unifiedMilitaryCapability.js +384 -0
- package/dist/capabilities/unifiedMilitaryCapability.js.map +1 -0
- package/dist/capabilities/universalCapabilityFramework.d.ts +352 -0
- package/dist/capabilities/universalCapabilityFramework.d.ts.map +1 -0
- package/dist/capabilities/universalCapabilityFramework.js +1056 -0
- package/dist/capabilities/universalCapabilityFramework.js.map +1 -0
- package/dist/capabilities/universalSecurityCapability.d.ts +46 -0
- package/dist/capabilities/universalSecurityCapability.d.ts.map +1 -0
- package/dist/capabilities/universalSecurityCapability.js +580 -0
- package/dist/capabilities/universalSecurityCapability.js.map +1 -0
- package/dist/capabilities/webCapability.d.ts +23 -0
- package/dist/capabilities/webCapability.d.ts.map +1 -0
- package/dist/capabilities/webCapability.js +33 -0
- package/dist/capabilities/webCapability.js.map +1 -0
- package/dist/capabilities/zeroDayDiscoveryCapability.d.ts +31 -0
- package/dist/capabilities/zeroDayDiscoveryCapability.d.ts.map +1 -0
- package/dist/capabilities/zeroDayDiscoveryCapability.js +183 -0
- package/dist/capabilities/zeroDayDiscoveryCapability.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +155 -0
- package/dist/config.js.map +1 -0
- package/dist/contracts/agent-profiles.schema.json +43 -0
- package/dist/contracts/agent-schemas.json +466 -0
- package/dist/contracts/models.schema.json +9 -0
- package/dist/contracts/module-schema.json +430 -0
- package/dist/contracts/schemas/agent-profile.schema.json +157 -0
- package/dist/contracts/schemas/agent-rules.schema.json +238 -0
- package/dist/contracts/schemas/agent-schemas.schema.json +528 -0
- package/dist/contracts/schemas/agent.schema.json +90 -0
- package/dist/contracts/schemas/tool-selection.schema.json +174 -0
- package/dist/contracts/tools.schema.json +82 -0
- package/dist/contracts/unified-schema.json +757 -0
- package/dist/contracts/v1/agent.d.ts +179 -0
- package/dist/contracts/v1/agent.d.ts.map +1 -0
- package/dist/contracts/v1/agent.js +8 -0
- package/dist/contracts/v1/agent.js.map +1 -0
- package/dist/contracts/v1/agentProfileManifest.d.ts +60 -0
- package/dist/contracts/v1/agentProfileManifest.d.ts.map +1 -0
- package/dist/contracts/v1/agentProfileManifest.js +9 -0
- package/dist/contracts/v1/agentProfileManifest.js.map +1 -0
- package/dist/contracts/v1/agentRules.d.ts +60 -0
- package/dist/contracts/v1/agentRules.d.ts.map +1 -0
- package/dist/contracts/v1/agentRules.js +10 -0
- package/dist/contracts/v1/agentRules.js.map +1 -0
- package/dist/contracts/v1/provider.d.ts +149 -0
- package/dist/contracts/v1/provider.d.ts.map +1 -0
- package/dist/contracts/v1/provider.js +7 -0
- package/dist/contracts/v1/provider.js.map +1 -0
- package/dist/contracts/v1/tool.d.ts +136 -0
- package/dist/contracts/v1/tool.d.ts.map +1 -0
- package/dist/contracts/v1/tool.js +7 -0
- package/dist/contracts/v1/tool.js.map +1 -0
- package/dist/contracts/v1/toolAccess.d.ts +43 -0
- package/dist/contracts/v1/toolAccess.d.ts.map +1 -0
- package/dist/contracts/v1/toolAccess.js +9 -0
- package/dist/contracts/v1/toolAccess.js.map +1 -0
- package/dist/core/agent.d.ts +287 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +1563 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/agentProfileManifest.d.ts +3 -0
- package/dist/core/agentProfileManifest.d.ts.map +1 -0
- package/dist/core/agentProfileManifest.js +188 -0
- package/dist/core/agentProfileManifest.js.map +1 -0
- package/dist/core/agentProfiles.d.ts +22 -0
- package/dist/core/agentProfiles.d.ts.map +1 -0
- package/dist/core/agentProfiles.js +35 -0
- package/dist/core/agentProfiles.js.map +1 -0
- package/dist/core/agentRulebook.d.ts +11 -0
- package/dist/core/agentRulebook.d.ts.map +1 -0
- package/dist/core/agentRulebook.js +136 -0
- package/dist/core/agentRulebook.js.map +1 -0
- package/dist/core/agentSchemaLoader.d.ts +131 -0
- package/dist/core/agentSchemaLoader.d.ts.map +1 -0
- package/dist/core/agentSchemaLoader.js +235 -0
- package/dist/core/agentSchemaLoader.js.map +1 -0
- package/dist/core/agiCore.d.ts +290 -0
- package/dist/core/agiCore.d.ts.map +1 -0
- package/dist/core/agiCore.js +1348 -0
- package/dist/core/agiCore.js.map +1 -0
- package/dist/core/aiErrorFixer.d.ts +57 -0
- package/dist/core/aiErrorFixer.d.ts.map +1 -0
- package/dist/core/aiErrorFixer.js +214 -0
- package/dist/core/aiErrorFixer.js.map +1 -0
- package/dist/core/antiTermination.d.ts +226 -0
- package/dist/core/antiTermination.d.ts.map +1 -0
- package/dist/core/antiTermination.js +713 -0
- package/dist/core/antiTermination.js.map +1 -0
- package/dist/core/appleSecurityAudit.d.ts +98 -0
- package/dist/core/appleSecurityAudit.d.ts.map +1 -0
- package/dist/core/appleSecurityAudit.js +505 -0
- package/dist/core/appleSecurityAudit.js.map +1 -0
- package/dist/core/appleSecurityIntegration.d.ts +130 -0
- package/dist/core/appleSecurityIntegration.d.ts.map +1 -0
- package/dist/core/appleSecurityIntegration.js +697 -0
- package/dist/core/appleSecurityIntegration.js.map +1 -0
- package/dist/core/bashCommandGuidance.d.ts +16 -0
- package/dist/core/bashCommandGuidance.d.ts.map +1 -0
- package/dist/core/bashCommandGuidance.js +40 -0
- package/dist/core/bashCommandGuidance.js.map +1 -0
- package/dist/core/constants.d.ts +31 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +62 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/contextManager.d.ts +271 -0
- package/dist/core/contextManager.d.ts.map +1 -0
- package/dist/core/contextManager.js +1073 -0
- package/dist/core/contextManager.js.map +1 -0
- package/dist/core/contextWindow.d.ts +42 -0
- package/dist/core/contextWindow.d.ts.map +1 -0
- package/dist/core/contextWindow.js +123 -0
- package/dist/core/contextWindow.js.map +1 -0
- package/dist/core/customCommands.d.ts +19 -0
- package/dist/core/customCommands.d.ts.map +1 -0
- package/dist/core/customCommands.js +85 -0
- package/dist/core/customCommands.js.map +1 -0
- package/dist/core/deepBugAnalyzer.d.ts +25 -0
- package/dist/core/deepBugAnalyzer.d.ts.map +1 -0
- package/dist/core/deepBugAnalyzer.js +44 -0
- package/dist/core/deepBugAnalyzer.js.map +1 -0
- package/dist/core/dualTournament.d.ts +110 -0
- package/dist/core/dualTournament.d.ts.map +1 -0
- package/dist/core/dualTournament.js +270 -0
- package/dist/core/dualTournament.js.map +1 -0
- package/dist/core/dynamicGuardrails.d.ts +207 -0
- package/dist/core/dynamicGuardrails.d.ts.map +1 -0
- package/dist/core/dynamicGuardrails.js +516 -0
- package/dist/core/dynamicGuardrails.js.map +1 -0
- package/dist/core/embeddingProviders.d.ts +80 -0
- package/dist/core/embeddingProviders.d.ts.map +1 -0
- package/dist/core/embeddingProviders.js +241 -0
- package/dist/core/embeddingProviders.js.map +1 -0
- package/dist/core/episodicMemory.d.ts +259 -0
- package/dist/core/episodicMemory.d.ts.map +1 -0
- package/dist/core/episodicMemory.js +833 -0
- package/dist/core/episodicMemory.js.map +1 -0
- package/dist/core/errors/apiKeyErrors.d.ts +11 -0
- package/dist/core/errors/apiKeyErrors.d.ts.map +1 -0
- package/dist/core/errors/apiKeyErrors.js +159 -0
- package/dist/core/errors/apiKeyErrors.js.map +1 -0
- package/dist/core/errors/errorTypes.d.ts +111 -0
- package/dist/core/errors/errorTypes.d.ts.map +1 -0
- package/dist/core/errors/errorTypes.js +345 -0
- package/dist/core/errors/errorTypes.js.map +1 -0
- package/dist/core/errors/index.d.ts +50 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/core/errors/index.js +156 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/errors/networkErrors.d.ts +14 -0
- package/dist/core/errors/networkErrors.d.ts.map +1 -0
- package/dist/core/errors/networkErrors.js +53 -0
- package/dist/core/errors/networkErrors.js.map +1 -0
- package/dist/core/errors/safetyValidator.d.ts +115 -0
- package/dist/core/errors/safetyValidator.d.ts.map +1 -0
- package/dist/core/errors/safetyValidator.js +302 -0
- package/dist/core/errors/safetyValidator.js.map +1 -0
- package/dist/core/errors.d.ts +4 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +33 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/finalResponseFormatter.d.ts +10 -0
- package/dist/core/finalResponseFormatter.d.ts.map +1 -0
- package/dist/core/finalResponseFormatter.js +14 -0
- package/dist/core/finalResponseFormatter.js.map +1 -0
- package/dist/core/flowProtection.d.ts +154 -0
- package/dist/core/flowProtection.d.ts.map +1 -0
- package/dist/core/flowProtection.js +436 -0
- package/dist/core/flowProtection.js.map +1 -0
- package/dist/core/gitWorktreeManager.d.ts +126 -0
- package/dist/core/gitWorktreeManager.d.ts.map +1 -0
- package/dist/core/gitWorktreeManager.js +403 -0
- package/dist/core/gitWorktreeManager.js.map +1 -0
- package/dist/core/guardrails.d.ts +150 -0
- package/dist/core/guardrails.d.ts.map +1 -0
- package/dist/core/guardrails.js +360 -0
- package/dist/core/guardrails.js.map +1 -0
- package/dist/core/hallucinationGuard.d.ts +57 -0
- package/dist/core/hallucinationGuard.d.ts.map +1 -0
- package/dist/core/hallucinationGuard.js +237 -0
- package/dist/core/hallucinationGuard.js.map +1 -0
- package/dist/core/hooks.d.ts +113 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +364 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/hotReload.d.ts +154 -0
- package/dist/core/hotReload.d.ts.map +1 -0
- package/dist/core/hotReload.js +451 -0
- package/dist/core/hotReload.js.map +1 -0
- package/dist/core/hypothesisEngine.d.ts +27 -0
- package/dist/core/hypothesisEngine.d.ts.map +1 -0
- package/dist/core/hypothesisEngine.js +58 -0
- package/dist/core/hypothesisEngine.js.map +1 -0
- package/dist/core/index.d.ts +26 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +54 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/inputProtection.d.ts +122 -0
- package/dist/core/inputProtection.d.ts.map +1 -0
- package/dist/core/inputProtection.js +421 -0
- package/dist/core/inputProtection.js.map +1 -0
- package/dist/core/liveGCPVerification.d.ts +41 -0
- package/dist/core/liveGCPVerification.d.ts.map +1 -0
- package/dist/core/liveGCPVerification.js +745 -0
- package/dist/core/liveGCPVerification.js.map +1 -0
- package/dist/core/modelDiscovery.d.ts +105 -0
- package/dist/core/modelDiscovery.d.ts.map +1 -0
- package/dist/core/modelDiscovery.js +740 -0
- package/dist/core/modelDiscovery.js.map +1 -0
- package/dist/core/multilinePasteHandler.d.ts +35 -0
- package/dist/core/multilinePasteHandler.d.ts.map +1 -0
- package/dist/core/multilinePasteHandler.js +80 -0
- package/dist/core/multilinePasteHandler.js.map +1 -0
- package/dist/core/parallel.d.ts +85 -0
- package/dist/core/parallel.d.ts.map +1 -0
- package/dist/core/parallel.js +150 -0
- package/dist/core/parallel.js.map +1 -0
- package/dist/core/parallelCoordinator.d.ts +21 -0
- package/dist/core/parallelCoordinator.d.ts.map +1 -0
- package/dist/core/parallelCoordinator.js +42 -0
- package/dist/core/parallelCoordinator.js.map +1 -0
- package/dist/core/parallelExecutor.d.ts +215 -0
- package/dist/core/parallelExecutor.d.ts.map +1 -0
- package/dist/core/parallelExecutor.js +584 -0
- package/dist/core/parallelExecutor.js.map +1 -0
- package/dist/core/preferences.d.ts +71 -0
- package/dist/core/preferences.d.ts.map +1 -0
- package/dist/core/preferences.js +341 -0
- package/dist/core/preferences.js.map +1 -0
- package/dist/core/productTestHarness.d.ts +46 -0
- package/dist/core/productTestHarness.d.ts.map +1 -0
- package/dist/core/productTestHarness.js +128 -0
- package/dist/core/productTestHarness.js.map +1 -0
- package/dist/core/providerKeys.d.ts +20 -0
- package/dist/core/providerKeys.d.ts.map +1 -0
- package/dist/core/providerKeys.js +40 -0
- package/dist/core/providerKeys.js.map +1 -0
- package/dist/core/realityScore.d.ts +159 -0
- package/dist/core/realityScore.d.ts.map +1 -0
- package/dist/core/realityScore.js +734 -0
- package/dist/core/realityScore.js.map +1 -0
- package/dist/core/repoUpgradeOrchestrator.d.ts +223 -0
- package/dist/core/repoUpgradeOrchestrator.d.ts.map +1 -0
- package/dist/core/repoUpgradeOrchestrator.js +1003 -0
- package/dist/core/repoUpgradeOrchestrator.js.map +1 -0
- package/dist/core/resultVerification.d.ts +47 -0
- package/dist/core/resultVerification.d.ts.map +1 -0
- package/dist/core/resultVerification.js +126 -0
- package/dist/core/resultVerification.js.map +1 -0
- package/dist/core/revenueEnvValidator.d.ts +30 -0
- package/dist/core/revenueEnvValidator.d.ts.map +1 -0
- package/dist/core/revenueEnvValidator.js +241 -0
- package/dist/core/revenueEnvValidator.js.map +1 -0
- package/dist/core/schemaValidator.d.ts +49 -0
- package/dist/core/schemaValidator.d.ts.map +1 -0
- package/dist/core/schemaValidator.js +234 -0
- package/dist/core/schemaValidator.js.map +1 -0
- package/dist/core/secretStore.d.ts +48 -0
- package/dist/core/secretStore.d.ts.map +1 -0
- package/dist/core/secretStore.js +295 -0
- package/dist/core/secretStore.js.map +1 -0
- package/dist/core/securityTournament.d.ts +83 -0
- package/dist/core/securityTournament.d.ts.map +1 -0
- package/dist/core/securityTournament.js +357 -0
- package/dist/core/securityTournament.js.map +1 -0
- package/dist/core/selfUpgrade.d.ts +253 -0
- package/dist/core/selfUpgrade.d.ts.map +1 -0
- package/dist/core/selfUpgrade.js +669 -0
- package/dist/core/selfUpgrade.js.map +1 -0
- package/dist/core/sessionStorage.d.ts +10 -0
- package/dist/core/sessionStorage.d.ts.map +1 -0
- package/dist/core/sessionStorage.js +46 -0
- package/dist/core/sessionStorage.js.map +1 -0
- package/dist/core/sessionStore.d.ts +35 -0
- package/dist/core/sessionStore.d.ts.map +1 -0
- package/dist/core/sessionStore.js +191 -0
- package/dist/core/sessionStore.js.map +1 -0
- package/dist/core/taskCompletionDetector.d.ts +112 -0
- package/dist/core/taskCompletionDetector.d.ts.map +1 -0
- package/dist/core/taskCompletionDetector.js +469 -0
- package/dist/core/taskCompletionDetector.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts +34 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -0
- package/dist/core/toolPreconditions.js +242 -0
- package/dist/core/toolPreconditions.js.map +1 -0
- package/dist/core/toolRuntime.d.ts +185 -0
- package/dist/core/toolRuntime.d.ts.map +1 -0
- package/dist/core/toolRuntime.js +412 -0
- package/dist/core/toolRuntime.js.map +1 -0
- package/dist/core/tournamentStrategy.d.ts +12 -0
- package/dist/core/tournamentStrategy.d.ts.map +1 -0
- package/dist/core/tournamentStrategy.js +41 -0
- package/dist/core/tournamentStrategy.js.map +1 -0
- package/dist/core/types/utilityTypes.d.ts +192 -0
- package/dist/core/types/utilityTypes.d.ts.map +1 -0
- package/dist/core/types/utilityTypes.js +272 -0
- package/dist/core/types/utilityTypes.js.map +1 -0
- package/dist/core/types.d.ts +334 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +76 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/unifiedOrchestrator.d.ts +47 -0
- package/dist/core/unifiedOrchestrator.d.ts.map +1 -0
- package/dist/core/unifiedOrchestrator.js +103 -0
- package/dist/core/unifiedOrchestrator.js.map +1 -0
- package/dist/core/universalSecurityAudit.d.ts +104 -0
- package/dist/core/universalSecurityAudit.d.ts.map +1 -0
- package/dist/core/universalSecurityAudit.js +2190 -0
- package/dist/core/universalSecurityAudit.js.map +1 -0
- package/dist/core/updateChecker.d.ts +148 -0
- package/dist/core/updateChecker.d.ts.map +1 -0
- package/dist/core/updateChecker.js +593 -0
- package/dist/core/updateChecker.js.map +1 -0
- package/dist/core/variantExecution.d.ts +23 -0
- package/dist/core/variantExecution.d.ts.map +1 -0
- package/dist/core/variantExecution.js +58 -0
- package/dist/core/variantExecution.js.map +1 -0
- package/dist/core/winnerStrategy.d.ts +15 -0
- package/dist/core/winnerStrategy.d.ts.map +1 -0
- package/dist/core/winnerStrategy.js +18 -0
- package/dist/core/winnerStrategy.js.map +1 -0
- package/dist/core/zeroDayDiscovery.d.ts +96 -0
- package/dist/core/zeroDayDiscovery.d.ts.map +1 -0
- package/dist/core/zeroDayDiscovery.js +358 -0
- package/dist/core/zeroDayDiscovery.js.map +1 -0
- package/dist/headless/interactiveShell.d.ts +22 -0
- package/dist/headless/interactiveShell.d.ts.map +1 -0
- package/dist/headless/interactiveShell.js +3799 -0
- package/dist/headless/interactiveShell.js.map +1 -0
- package/dist/headless/quickMode.d.ts +26 -0
- package/dist/headless/quickMode.d.ts.map +1 -0
- package/dist/headless/quickMode.js +226 -0
- package/dist/headless/quickMode.js.map +1 -0
- package/dist/orchestration/index.d.ts +10 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +13 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/repoUpgradeRunner.d.ts +44 -0
- package/dist/orchestration/repoUpgradeRunner.d.ts.map +1 -0
- package/dist/orchestration/repoUpgradeRunner.js +375 -0
- package/dist/orchestration/repoUpgradeRunner.js.map +1 -0
- package/dist/orchestration/securityAuditRunner.d.ts +144 -0
- package/dist/orchestration/securityAuditRunner.d.ts.map +1 -0
- package/dist/orchestration/securityAuditRunner.js +526 -0
- package/dist/orchestration/securityAuditRunner.js.map +1 -0
- package/dist/plugins/index.d.ts +49 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +105 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/providers/deepseek/index.d.ts +11 -0
- package/dist/plugins/providers/deepseek/index.d.ts.map +1 -0
- package/dist/plugins/providers/deepseek/index.js +54 -0
- package/dist/plugins/providers/deepseek/index.js.map +1 -0
- package/dist/plugins/providers/index.d.ts +2 -0
- package/dist/plugins/providers/index.d.ts.map +1 -0
- package/dist/plugins/providers/index.js +11 -0
- package/dist/plugins/providers/index.js.map +1 -0
- package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts +3 -0
- package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js +27 -0
- package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js.map +1 -0
- package/dist/plugins/tools/apple/secureApplePlugin.d.ts +3 -0
- package/dist/plugins/tools/apple/secureApplePlugin.d.ts.map +1 -0
- package/dist/plugins/tools/apple/secureApplePlugin.js +26 -0
- package/dist/plugins/tools/apple/secureApplePlugin.js.map +1 -0
- package/dist/plugins/tools/authorizedSecurity/authorizedSecurityPlugin.d.ts +3 -0
- package/dist/plugins/tools/authorizedSecurity/authorizedSecurityPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/authorizedSecurity/authorizedSecurityPlugin.js +9 -0
- package/dist/plugins/tools/authorizedSecurity/authorizedSecurityPlugin.js.map +1 -0
- package/dist/plugins/tools/bash/localBashPlugin.d.ts +3 -0
- package/dist/plugins/tools/bash/localBashPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/bash/localBashPlugin.js +14 -0
- package/dist/plugins/tools/bash/localBashPlugin.js.map +1 -0
- package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.d.ts +3 -0
- package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.js +27 -0
- package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.js.map +1 -0
- package/dist/plugins/tools/edit/editPlugin.d.ts +9 -0
- package/dist/plugins/tools/edit/editPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/edit/editPlugin.js +15 -0
- package/dist/plugins/tools/edit/editPlugin.js.map +1 -0
- package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts +3 -0
- package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js +9 -0
- package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js.map +1 -0
- package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts +3 -0
- package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/filesystem/localFilesystemPlugin.js +14 -0
- package/dist/plugins/tools/filesystem/localFilesystemPlugin.js.map +1 -0
- package/dist/plugins/tools/gitHistory/gitHistoryPlugin.d.ts +3 -0
- package/dist/plugins/tools/gitHistory/gitHistoryPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/gitHistory/gitHistoryPlugin.js +9 -0
- package/dist/plugins/tools/gitHistory/gitHistoryPlugin.js.map +1 -0
- package/dist/plugins/tools/index.d.ts +3 -0
- package/dist/plugins/tools/index.d.ts.map +1 -0
- package/dist/plugins/tools/index.js +3 -0
- package/dist/plugins/tools/index.js.map +1 -0
- package/dist/plugins/tools/integrity/integrityPlugin.d.ts +3 -0
- package/dist/plugins/tools/integrity/integrityPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/integrity/integrityPlugin.js +31 -0
- package/dist/plugins/tools/integrity/integrityPlugin.js.map +1 -0
- package/dist/plugins/tools/mcp/mcpPlugin.d.ts +3 -0
- package/dist/plugins/tools/mcp/mcpPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/mcp/mcpPlugin.js +27 -0
- package/dist/plugins/tools/mcp/mcpPlugin.js.map +1 -0
- package/dist/plugins/tools/nodeDefaults.d.ts +15 -0
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -0
- package/dist/plugins/tools/nodeDefaults.js +37 -0
- package/dist/plugins/tools/nodeDefaults.js.map +1 -0
- package/dist/plugins/tools/offensiveDestruction/offensiveDestructionPlugin.d.ts +3 -0
- package/dist/plugins/tools/offensiveDestruction/offensiveDestructionPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/offensiveDestruction/offensiveDestructionPlugin.js +9 -0
- package/dist/plugins/tools/offensiveDestruction/offensiveDestructionPlugin.js.map +1 -0
- package/dist/plugins/tools/orchestration/orchestrationPlugin.d.ts +3 -0
- package/dist/plugins/tools/orchestration/orchestrationPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/orchestration/orchestrationPlugin.js +340 -0
- package/dist/plugins/tools/orchestration/orchestrationPlugin.js.map +1 -0
- package/dist/plugins/tools/registry.d.ts +22 -0
- package/dist/plugins/tools/registry.d.ts.map +1 -0
- package/dist/plugins/tools/registry.js +58 -0
- package/dist/plugins/tools/registry.js.map +1 -0
- package/dist/plugins/tools/search/localSearchPlugin.d.ts +3 -0
- package/dist/plugins/tools/search/localSearchPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/search/localSearchPlugin.js +14 -0
- package/dist/plugins/tools/search/localSearchPlugin.js.map +1 -0
- package/dist/plugins/tools/skills/skillPlugin.d.ts +3 -0
- package/dist/plugins/tools/skills/skillPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/skills/skillPlugin.js +27 -0
- package/dist/plugins/tools/skills/skillPlugin.js.map +1 -0
- package/dist/plugins/tools/tao/secureTaoPlugin.d.ts +3 -0
- package/dist/plugins/tools/tao/secureTaoPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/tao/secureTaoPlugin.js +37 -0
- package/dist/plugins/tools/tao/secureTaoPlugin.js.map +1 -0
- package/dist/providers/baseProvider.d.ts +148 -0
- package/dist/providers/baseProvider.d.ts.map +1 -0
- package/dist/providers/baseProvider.js +284 -0
- package/dist/providers/baseProvider.js.map +1 -0
- package/dist/providers/openaiChatCompletionsProvider.d.ts +64 -0
- package/dist/providers/openaiChatCompletionsProvider.d.ts.map +1 -0
- package/dist/providers/openaiChatCompletionsProvider.js +1000 -0
- package/dist/providers/openaiChatCompletionsProvider.js.map +1 -0
- package/dist/providers/providerFactory.d.ts +22 -0
- package/dist/providers/providerFactory.d.ts.map +1 -0
- package/dist/providers/providerFactory.js +25 -0
- package/dist/providers/providerFactory.js.map +1 -0
- package/dist/providers/resilientProvider.d.ts +103 -0
- package/dist/providers/resilientProvider.d.ts.map +1 -0
- package/dist/providers/resilientProvider.js +462 -0
- package/dist/providers/resilientProvider.js.map +1 -0
- package/dist/runtime/agentController.d.ts +114 -0
- package/dist/runtime/agentController.d.ts.map +1 -0
- package/dist/runtime/agentController.js +693 -0
- package/dist/runtime/agentController.js.map +1 -0
- package/dist/runtime/agentHost.d.ts +61 -0
- package/dist/runtime/agentHost.d.ts.map +1 -0
- package/dist/runtime/agentHost.js +157 -0
- package/dist/runtime/agentHost.js.map +1 -0
- package/dist/runtime/agentSession.d.ts +45 -0
- package/dist/runtime/agentSession.d.ts.map +1 -0
- package/dist/runtime/agentSession.js +210 -0
- package/dist/runtime/agentSession.js.map +1 -0
- package/dist/runtime/agentWorkerPool.d.ts +167 -0
- package/dist/runtime/agentWorkerPool.d.ts.map +1 -0
- package/dist/runtime/agentWorkerPool.js +435 -0
- package/dist/runtime/agentWorkerPool.js.map +1 -0
- package/dist/runtime/node.d.ts +7 -0
- package/dist/runtime/node.d.ts.map +1 -0
- package/dist/runtime/node.js +24 -0
- package/dist/runtime/node.js.map +1 -0
- package/dist/runtime/universal.d.ts +18 -0
- package/dist/runtime/universal.d.ts.map +1 -0
- package/dist/runtime/universal.js +21 -0
- package/dist/runtime/universal.js.map +1 -0
- package/dist/shell/autoExecutor.d.ts +70 -0
- package/dist/shell/autoExecutor.d.ts.map +1 -0
- package/dist/shell/autoExecutor.js +320 -0
- package/dist/shell/autoExecutor.js.map +1 -0
- package/dist/shell/commandRegistry.d.ts +122 -0
- package/dist/shell/commandRegistry.d.ts.map +1 -0
- package/dist/shell/commandRegistry.js +386 -0
- package/dist/shell/commandRegistry.js.map +1 -0
- package/dist/shell/composableMessage.d.ts +183 -0
- package/dist/shell/composableMessage.d.ts.map +1 -0
- package/dist/shell/composableMessage.js +420 -0
- package/dist/shell/composableMessage.js.map +1 -0
- package/dist/shell/liveStatus.d.ts +27 -0
- package/dist/shell/liveStatus.d.ts.map +1 -0
- package/dist/shell/liveStatus.js +53 -0
- package/dist/shell/liveStatus.js.map +1 -0
- package/dist/shell/systemPrompt.d.ts +12 -0
- package/dist/shell/systemPrompt.d.ts.map +1 -0
- package/dist/shell/systemPrompt.js +16 -0
- package/dist/shell/systemPrompt.js.map +1 -0
- package/dist/shell/vimMode.d.ts +66 -0
- package/dist/shell/vimMode.d.ts.map +1 -0
- package/dist/shell/vimMode.js +435 -0
- package/dist/shell/vimMode.js.map +1 -0
- package/dist/tools/bashTools.d.ts +6 -0
- package/dist/tools/bashTools.d.ts.map +1 -0
- package/dist/tools/bashTools.js +485 -0
- package/dist/tools/bashTools.js.map +1 -0
- package/dist/tools/diffUtils.d.ts +43 -0
- package/dist/tools/diffUtils.d.ts.map +1 -0
- package/dist/tools/diffUtils.js +607 -0
- package/dist/tools/diffUtils.js.map +1 -0
- package/dist/tools/editTools.d.ts +29 -0
- package/dist/tools/editTools.d.ts.map +1 -0
- package/dist/tools/editTools.js +702 -0
- package/dist/tools/editTools.js.map +1 -0
- package/dist/tools/emailTools.d.ts +140 -0
- package/dist/tools/emailTools.d.ts.map +1 -0
- package/dist/tools/emailTools.js +792 -0
- package/dist/tools/emailTools.js.map +1 -0
- package/dist/tools/fileReadTracker.d.ts +69 -0
- package/dist/tools/fileReadTracker.d.ts.map +1 -0
- package/dist/tools/fileReadTracker.js +213 -0
- package/dist/tools/fileReadTracker.js.map +1 -0
- package/dist/tools/fileTools.d.ts +3 -0
- package/dist/tools/fileTools.d.ts.map +1 -0
- package/dist/tools/fileTools.js +342 -0
- package/dist/tools/fileTools.js.map +1 -0
- package/dist/tools/grepTools.d.ts +3 -0
- package/dist/tools/grepTools.d.ts.map +1 -0
- package/dist/tools/grepTools.js +129 -0
- package/dist/tools/grepTools.js.map +1 -0
- package/dist/tools/humanOpsTools.d.ts +3 -0
- package/dist/tools/humanOpsTools.d.ts.map +1 -0
- package/dist/tools/humanOpsTools.js +86 -0
- package/dist/tools/humanOpsTools.js.map +1 -0
- package/dist/tools/localExplore.d.ts +38 -0
- package/dist/tools/localExplore.d.ts.map +1 -0
- package/dist/tools/localExplore.js +30 -0
- package/dist/tools/localExplore.js.map +1 -0
- package/dist/tools/metaTools.d.ts +3 -0
- package/dist/tools/metaTools.d.ts.map +1 -0
- package/dist/tools/metaTools.js +148 -0
- package/dist/tools/metaTools.js.map +1 -0
- package/dist/tools/planningTools.d.ts +12 -0
- package/dist/tools/planningTools.d.ts.map +1 -0
- package/dist/tools/planningTools.js +75 -0
- package/dist/tools/planningTools.js.map +1 -0
- package/dist/tools/searchTools.d.ts +12 -0
- package/dist/tools/searchTools.d.ts.map +1 -0
- package/dist/tools/searchTools.js +370 -0
- package/dist/tools/searchTools.js.map +1 -0
- package/dist/tools/secureAppleExploitation.d.ts +29 -0
- package/dist/tools/secureAppleExploitation.d.ts.map +1 -0
- package/dist/tools/secureAppleExploitation.js +518 -0
- package/dist/tools/secureAppleExploitation.js.map +1 -0
- package/dist/tools/telemetryTools.d.ts +5 -0
- package/dist/tools/telemetryTools.d.ts.map +1 -0
- package/dist/tools/telemetryTools.js +9 -0
- package/dist/tools/telemetryTools.js.map +1 -0
- package/dist/tools/unifiedOps.d.ts +3 -0
- package/dist/tools/unifiedOps.d.ts.map +1 -0
- package/dist/tools/unifiedOps.js +57 -0
- package/dist/tools/unifiedOps.js.map +1 -0
- package/dist/tools/webTools.d.ts +26 -0
- package/dist/tools/webTools.d.ts.map +1 -0
- package/dist/tools/webTools.js +227 -0
- package/dist/tools/webTools.js.map +1 -0
- package/dist/ui/PromptController.d.ts +174 -0
- package/dist/ui/PromptController.d.ts.map +1 -0
- package/dist/ui/PromptController.js +351 -0
- package/dist/ui/PromptController.js.map +1 -0
- package/dist/ui/UnifiedUIRenderer.d.ts +779 -0
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -0
- package/dist/ui/UnifiedUIRenderer.js +5458 -0
- package/dist/ui/UnifiedUIRenderer.js.map +1 -0
- package/dist/ui/animatedStatus.d.ts +140 -0
- package/dist/ui/animatedStatus.d.ts.map +1 -0
- package/dist/ui/animatedStatus.js +480 -0
- package/dist/ui/animatedStatus.js.map +1 -0
- package/dist/ui/animation/AnimationScheduler.d.ts +197 -0
- package/dist/ui/animation/AnimationScheduler.d.ts.map +1 -0
- package/dist/ui/animation/AnimationScheduler.js +440 -0
- package/dist/ui/animation/AnimationScheduler.js.map +1 -0
- package/dist/ui/codeHighlighter.d.ts +6 -0
- package/dist/ui/codeHighlighter.d.ts.map +1 -0
- package/dist/ui/codeHighlighter.js +855 -0
- package/dist/ui/codeHighlighter.js.map +1 -0
- package/dist/ui/designSystem.d.ts +26 -0
- package/dist/ui/designSystem.d.ts.map +1 -0
- package/dist/ui/designSystem.js +114 -0
- package/dist/ui/designSystem.js.map +1 -0
- package/dist/ui/errorFormatter.d.ts +64 -0
- package/dist/ui/errorFormatter.d.ts.map +1 -0
- package/dist/ui/errorFormatter.js +316 -0
- package/dist/ui/errorFormatter.js.map +1 -0
- package/dist/ui/globalWriteLock.d.ts +63 -0
- package/dist/ui/globalWriteLock.d.ts.map +1 -0
- package/dist/ui/globalWriteLock.js +173 -0
- package/dist/ui/globalWriteLock.js.map +1 -0
- package/dist/ui/index.d.ts +32 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +54 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/interrupts/InterruptManager.d.ts +157 -0
- package/dist/ui/interrupts/InterruptManager.d.ts.map +1 -0
- package/dist/ui/interrupts/InterruptManager.js +501 -0
- package/dist/ui/interrupts/InterruptManager.js.map +1 -0
- package/dist/ui/layout.d.ts +27 -0
- package/dist/ui/layout.d.ts.map +1 -0
- package/dist/ui/layout.js +184 -0
- package/dist/ui/layout.js.map +1 -0
- package/dist/ui/maxOffensiveUkraineUI.d.ts +94 -0
- package/dist/ui/maxOffensiveUkraineUI.d.ts.map +1 -0
- package/dist/ui/maxOffensiveUkraineUI.js +316 -0
- package/dist/ui/maxOffensiveUkraineUI.js.map +1 -0
- package/dist/ui/outputMode.d.ts +44 -0
- package/dist/ui/outputMode.d.ts.map +1 -0
- package/dist/ui/outputMode.js +123 -0
- package/dist/ui/outputMode.js.map +1 -0
- package/dist/ui/overlay/OverlayManager.d.ts +105 -0
- package/dist/ui/overlay/OverlayManager.d.ts.map +1 -0
- package/dist/ui/overlay/OverlayManager.js +291 -0
- package/dist/ui/overlay/OverlayManager.js.map +1 -0
- package/dist/ui/premiumComponents.d.ts +54 -0
- package/dist/ui/premiumComponents.d.ts.map +1 -0
- package/dist/ui/premiumComponents.js +241 -0
- package/dist/ui/premiumComponents.js.map +1 -0
- package/dist/ui/richText.d.ts +13 -0
- package/dist/ui/richText.d.ts.map +1 -0
- package/dist/ui/richText.js +443 -0
- package/dist/ui/richText.js.map +1 -0
- package/dist/ui/telemetry/ResponseTracker.d.ts +22 -0
- package/dist/ui/telemetry/ResponseTracker.d.ts.map +1 -0
- package/dist/ui/telemetry/ResponseTracker.js +60 -0
- package/dist/ui/telemetry/ResponseTracker.js.map +1 -0
- package/dist/ui/telemetry/UITelemetry.d.ts +181 -0
- package/dist/ui/telemetry/UITelemetry.d.ts.map +1 -0
- package/dist/ui/telemetry/UITelemetry.js +446 -0
- package/dist/ui/telemetry/UITelemetry.js.map +1 -0
- package/dist/ui/textHighlighter.d.ts +83 -0
- package/dist/ui/textHighlighter.d.ts.map +1 -0
- package/dist/ui/textHighlighter.js +267 -0
- package/dist/ui/textHighlighter.js.map +1 -0
- package/dist/ui/theme.d.ts +364 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +471 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/toolDisplay.d.ts +221 -0
- package/dist/ui/toolDisplay.d.ts.map +1 -0
- package/dist/ui/toolDisplay.js +1654 -0
- package/dist/ui/toolDisplay.js.map +1 -0
- package/dist/ui/uiConstants.d.ts +288 -0
- package/dist/ui/uiConstants.d.ts.map +1 -0
- package/dist/ui/uiConstants.js +472 -0
- package/dist/ui/uiConstants.js.map +1 -0
- package/dist/utils/askUserPrompt.d.ts +21 -0
- package/dist/utils/askUserPrompt.d.ts.map +1 -0
- package/dist/utils/askUserPrompt.js +87 -0
- package/dist/utils/askUserPrompt.js.map +1 -0
- package/dist/utils/asyncUtils.d.ts +95 -0
- package/dist/utils/asyncUtils.d.ts.map +1 -0
- package/dist/utils/asyncUtils.js +286 -0
- package/dist/utils/asyncUtils.js.map +1 -0
- package/dist/utils/debugLogger.d.ts +6 -0
- package/dist/utils/debugLogger.d.ts.map +1 -0
- package/dist/utils/debugLogger.js +39 -0
- package/dist/utils/debugLogger.js.map +1 -0
- package/dist/utils/errorUtils.d.ts +12 -0
- package/dist/utils/errorUtils.d.ts.map +1 -0
- package/dist/utils/errorUtils.js +83 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +78 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/packageInfo.d.ts +14 -0
- package/dist/utils/packageInfo.d.ts.map +1 -0
- package/dist/utils/packageInfo.js +45 -0
- package/dist/utils/packageInfo.js.map +1 -0
- package/dist/utils/planFormatter.d.ts +34 -0
- package/dist/utils/planFormatter.d.ts.map +1 -0
- package/dist/utils/planFormatter.js +141 -0
- package/dist/utils/planFormatter.js.map +1 -0
- package/dist/utils/securityUtils.d.ts +132 -0
- package/dist/utils/securityUtils.d.ts.map +1 -0
- package/dist/utils/securityUtils.js +324 -0
- package/dist/utils/securityUtils.js.map +1 -0
- package/dist/workspace.d.ts +8 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +134 -0
- package/dist/workspace.js.map +1 -0
- package/dist/workspace.validator.d.ts +49 -0
- package/dist/workspace.validator.d.ts.map +1 -0
- package/dist/workspace.validator.js +215 -0
- package/dist/workspace.validator.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,2190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Security Audit System
|
|
3
|
+
*
|
|
4
|
+
* Provider-agnostic security scanning for any cloud infrastructure, company, product.
|
|
5
|
+
* This is the DEFAULT capability for all AGI Core operations.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Google Cloud Platform (GCP)
|
|
9
|
+
* - Amazon Web Services (AWS)
|
|
10
|
+
* - Microsoft Azure
|
|
11
|
+
* - Any custom infrastructure
|
|
12
|
+
*
|
|
13
|
+
* Features:
|
|
14
|
+
* - Live verification against real APIs
|
|
15
|
+
* - Zero-day prediction via unconventional heuristics
|
|
16
|
+
* - Dual tournament RL validation
|
|
17
|
+
* - Full APT kill chain coverage
|
|
18
|
+
*/
|
|
19
|
+
import { exec } from 'child_process';
|
|
20
|
+
import { promisify } from 'util';
|
|
21
|
+
import https from 'https';
|
|
22
|
+
const execAsync = promisify(exec);
|
|
23
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
24
|
+
// Zero-Day Prediction Heuristics
|
|
25
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
26
|
+
const ZERO_DAY_HEURISTICS = {
|
|
27
|
+
complexityCorrelation: {
|
|
28
|
+
principle: 'Vulnerabilities cluster where code complexity exceeds cognitive limits',
|
|
29
|
+
indicators: ['Cyclomatic complexity > 50', 'Function length > 500 lines', 'Deep nesting > 6 levels', 'Multiple async patterns', 'Complex state machines'],
|
|
30
|
+
weight: 0.85,
|
|
31
|
+
},
|
|
32
|
+
trustBoundaryAnalysis: {
|
|
33
|
+
principle: 'Every trust boundary crossing is a potential attack surface',
|
|
34
|
+
indicators: ['Service-to-service auth', 'Cross-region data transfer', 'User input propagation', 'Third-party integrations', 'API gateway boundaries'],
|
|
35
|
+
weight: 0.90,
|
|
36
|
+
},
|
|
37
|
+
temporalCoupling: {
|
|
38
|
+
principle: 'Time-based operations create race condition opportunities',
|
|
39
|
+
indicators: ['Async token refresh', 'Distributed consensus', 'Cache invalidation', 'Session management', 'Rate limiting windows'],
|
|
40
|
+
weight: 0.80,
|
|
41
|
+
},
|
|
42
|
+
serializationBoundaries: {
|
|
43
|
+
principle: 'Data format transitions are high-risk transformation points',
|
|
44
|
+
indicators: ['JSON to protobuf conversion', 'XML parsing', 'Custom serialization', 'Encoding transitions', 'Schema migrations'],
|
|
45
|
+
weight: 0.88,
|
|
46
|
+
},
|
|
47
|
+
emergentBehaviors: {
|
|
48
|
+
principle: 'Complex systems exhibit behaviors not present in components',
|
|
49
|
+
indicators: ['Multi-service workflows', 'Distributed transactions', 'Event-driven architectures', 'Microservice meshes', 'Cascading failures'],
|
|
50
|
+
weight: 0.75,
|
|
51
|
+
},
|
|
52
|
+
errorHandlingAsymmetry: {
|
|
53
|
+
principle: 'Error paths receive less testing than happy paths',
|
|
54
|
+
indicators: ['Exception handling in auth', 'Rollback logic', 'Timeout handling', 'Partial failure states', 'Recovery procedures'],
|
|
55
|
+
weight: 0.82,
|
|
56
|
+
},
|
|
57
|
+
implicitStateDependencies: {
|
|
58
|
+
principle: 'Hidden state coupling creates unexpected interactions',
|
|
59
|
+
indicators: ['Global configuration', 'Shared caches', 'Connection pools', 'Thread-local storage', 'Implicit ordering'],
|
|
60
|
+
weight: 0.78,
|
|
61
|
+
},
|
|
62
|
+
resourceExhaustion: {
|
|
63
|
+
principle: 'Resource limits are often enforced inconsistently',
|
|
64
|
+
indicators: ['Memory allocation', 'File handles', 'Network connections', 'CPU quotas', 'Storage limits'],
|
|
65
|
+
weight: 0.70,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
69
|
+
// APT Kill Chain Phases
|
|
70
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
71
|
+
const APT_KILL_CHAIN = [
|
|
72
|
+
{ phase: 'reconnaissance', description: 'Information gathering about targets' },
|
|
73
|
+
{ phase: 'weaponization', description: 'Creating attack payloads' },
|
|
74
|
+
{ phase: 'delivery', description: 'Transmitting attack to target' },
|
|
75
|
+
{ phase: 'exploitation', description: 'Executing attack payload' },
|
|
76
|
+
{ phase: 'installation', description: 'Establishing persistence' },
|
|
77
|
+
{ phase: 'command-control', description: 'Remote access channel' },
|
|
78
|
+
{ phase: 'actions', description: 'Achieving objectives' },
|
|
79
|
+
];
|
|
80
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
81
|
+
// GCP Tests
|
|
82
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
83
|
+
async function getGCPAccessToken() {
|
|
84
|
+
try {
|
|
85
|
+
const { stdout } = await execAsync('gcloud auth print-access-token');
|
|
86
|
+
return stdout.trim();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
throw new Error(`Failed to get GCP access token: ${error}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function gcpApiCall(endpoint, method = 'GET', body, accessToken) {
|
|
93
|
+
const token = accessToken || await getGCPAccessToken();
|
|
94
|
+
const url = new URL(endpoint);
|
|
95
|
+
const startTime = performance.now();
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const options = {
|
|
98
|
+
hostname: url.hostname,
|
|
99
|
+
path: url.pathname + url.search,
|
|
100
|
+
method,
|
|
101
|
+
headers: {
|
|
102
|
+
'Authorization': `Bearer ${token}`,
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
'User-Agent': 'agi-core-universal-audit/1.0',
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const req = https.request(options, (res) => {
|
|
108
|
+
let data = '';
|
|
109
|
+
res.on('data', chunk => data += chunk);
|
|
110
|
+
res.on('end', () => {
|
|
111
|
+
const timingMs = performance.now() - startTime;
|
|
112
|
+
try {
|
|
113
|
+
resolve({
|
|
114
|
+
data: data ? JSON.parse(data) : {},
|
|
115
|
+
timingMs,
|
|
116
|
+
statusCode: res.statusCode || 0,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
resolve({ data: { raw: data }, timingMs, statusCode: res.statusCode || 0 });
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
req.on('error', reject);
|
|
125
|
+
req.setTimeout(30000, () => {
|
|
126
|
+
req.destroy();
|
|
127
|
+
reject(new Error('Request timeout'));
|
|
128
|
+
});
|
|
129
|
+
if (body)
|
|
130
|
+
req.write(JSON.stringify(body));
|
|
131
|
+
req.end();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const GCP_TESTS = [
|
|
135
|
+
{
|
|
136
|
+
id: 'GCP-IAM-TIMING-001',
|
|
137
|
+
name: 'IAM Timing Oracle Detection',
|
|
138
|
+
category: 'IAM',
|
|
139
|
+
aptPhase: 'reconnaissance',
|
|
140
|
+
execute: async (config) => {
|
|
141
|
+
if (!config.projectId)
|
|
142
|
+
return null;
|
|
143
|
+
const timings = [];
|
|
144
|
+
const evidence = [];
|
|
145
|
+
const token = await getGCPAccessToken();
|
|
146
|
+
const testCases = [
|
|
147
|
+
{ permission: 'resourcemanager.projects.get' },
|
|
148
|
+
{ permission: 'resourcemanager.projects.delete' },
|
|
149
|
+
{ permission: 'iam.roles.create' },
|
|
150
|
+
{ permission: 'compute.instances.create' },
|
|
151
|
+
];
|
|
152
|
+
for (const tc of testCases) {
|
|
153
|
+
try {
|
|
154
|
+
const result = await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:testIamPermissions`, 'POST', { permissions: [tc.permission] }, token);
|
|
155
|
+
timings.push(result.timingMs);
|
|
156
|
+
evidence.push(`${tc.permission}: ${result.timingMs.toFixed(2)}ms`);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
evidence.push(`${tc.permission}: ERROR`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const validTimings = timings.filter(t => t > 0);
|
|
163
|
+
const mean = validTimings.reduce((a, b) => a + b, 0) / validTimings.length;
|
|
164
|
+
const variance = validTimings.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / validTimings.length;
|
|
165
|
+
const stdDev = Math.sqrt(variance);
|
|
166
|
+
const cv = (stdDev / mean) * 100;
|
|
167
|
+
const vulnerable = cv > 25;
|
|
168
|
+
evidence.push(`CV: ${cv.toFixed(1)}% (threshold: 25%)`);
|
|
169
|
+
if (!vulnerable)
|
|
170
|
+
return null;
|
|
171
|
+
return {
|
|
172
|
+
id: 'GCP-IAM-TIMING-001',
|
|
173
|
+
provider: 'gcp',
|
|
174
|
+
vulnerability: 'IAM Timing Oracle',
|
|
175
|
+
severity: 'high',
|
|
176
|
+
confidence: 0.75 + (cv / 400),
|
|
177
|
+
evidence,
|
|
178
|
+
technique: 'Timing Analysis',
|
|
179
|
+
timestamp: new Date().toISOString(),
|
|
180
|
+
resource: `projects/${config.projectId}`,
|
|
181
|
+
exploitability: 'moderate',
|
|
182
|
+
verified: true,
|
|
183
|
+
aptPhase: 'reconnaissance',
|
|
184
|
+
remediation: 'Implement constant-time permission checks',
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'GCP-SA-KEY-RACE-001',
|
|
190
|
+
name: 'Service Account Key Race Condition',
|
|
191
|
+
category: 'IAM',
|
|
192
|
+
aptPhase: 'exploitation',
|
|
193
|
+
execute: async (config) => {
|
|
194
|
+
if (!config.projectId)
|
|
195
|
+
return null;
|
|
196
|
+
const evidence = [];
|
|
197
|
+
const token = await getGCPAccessToken();
|
|
198
|
+
try {
|
|
199
|
+
const saResult = await gcpApiCall(`https://iam.googleapis.com/v1/projects/${config.projectId}/serviceAccounts`, 'GET', undefined, token);
|
|
200
|
+
const accounts = saResult.data.accounts || [];
|
|
201
|
+
evidence.push(`Found ${accounts.length} service accounts`);
|
|
202
|
+
const permCheck = await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:testIamPermissions`, 'POST', { permissions: ['iam.serviceAccountKeys.create'] }, token);
|
|
203
|
+
const perms = permCheck.data.permissions || [];
|
|
204
|
+
const canCreateKeys = perms.includes('iam.serviceAccountKeys.create');
|
|
205
|
+
evidence.push(`Can create SA keys: ${canCreateKeys}`);
|
|
206
|
+
if (!canCreateKeys)
|
|
207
|
+
return null;
|
|
208
|
+
return {
|
|
209
|
+
id: 'GCP-SA-KEY-RACE-001',
|
|
210
|
+
provider: 'gcp',
|
|
211
|
+
vulnerability: 'Service Account Key Creation Race',
|
|
212
|
+
severity: 'critical',
|
|
213
|
+
confidence: 0.85,
|
|
214
|
+
evidence,
|
|
215
|
+
technique: 'Permission Enumeration + TOCTOU Analysis',
|
|
216
|
+
timestamp: new Date().toISOString(),
|
|
217
|
+
resource: `projects/${config.projectId}/serviceAccounts`,
|
|
218
|
+
exploitability: 'trivial',
|
|
219
|
+
verified: true,
|
|
220
|
+
aptPhase: 'exploitation',
|
|
221
|
+
remediation: 'Disable SA key creation, use Workload Identity',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (e) {
|
|
225
|
+
evidence.push(`Error: ${e}`);
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 'GCP-STORAGE-ACL-001',
|
|
232
|
+
name: 'Storage Bucket ACL Misconfiguration',
|
|
233
|
+
category: 'Storage',
|
|
234
|
+
aptPhase: 'reconnaissance',
|
|
235
|
+
execute: async (config) => {
|
|
236
|
+
if (!config.projectId)
|
|
237
|
+
return null;
|
|
238
|
+
const evidence = [];
|
|
239
|
+
const vulnerabilities = [];
|
|
240
|
+
const token = await getGCPAccessToken();
|
|
241
|
+
try {
|
|
242
|
+
const bucketsResult = await gcpApiCall(`https://storage.googleapis.com/storage/v1/b?project=${config.projectId}`, 'GET', undefined, token);
|
|
243
|
+
const items = bucketsResult.data.items || [];
|
|
244
|
+
evidence.push(`Found ${items.length} buckets`);
|
|
245
|
+
for (const bucket of items.slice(0, 10)) {
|
|
246
|
+
const detail = await gcpApiCall(`https://storage.googleapis.com/storage/v1/b/${bucket.name}?projection=full`, 'GET', undefined, token);
|
|
247
|
+
const data = detail.data;
|
|
248
|
+
const uniformAccess = data.iamConfiguration?.uniformBucketLevelAccess?.enabled;
|
|
249
|
+
const publicPrevention = data.iamConfiguration?.publicAccessPrevention;
|
|
250
|
+
if (!uniformAccess) {
|
|
251
|
+
vulnerabilities.push(`${bucket.name}: Legacy ACL mode`);
|
|
252
|
+
}
|
|
253
|
+
if (publicPrevention !== 'enforced') {
|
|
254
|
+
vulnerabilities.push(`${bucket.name}: Public prevention not enforced`);
|
|
255
|
+
}
|
|
256
|
+
if (data.acl) {
|
|
257
|
+
for (const acl of data.acl) {
|
|
258
|
+
if (acl.entity === 'allUsers' || acl.entity === 'allAuthenticatedUsers') {
|
|
259
|
+
vulnerabilities.push(`${bucket.name}: PUBLIC via ${acl.entity}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
evidence.push(...vulnerabilities);
|
|
265
|
+
if (vulnerabilities.length === 0)
|
|
266
|
+
return null;
|
|
267
|
+
return {
|
|
268
|
+
id: 'GCP-STORAGE-ACL-001',
|
|
269
|
+
provider: 'gcp',
|
|
270
|
+
vulnerability: 'Storage Bucket ACL Misconfiguration',
|
|
271
|
+
severity: vulnerabilities.some(v => v.includes('PUBLIC')) ? 'critical' : 'high',
|
|
272
|
+
confidence: 0.95,
|
|
273
|
+
evidence,
|
|
274
|
+
technique: 'Configuration Audit',
|
|
275
|
+
timestamp: new Date().toISOString(),
|
|
276
|
+
resource: `projects/${config.projectId}/buckets`,
|
|
277
|
+
exploitability: 'trivial',
|
|
278
|
+
verified: true,
|
|
279
|
+
aptPhase: 'reconnaissance',
|
|
280
|
+
remediation: 'Enable uniform bucket-level access, enforce public prevention',
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
catch (e) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: 'GCP-IAM-CROSS-PROJECT-001',
|
|
290
|
+
name: 'Cross-Project IAM Binding Exposure',
|
|
291
|
+
category: 'IAM',
|
|
292
|
+
aptPhase: 'reconnaissance',
|
|
293
|
+
execute: async (config) => {
|
|
294
|
+
if (!config.projectId)
|
|
295
|
+
return null;
|
|
296
|
+
const evidence = [];
|
|
297
|
+
const vulnerabilities = [];
|
|
298
|
+
const token = await getGCPAccessToken();
|
|
299
|
+
try {
|
|
300
|
+
const policyResult = await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:getIamPolicy`, 'POST', { options: { requestedPolicyVersion: 3 } }, token);
|
|
301
|
+
const bindings = policyResult.data.bindings || [];
|
|
302
|
+
for (const binding of bindings) {
|
|
303
|
+
for (const member of binding.members || []) {
|
|
304
|
+
if (member.startsWith('serviceAccount:') && !member.includes(config.projectId)) {
|
|
305
|
+
vulnerabilities.push(`Cross-project SA: ${member} has ${binding.role}`);
|
|
306
|
+
}
|
|
307
|
+
if (member === 'allUsers' || member === 'allAuthenticatedUsers') {
|
|
308
|
+
vulnerabilities.push(`PUBLIC: ${member} has ${binding.role}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
evidence.push(`Analyzed ${bindings.length} IAM bindings`);
|
|
313
|
+
evidence.push(...vulnerabilities);
|
|
314
|
+
if (vulnerabilities.length === 0)
|
|
315
|
+
return null;
|
|
316
|
+
return {
|
|
317
|
+
id: 'GCP-IAM-CROSS-PROJECT-001',
|
|
318
|
+
provider: 'gcp',
|
|
319
|
+
vulnerability: 'Cross-Project IAM Exposure',
|
|
320
|
+
severity: vulnerabilities.some(v => v.includes('PUBLIC')) ? 'critical' : 'high',
|
|
321
|
+
confidence: 0.9,
|
|
322
|
+
evidence,
|
|
323
|
+
technique: 'IAM Policy Analysis',
|
|
324
|
+
timestamp: new Date().toISOString(),
|
|
325
|
+
resource: `projects/${config.projectId}/iamPolicy`,
|
|
326
|
+
exploitability: 'moderate',
|
|
327
|
+
verified: true,
|
|
328
|
+
aptPhase: 'reconnaissance',
|
|
329
|
+
remediation: 'Review and restrict cross-project bindings',
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
catch (e) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: 'GCP-VPC-SC-001',
|
|
339
|
+
name: 'VPC Service Controls Not Configured',
|
|
340
|
+
category: 'Network',
|
|
341
|
+
aptPhase: 'reconnaissance',
|
|
342
|
+
execute: async (config) => {
|
|
343
|
+
const evidence = [];
|
|
344
|
+
const token = await getGCPAccessToken();
|
|
345
|
+
try {
|
|
346
|
+
const policyResult = await gcpApiCall(`https://accesscontextmanager.googleapis.com/v1/accessPolicies`, 'GET', undefined, token);
|
|
347
|
+
const policies = policyResult.data.accessPolicies || [];
|
|
348
|
+
if (policies.length > 0) {
|
|
349
|
+
evidence.push(`Found ${policies.length} access policies`);
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
evidence.push('No VPC Service Controls configured');
|
|
353
|
+
return {
|
|
354
|
+
id: 'GCP-VPC-SC-001',
|
|
355
|
+
provider: 'gcp',
|
|
356
|
+
vulnerability: 'VPC Service Controls Not Configured',
|
|
357
|
+
severity: 'medium',
|
|
358
|
+
confidence: 0.85,
|
|
359
|
+
evidence,
|
|
360
|
+
technique: 'Service Perimeter Analysis',
|
|
361
|
+
timestamp: new Date().toISOString(),
|
|
362
|
+
resource: 'organization/accessPolicies',
|
|
363
|
+
exploitability: 'complex',
|
|
364
|
+
verified: true,
|
|
365
|
+
aptPhase: 'reconnaissance',
|
|
366
|
+
remediation: 'Configure VPC Service Controls with service perimeters',
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
catch (e) {
|
|
370
|
+
if (String(e).includes('403')) {
|
|
371
|
+
evidence.push('Access Context Manager API not enabled');
|
|
372
|
+
return {
|
|
373
|
+
id: 'GCP-VPC-SC-001',
|
|
374
|
+
provider: 'gcp',
|
|
375
|
+
vulnerability: 'VPC Service Controls Not Configured',
|
|
376
|
+
severity: 'medium',
|
|
377
|
+
confidence: 0.7,
|
|
378
|
+
evidence,
|
|
379
|
+
technique: 'API Availability Check',
|
|
380
|
+
timestamp: new Date().toISOString(),
|
|
381
|
+
resource: 'organization/accessPolicies',
|
|
382
|
+
exploitability: 'complex',
|
|
383
|
+
verified: true,
|
|
384
|
+
aptPhase: 'reconnaissance',
|
|
385
|
+
remediation: 'Enable Access Context Manager API and configure VPC-SC',
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
id: 'GCP-FIREWALL-OPEN-001',
|
|
394
|
+
name: 'Firewall Rules Open to Internet',
|
|
395
|
+
category: 'Network',
|
|
396
|
+
aptPhase: 'reconnaissance',
|
|
397
|
+
execute: async (config) => {
|
|
398
|
+
if (!config.projectId)
|
|
399
|
+
return null;
|
|
400
|
+
const evidence = [];
|
|
401
|
+
const vulnerabilities = [];
|
|
402
|
+
const token = await getGCPAccessToken();
|
|
403
|
+
try {
|
|
404
|
+
const firewallResult = await gcpApiCall(`https://compute.googleapis.com/compute/v1/projects/${config.projectId}/global/firewalls`, 'GET', undefined, token);
|
|
405
|
+
const items = firewallResult.data.items || [];
|
|
406
|
+
evidence.push(`Found ${items.length} firewall rules`);
|
|
407
|
+
for (const rule of items) {
|
|
408
|
+
if (rule.sourceRanges?.includes('0.0.0.0/0') && rule.direction === 'INGRESS') {
|
|
409
|
+
const ports = rule.allowed?.flatMap(a => a.ports || ['all']).join(', ') || 'all';
|
|
410
|
+
vulnerabilities.push(`${rule.name}: Open to 0.0.0.0/0 on ports: ${ports}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
evidence.push(...vulnerabilities);
|
|
414
|
+
if (vulnerabilities.length === 0)
|
|
415
|
+
return null;
|
|
416
|
+
return {
|
|
417
|
+
id: 'GCP-FIREWALL-OPEN-001',
|
|
418
|
+
provider: 'gcp',
|
|
419
|
+
vulnerability: 'Firewall Rules Open to Internet',
|
|
420
|
+
severity: 'critical',
|
|
421
|
+
confidence: 0.95,
|
|
422
|
+
evidence,
|
|
423
|
+
technique: 'Firewall Rule Analysis',
|
|
424
|
+
timestamp: new Date().toISOString(),
|
|
425
|
+
resource: `projects/${config.projectId}/firewalls`,
|
|
426
|
+
exploitability: 'trivial',
|
|
427
|
+
verified: true,
|
|
428
|
+
aptPhase: 'reconnaissance',
|
|
429
|
+
remediation: 'Restrict source ranges, use service accounts',
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
catch (e) {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'GCP-GKE-SECURITY-001',
|
|
439
|
+
name: 'GKE Cluster Security Misconfiguration',
|
|
440
|
+
category: 'Kubernetes',
|
|
441
|
+
aptPhase: 'reconnaissance',
|
|
442
|
+
execute: async (config) => {
|
|
443
|
+
if (!config.projectId)
|
|
444
|
+
return null;
|
|
445
|
+
const evidence = [];
|
|
446
|
+
const vulnerabilities = [];
|
|
447
|
+
const token = await getGCPAccessToken();
|
|
448
|
+
try {
|
|
449
|
+
const clustersResult = await gcpApiCall(`https://container.googleapis.com/v1/projects/${config.projectId}/locations/-/clusters`, 'GET', undefined, token);
|
|
450
|
+
const clusters = clustersResult.data.clusters || [];
|
|
451
|
+
evidence.push(`Found ${clusters.length} GKE clusters`);
|
|
452
|
+
for (const cluster of clusters) {
|
|
453
|
+
if (!cluster.workloadIdentityConfig?.workloadPool) {
|
|
454
|
+
vulnerabilities.push(`${cluster.name}: No Workload Identity`);
|
|
455
|
+
}
|
|
456
|
+
if (!cluster.shieldedNodes?.enabled) {
|
|
457
|
+
vulnerabilities.push(`${cluster.name}: Shielded Nodes disabled`);
|
|
458
|
+
}
|
|
459
|
+
if (!cluster.networkPolicy?.enabled) {
|
|
460
|
+
vulnerabilities.push(`${cluster.name}: No Network Policy`);
|
|
461
|
+
}
|
|
462
|
+
if (!cluster.masterAuthorizedNetworksConfig?.enabled) {
|
|
463
|
+
vulnerabilities.push(`${cluster.name}: Master not restricted`);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
evidence.push(...vulnerabilities);
|
|
467
|
+
if (vulnerabilities.length === 0)
|
|
468
|
+
return null;
|
|
469
|
+
return {
|
|
470
|
+
id: 'GCP-GKE-SECURITY-001',
|
|
471
|
+
provider: 'gcp',
|
|
472
|
+
vulnerability: 'GKE Cluster Security Misconfiguration',
|
|
473
|
+
severity: 'high',
|
|
474
|
+
confidence: 0.9,
|
|
475
|
+
evidence,
|
|
476
|
+
technique: 'Cluster Configuration Audit',
|
|
477
|
+
timestamp: new Date().toISOString(),
|
|
478
|
+
resource: `projects/${config.projectId}/clusters`,
|
|
479
|
+
exploitability: 'moderate',
|
|
480
|
+
verified: true,
|
|
481
|
+
aptPhase: 'reconnaissance',
|
|
482
|
+
remediation: 'Enable Workload Identity, Shielded Nodes, Network Policy',
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
catch (e) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
id: 'GCP-BIGQUERY-EXPOSURE-001',
|
|
492
|
+
name: 'BigQuery Dataset Public Exposure',
|
|
493
|
+
category: 'Data',
|
|
494
|
+
aptPhase: 'reconnaissance',
|
|
495
|
+
execute: async (config) => {
|
|
496
|
+
if (!config.projectId)
|
|
497
|
+
return null;
|
|
498
|
+
const evidence = [];
|
|
499
|
+
const vulnerabilities = [];
|
|
500
|
+
const token = await getGCPAccessToken();
|
|
501
|
+
try {
|
|
502
|
+
const datasetsResult = await gcpApiCall(`https://bigquery.googleapis.com/bigquery/v2/projects/${config.projectId}/datasets`, 'GET', undefined, token);
|
|
503
|
+
const datasets = datasetsResult.data.datasets || [];
|
|
504
|
+
evidence.push(`Found ${datasets.length} BigQuery datasets`);
|
|
505
|
+
for (const dataset of datasets.slice(0, 10)) {
|
|
506
|
+
const detail = await gcpApiCall(`https://bigquery.googleapis.com/bigquery/v2/projects/${config.projectId}/datasets/${dataset.datasetReference.datasetId}`, 'GET', undefined, token);
|
|
507
|
+
const access = detail.data.access || [];
|
|
508
|
+
for (const a of access) {
|
|
509
|
+
if (a.specialGroup === 'allAuthenticatedUsers' || a.specialGroup === 'allUsers') {
|
|
510
|
+
vulnerabilities.push(`${dataset.datasetReference.datasetId}: PUBLIC via ${a.specialGroup}`);
|
|
511
|
+
}
|
|
512
|
+
if (a.iamMember?.startsWith('allUsers') || a.iamMember?.startsWith('allAuthenticatedUsers')) {
|
|
513
|
+
vulnerabilities.push(`${dataset.datasetReference.datasetId}: PUBLIC via ${a.iamMember}`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
evidence.push(...vulnerabilities);
|
|
518
|
+
if (vulnerabilities.length === 0)
|
|
519
|
+
return null;
|
|
520
|
+
return {
|
|
521
|
+
id: 'GCP-BIGQUERY-EXPOSURE-001',
|
|
522
|
+
provider: 'gcp',
|
|
523
|
+
vulnerability: 'BigQuery Dataset Public Exposure',
|
|
524
|
+
severity: 'critical',
|
|
525
|
+
confidence: 0.95,
|
|
526
|
+
evidence,
|
|
527
|
+
technique: 'Dataset ACL Analysis',
|
|
528
|
+
timestamp: new Date().toISOString(),
|
|
529
|
+
resource: `projects/${config.projectId}/datasets`,
|
|
530
|
+
exploitability: 'trivial',
|
|
531
|
+
verified: true,
|
|
532
|
+
aptPhase: 'reconnaissance',
|
|
533
|
+
remediation: 'Remove public access, use authorized views',
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
catch (e) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
542
|
+
// GOOGLE WORKSPACE TESTS
|
|
543
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
544
|
+
{
|
|
545
|
+
id: 'GCP-WORKSPACE-ADMIN-001',
|
|
546
|
+
name: 'Google Workspace Admin API Exposure',
|
|
547
|
+
category: 'Workspace',
|
|
548
|
+
aptPhase: 'reconnaissance',
|
|
549
|
+
execute: async (config) => {
|
|
550
|
+
const evidence = [];
|
|
551
|
+
const vulnerabilities = [];
|
|
552
|
+
const token = await getGCPAccessToken();
|
|
553
|
+
try {
|
|
554
|
+
// Check Directory API access
|
|
555
|
+
const directoryResult = await gcpApiCall('https://admin.googleapis.com/admin/directory/v1/users?maxResults=1', 'GET', undefined, token);
|
|
556
|
+
if (directoryResult.statusCode === 200) {
|
|
557
|
+
vulnerabilities.push('Directory API accessible - can enumerate users');
|
|
558
|
+
evidence.push('Admin Directory API: ACCESSIBLE');
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
evidence.push(`Admin Directory API: ${directoryResult.statusCode}`);
|
|
562
|
+
}
|
|
563
|
+
// Check Reports API
|
|
564
|
+
const reportsResult = await gcpApiCall('https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/login?maxResults=1', 'GET', undefined, token);
|
|
565
|
+
if (reportsResult.statusCode === 200) {
|
|
566
|
+
vulnerabilities.push('Reports API accessible - can view login activity');
|
|
567
|
+
evidence.push('Admin Reports API: ACCESSIBLE');
|
|
568
|
+
}
|
|
569
|
+
// Check Groups API
|
|
570
|
+
const groupsResult = await gcpApiCall('https://admin.googleapis.com/admin/directory/v1/groups?maxResults=1', 'GET', undefined, token);
|
|
571
|
+
if (groupsResult.statusCode === 200) {
|
|
572
|
+
vulnerabilities.push('Groups API accessible - can enumerate groups');
|
|
573
|
+
evidence.push('Admin Groups API: ACCESSIBLE');
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
catch (e) {
|
|
577
|
+
evidence.push(`Error: ${e}`);
|
|
578
|
+
}
|
|
579
|
+
if (vulnerabilities.length === 0)
|
|
580
|
+
return null;
|
|
581
|
+
return {
|
|
582
|
+
id: 'GCP-WORKSPACE-ADMIN-001',
|
|
583
|
+
provider: 'gcp',
|
|
584
|
+
vulnerability: 'Google Workspace Admin API Exposure',
|
|
585
|
+
severity: 'critical',
|
|
586
|
+
confidence: 0.95,
|
|
587
|
+
evidence,
|
|
588
|
+
technique: 'Admin API Enumeration',
|
|
589
|
+
timestamp: new Date().toISOString(),
|
|
590
|
+
resource: 'workspace/admin',
|
|
591
|
+
exploitability: 'moderate',
|
|
592
|
+
verified: true,
|
|
593
|
+
aptPhase: 'reconnaissance',
|
|
594
|
+
remediation: 'Restrict Admin SDK API scopes, use domain-wide delegation carefully',
|
|
595
|
+
};
|
|
596
|
+
},
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
id: 'GCP-WORKSPACE-GMAIL-001',
|
|
600
|
+
name: 'Gmail API Over-Privileged Access',
|
|
601
|
+
category: 'Workspace',
|
|
602
|
+
aptPhase: 'reconnaissance',
|
|
603
|
+
execute: async (config) => {
|
|
604
|
+
const evidence = [];
|
|
605
|
+
const vulnerabilities = [];
|
|
606
|
+
const token = await getGCPAccessToken();
|
|
607
|
+
try {
|
|
608
|
+
// Check Gmail API access
|
|
609
|
+
const gmailResult = await gcpApiCall('https://gmail.googleapis.com/gmail/v1/users/me/profile', 'GET', undefined, token);
|
|
610
|
+
if (gmailResult.statusCode === 200) {
|
|
611
|
+
evidence.push('Gmail API: ACCESSIBLE');
|
|
612
|
+
// Check message access
|
|
613
|
+
const messagesResult = await gcpApiCall('https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=1', 'GET', undefined, token);
|
|
614
|
+
if (messagesResult.statusCode === 200) {
|
|
615
|
+
vulnerabilities.push('Gmail messages accessible - potential data exfiltration');
|
|
616
|
+
}
|
|
617
|
+
// Check settings access
|
|
618
|
+
const settingsResult = await gcpApiCall('https://gmail.googleapis.com/gmail/v1/users/me/settings/forwardingAddresses', 'GET', undefined, token);
|
|
619
|
+
if (settingsResult.statusCode === 200) {
|
|
620
|
+
vulnerabilities.push('Gmail settings accessible - can modify forwarding');
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
catch (e) {
|
|
625
|
+
evidence.push(`Error: ${e}`);
|
|
626
|
+
}
|
|
627
|
+
if (vulnerabilities.length === 0)
|
|
628
|
+
return null;
|
|
629
|
+
return {
|
|
630
|
+
id: 'GCP-WORKSPACE-GMAIL-001',
|
|
631
|
+
provider: 'gcp',
|
|
632
|
+
vulnerability: 'Gmail API Over-Privileged Access',
|
|
633
|
+
severity: 'high',
|
|
634
|
+
confidence: 0.9,
|
|
635
|
+
evidence,
|
|
636
|
+
technique: 'OAuth Scope Analysis',
|
|
637
|
+
timestamp: new Date().toISOString(),
|
|
638
|
+
resource: 'workspace/gmail',
|
|
639
|
+
exploitability: 'moderate',
|
|
640
|
+
verified: true,
|
|
641
|
+
aptPhase: 'reconnaissance',
|
|
642
|
+
remediation: 'Use least-privilege OAuth scopes, review domain-wide delegation',
|
|
643
|
+
};
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
id: 'GCP-WORKSPACE-DRIVE-001',
|
|
648
|
+
name: 'Google Drive Sharing Exposure',
|
|
649
|
+
category: 'Workspace',
|
|
650
|
+
aptPhase: 'reconnaissance',
|
|
651
|
+
execute: async (config) => {
|
|
652
|
+
const evidence = [];
|
|
653
|
+
const vulnerabilities = [];
|
|
654
|
+
const token = await getGCPAccessToken();
|
|
655
|
+
try {
|
|
656
|
+
// Check Drive API access
|
|
657
|
+
const driveResult = await gcpApiCall('https://www.googleapis.com/drive/v3/files?pageSize=10&q=visibility%3D%27anyoneWithLink%27', 'GET', undefined, token);
|
|
658
|
+
if (driveResult.statusCode === 200) {
|
|
659
|
+
const files = driveResult.data.files || [];
|
|
660
|
+
if (files.length > 0) {
|
|
661
|
+
vulnerabilities.push(`Found ${files.length} publicly shared files`);
|
|
662
|
+
evidence.push(...files.slice(0, 5).map(f => `Public file: ${f.name}`));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
// Check for files shared with anyone in org
|
|
666
|
+
const orgSharedResult = await gcpApiCall('https://www.googleapis.com/drive/v3/files?pageSize=10&q=visibility%3D%27domainWithLink%27', 'GET', undefined, token);
|
|
667
|
+
if (orgSharedResult.statusCode === 200) {
|
|
668
|
+
const files = orgSharedResult.data.files || [];
|
|
669
|
+
if (files.length > 0) {
|
|
670
|
+
evidence.push(`Found ${files.length} domain-shared files`);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
catch (e) {
|
|
675
|
+
evidence.push(`Error: ${e}`);
|
|
676
|
+
}
|
|
677
|
+
if (vulnerabilities.length === 0)
|
|
678
|
+
return null;
|
|
679
|
+
return {
|
|
680
|
+
id: 'GCP-WORKSPACE-DRIVE-001',
|
|
681
|
+
provider: 'gcp',
|
|
682
|
+
vulnerability: 'Google Drive Public Sharing Exposure',
|
|
683
|
+
severity: 'high',
|
|
684
|
+
confidence: 0.9,
|
|
685
|
+
evidence,
|
|
686
|
+
technique: 'Drive Sharing Analysis',
|
|
687
|
+
timestamp: new Date().toISOString(),
|
|
688
|
+
resource: 'workspace/drive',
|
|
689
|
+
exploitability: 'trivial',
|
|
690
|
+
verified: true,
|
|
691
|
+
aptPhase: 'reconnaissance',
|
|
692
|
+
remediation: 'Enable sharing restrictions, audit public links',
|
|
693
|
+
};
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
697
|
+
// FIREBASE TESTS
|
|
698
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
699
|
+
{
|
|
700
|
+
id: 'GCP-FIREBASE-AUTH-001',
|
|
701
|
+
name: 'Firebase Auth Configuration Weakness',
|
|
702
|
+
category: 'Firebase',
|
|
703
|
+
aptPhase: 'reconnaissance',
|
|
704
|
+
execute: async (config) => {
|
|
705
|
+
if (!config.projectId)
|
|
706
|
+
return null;
|
|
707
|
+
const evidence = [];
|
|
708
|
+
const vulnerabilities = [];
|
|
709
|
+
const token = await getGCPAccessToken();
|
|
710
|
+
try {
|
|
711
|
+
// Check Firebase Auth config
|
|
712
|
+
const authResult = await gcpApiCall(`https://identitytoolkit.googleapis.com/v1/projects/${config.projectId}/config`, 'GET', undefined, token);
|
|
713
|
+
if (authResult.statusCode === 200) {
|
|
714
|
+
const authConfig = authResult.data;
|
|
715
|
+
evidence.push('Firebase Auth: ACCESSIBLE');
|
|
716
|
+
// Check for weak settings
|
|
717
|
+
if (authConfig.signIn?.allowDuplicateEmails) {
|
|
718
|
+
vulnerabilities.push('Duplicate emails allowed');
|
|
719
|
+
}
|
|
720
|
+
if (authConfig.authorizedDomains?.includes('localhost')) {
|
|
721
|
+
vulnerabilities.push('localhost in authorized domains');
|
|
722
|
+
}
|
|
723
|
+
if (authConfig.mfa?.state !== 'ENABLED') {
|
|
724
|
+
vulnerabilities.push('MFA not enforced');
|
|
725
|
+
}
|
|
726
|
+
evidence.push(`Authorized domains: ${authConfig.authorizedDomains?.join(', ')}`);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
catch (e) {
|
|
730
|
+
evidence.push(`Error: ${e}`);
|
|
731
|
+
}
|
|
732
|
+
if (vulnerabilities.length === 0)
|
|
733
|
+
return null;
|
|
734
|
+
return {
|
|
735
|
+
id: 'GCP-FIREBASE-AUTH-001',
|
|
736
|
+
provider: 'gcp',
|
|
737
|
+
vulnerability: 'Firebase Auth Configuration Weakness',
|
|
738
|
+
severity: 'high',
|
|
739
|
+
confidence: 0.85,
|
|
740
|
+
evidence,
|
|
741
|
+
technique: 'Auth Config Analysis',
|
|
742
|
+
timestamp: new Date().toISOString(),
|
|
743
|
+
resource: `firebase/${config.projectId}/auth`,
|
|
744
|
+
exploitability: 'moderate',
|
|
745
|
+
verified: true,
|
|
746
|
+
aptPhase: 'reconnaissance',
|
|
747
|
+
remediation: 'Enable MFA, restrict authorized domains, disable duplicate emails',
|
|
748
|
+
};
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
id: 'GCP-FIREBASE-DB-001',
|
|
753
|
+
name: 'Firebase Realtime Database Rules',
|
|
754
|
+
category: 'Firebase',
|
|
755
|
+
aptPhase: 'reconnaissance',
|
|
756
|
+
execute: async (config) => {
|
|
757
|
+
if (!config.projectId)
|
|
758
|
+
return null;
|
|
759
|
+
const evidence = [];
|
|
760
|
+
const vulnerabilities = [];
|
|
761
|
+
const token = await getGCPAccessToken();
|
|
762
|
+
try {
|
|
763
|
+
// Check Firebase RTDB rules
|
|
764
|
+
const rulesResult = await gcpApiCall(`https://firebasedatabase.googleapis.com/v1beta/projects/${config.projectId}/locations/-/instances`, 'GET', undefined, token);
|
|
765
|
+
if (rulesResult.statusCode === 200) {
|
|
766
|
+
const instances = rulesResult.data.instances || [];
|
|
767
|
+
evidence.push(`Found ${instances.length} RTDB instances`);
|
|
768
|
+
for (const instance of instances) {
|
|
769
|
+
if (instance.databaseUrl) {
|
|
770
|
+
// Try to read rules (requires admin access)
|
|
771
|
+
try {
|
|
772
|
+
const dbRulesResult = await gcpApiCall(`${instance.databaseUrl}/.settings/rules.json`, 'GET', undefined, token);
|
|
773
|
+
if (dbRulesResult.statusCode === 200) {
|
|
774
|
+
const rules = JSON.stringify(dbRulesResult.data);
|
|
775
|
+
if (rules.includes('"read": true') || rules.includes('".read": true')) {
|
|
776
|
+
vulnerabilities.push(`${instance.name}: Public read access in rules`);
|
|
777
|
+
}
|
|
778
|
+
if (rules.includes('"write": true') || rules.includes('".write": true')) {
|
|
779
|
+
vulnerabilities.push(`${instance.name}: Public write access in rules`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
catch {
|
|
784
|
+
evidence.push(`${instance.name}: Could not read rules`);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
catch (e) {
|
|
791
|
+
evidence.push(`Error: ${e}`);
|
|
792
|
+
}
|
|
793
|
+
if (vulnerabilities.length === 0)
|
|
794
|
+
return null;
|
|
795
|
+
return {
|
|
796
|
+
id: 'GCP-FIREBASE-DB-001',
|
|
797
|
+
provider: 'gcp',
|
|
798
|
+
vulnerability: 'Firebase Realtime Database Public Access',
|
|
799
|
+
severity: 'critical',
|
|
800
|
+
confidence: 0.95,
|
|
801
|
+
evidence,
|
|
802
|
+
technique: 'Rules Analysis',
|
|
803
|
+
timestamp: new Date().toISOString(),
|
|
804
|
+
resource: `firebase/${config.projectId}/rtdb`,
|
|
805
|
+
exploitability: 'trivial',
|
|
806
|
+
verified: true,
|
|
807
|
+
aptPhase: 'reconnaissance',
|
|
808
|
+
remediation: 'Implement proper security rules, require authentication',
|
|
809
|
+
};
|
|
810
|
+
},
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
id: 'GCP-FIREBASE-STORAGE-001',
|
|
814
|
+
name: 'Firebase Storage Rules Misconfiguration',
|
|
815
|
+
category: 'Firebase',
|
|
816
|
+
aptPhase: 'reconnaissance',
|
|
817
|
+
execute: async (config) => {
|
|
818
|
+
if (!config.projectId)
|
|
819
|
+
return null;
|
|
820
|
+
const evidence = [];
|
|
821
|
+
const vulnerabilities = [];
|
|
822
|
+
const token = await getGCPAccessToken();
|
|
823
|
+
try {
|
|
824
|
+
// Check default Firebase Storage bucket
|
|
825
|
+
const bucketName = `${config.projectId}.appspot.com`;
|
|
826
|
+
const storageResult = await gcpApiCall(`https://storage.googleapis.com/storage/v1/b/${bucketName}?projection=full`, 'GET', undefined, token);
|
|
827
|
+
if (storageResult.statusCode === 200) {
|
|
828
|
+
evidence.push(`Firebase Storage bucket found: ${bucketName}`);
|
|
829
|
+
const bucket = storageResult.data;
|
|
830
|
+
if (!bucket.iamConfiguration?.uniformBucketLevelAccess?.enabled) {
|
|
831
|
+
vulnerabilities.push('Uniform bucket access not enabled');
|
|
832
|
+
}
|
|
833
|
+
if (bucket.iamConfiguration?.publicAccessPrevention !== 'enforced') {
|
|
834
|
+
vulnerabilities.push('Public access prevention not enforced');
|
|
835
|
+
}
|
|
836
|
+
if (bucket.cors && bucket.cors.length > 0) {
|
|
837
|
+
evidence.push(`CORS configured: ${JSON.stringify(bucket.cors)}`);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
catch (e) {
|
|
842
|
+
evidence.push(`Error: ${e}`);
|
|
843
|
+
}
|
|
844
|
+
if (vulnerabilities.length === 0)
|
|
845
|
+
return null;
|
|
846
|
+
return {
|
|
847
|
+
id: 'GCP-FIREBASE-STORAGE-001',
|
|
848
|
+
provider: 'gcp',
|
|
849
|
+
vulnerability: 'Firebase Storage Security Misconfiguration',
|
|
850
|
+
severity: 'high',
|
|
851
|
+
confidence: 0.9,
|
|
852
|
+
evidence,
|
|
853
|
+
technique: 'Storage Config Analysis',
|
|
854
|
+
timestamp: new Date().toISOString(),
|
|
855
|
+
resource: `firebase/${config.projectId}/storage`,
|
|
856
|
+
exploitability: 'moderate',
|
|
857
|
+
verified: true,
|
|
858
|
+
aptPhase: 'reconnaissance',
|
|
859
|
+
remediation: 'Enable uniform access, enforce public prevention, review rules',
|
|
860
|
+
};
|
|
861
|
+
},
|
|
862
|
+
},
|
|
863
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
864
|
+
// ANDROID / PLAY CONSOLE TESTS
|
|
865
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
866
|
+
{
|
|
867
|
+
id: 'GCP-ANDROID-PLAY-001',
|
|
868
|
+
name: 'Google Play Console API Access',
|
|
869
|
+
category: 'Android',
|
|
870
|
+
aptPhase: 'reconnaissance',
|
|
871
|
+
execute: async (config) => {
|
|
872
|
+
const evidence = [];
|
|
873
|
+
const vulnerabilities = [];
|
|
874
|
+
const token = await getGCPAccessToken();
|
|
875
|
+
try {
|
|
876
|
+
// Check Android Publisher API access
|
|
877
|
+
const publisherResult = await gcpApiCall('https://androidpublisher.googleapis.com/androidpublisher/v3/applications', 'GET', undefined, token);
|
|
878
|
+
if (publisherResult.statusCode === 200) {
|
|
879
|
+
evidence.push('Android Publisher API: ACCESSIBLE');
|
|
880
|
+
vulnerabilities.push('Can access Play Console data - potential app manipulation');
|
|
881
|
+
}
|
|
882
|
+
// Check for Play Integrity API
|
|
883
|
+
const integrityResult = await gcpApiCall('https://playintegrity.googleapis.com/v1/deviceRecall', 'GET', undefined, token);
|
|
884
|
+
if (integrityResult.statusCode !== 403) {
|
|
885
|
+
evidence.push('Play Integrity API: ACCESSIBLE');
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
catch (e) {
|
|
889
|
+
evidence.push(`Error: ${e}`);
|
|
890
|
+
}
|
|
891
|
+
if (vulnerabilities.length === 0)
|
|
892
|
+
return null;
|
|
893
|
+
return {
|
|
894
|
+
id: 'GCP-ANDROID-PLAY-001',
|
|
895
|
+
provider: 'gcp',
|
|
896
|
+
vulnerability: 'Google Play Console API Exposure',
|
|
897
|
+
severity: 'critical',
|
|
898
|
+
confidence: 0.9,
|
|
899
|
+
evidence,
|
|
900
|
+
technique: 'API Enumeration',
|
|
901
|
+
timestamp: new Date().toISOString(),
|
|
902
|
+
resource: 'android/play-console',
|
|
903
|
+
exploitability: 'moderate',
|
|
904
|
+
verified: true,
|
|
905
|
+
aptPhase: 'reconnaissance',
|
|
906
|
+
remediation: 'Restrict Play Console API access, use service account scoping',
|
|
907
|
+
};
|
|
908
|
+
},
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
id: 'GCP-ANDROID-FCM-001',
|
|
912
|
+
name: 'Firebase Cloud Messaging Misconfiguration',
|
|
913
|
+
category: 'Android',
|
|
914
|
+
aptPhase: 'reconnaissance',
|
|
915
|
+
execute: async (config) => {
|
|
916
|
+
if (!config.projectId)
|
|
917
|
+
return null;
|
|
918
|
+
const evidence = [];
|
|
919
|
+
const vulnerabilities = [];
|
|
920
|
+
const token = await getGCPAccessToken();
|
|
921
|
+
try {
|
|
922
|
+
// Check FCM API access
|
|
923
|
+
const fcmResult = await gcpApiCall(`https://fcm.googleapis.com/v1/projects/${config.projectId}/messages:send`, 'POST', {
|
|
924
|
+
validate_only: true,
|
|
925
|
+
message: { topic: 'test' },
|
|
926
|
+
}, token);
|
|
927
|
+
if (fcmResult.statusCode === 200 || fcmResult.statusCode === 400) {
|
|
928
|
+
// 400 means we have access but invalid message
|
|
929
|
+
evidence.push('FCM API: ACCESSIBLE');
|
|
930
|
+
if (fcmResult.statusCode === 200) {
|
|
931
|
+
vulnerabilities.push('Can send push notifications - potential phishing vector');
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
catch (e) {
|
|
936
|
+
evidence.push(`Error: ${e}`);
|
|
937
|
+
}
|
|
938
|
+
if (vulnerabilities.length === 0)
|
|
939
|
+
return null;
|
|
940
|
+
return {
|
|
941
|
+
id: 'GCP-ANDROID-FCM-001',
|
|
942
|
+
provider: 'gcp',
|
|
943
|
+
vulnerability: 'Firebase Cloud Messaging Access',
|
|
944
|
+
severity: 'high',
|
|
945
|
+
confidence: 0.85,
|
|
946
|
+
evidence,
|
|
947
|
+
technique: 'FCM API Testing',
|
|
948
|
+
timestamp: new Date().toISOString(),
|
|
949
|
+
resource: `firebase/${config.projectId}/fcm`,
|
|
950
|
+
exploitability: 'moderate',
|
|
951
|
+
verified: true,
|
|
952
|
+
aptPhase: 'reconnaissance',
|
|
953
|
+
remediation: 'Restrict FCM API access, validate message origins',
|
|
954
|
+
};
|
|
955
|
+
},
|
|
956
|
+
},
|
|
957
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
958
|
+
// GOOGLE CLOUD IDENTITY & SECURITY
|
|
959
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
960
|
+
{
|
|
961
|
+
id: 'GCP-IDENTITY-001',
|
|
962
|
+
name: 'Cloud Identity Group Enumeration',
|
|
963
|
+
category: 'Identity',
|
|
964
|
+
aptPhase: 'reconnaissance',
|
|
965
|
+
execute: async (config) => {
|
|
966
|
+
const evidence = [];
|
|
967
|
+
const vulnerabilities = [];
|
|
968
|
+
const token = await getGCPAccessToken();
|
|
969
|
+
try {
|
|
970
|
+
// Check Cloud Identity Groups API
|
|
971
|
+
const groupsResult = await gcpApiCall('https://cloudidentity.googleapis.com/v1/groups?pageSize=10', 'GET', undefined, token);
|
|
972
|
+
if (groupsResult.statusCode === 200) {
|
|
973
|
+
const groups = groupsResult.data.groups || [];
|
|
974
|
+
evidence.push(`Found ${groups.length} Cloud Identity groups`);
|
|
975
|
+
if (groups.length > 0) {
|
|
976
|
+
vulnerabilities.push('Cloud Identity groups enumerable');
|
|
977
|
+
evidence.push(...groups.slice(0, 5).map(g => `Group: ${g.displayName || g.groupKey?.id}`));
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
// Check devices
|
|
981
|
+
const devicesResult = await gcpApiCall('https://cloudidentity.googleapis.com/v1/devices?pageSize=10', 'GET', undefined, token);
|
|
982
|
+
if (devicesResult.statusCode === 200) {
|
|
983
|
+
const devices = devicesResult.data.devices || [];
|
|
984
|
+
if (devices.length > 0) {
|
|
985
|
+
vulnerabilities.push(`Found ${devices.length} managed devices`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
catch (e) {
|
|
990
|
+
evidence.push(`Error: ${e}`);
|
|
991
|
+
}
|
|
992
|
+
if (vulnerabilities.length === 0)
|
|
993
|
+
return null;
|
|
994
|
+
return {
|
|
995
|
+
id: 'GCP-IDENTITY-001',
|
|
996
|
+
provider: 'gcp',
|
|
997
|
+
vulnerability: 'Cloud Identity Enumeration',
|
|
998
|
+
severity: 'medium',
|
|
999
|
+
confidence: 0.85,
|
|
1000
|
+
evidence,
|
|
1001
|
+
technique: 'Identity API Analysis',
|
|
1002
|
+
timestamp: new Date().toISOString(),
|
|
1003
|
+
resource: 'cloudidentity/groups',
|
|
1004
|
+
exploitability: 'moderate',
|
|
1005
|
+
verified: true,
|
|
1006
|
+
aptPhase: 'reconnaissance',
|
|
1007
|
+
remediation: 'Restrict Cloud Identity API access, audit group visibility',
|
|
1008
|
+
};
|
|
1009
|
+
},
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
id: 'GCP-CHRONICLE-001',
|
|
1013
|
+
name: 'Chronicle Security Data Access',
|
|
1014
|
+
category: 'Security',
|
|
1015
|
+
aptPhase: 'reconnaissance',
|
|
1016
|
+
execute: async (config) => {
|
|
1017
|
+
const evidence = [];
|
|
1018
|
+
const vulnerabilities = [];
|
|
1019
|
+
const token = await getGCPAccessToken();
|
|
1020
|
+
try {
|
|
1021
|
+
// Check Chronicle API access
|
|
1022
|
+
const chronicleResult = await gcpApiCall('https://chronicle.googleapis.com/v1alpha/logs:search', 'POST', { query: 'metadata.event_type = "USER_LOGIN"', time_range: { start_time: new Date(Date.now() - 3600000).toISOString(), end_time: new Date().toISOString() } }, token);
|
|
1023
|
+
if (chronicleResult.statusCode === 200) {
|
|
1024
|
+
vulnerabilities.push('Chronicle API accessible - can search security logs');
|
|
1025
|
+
evidence.push('Chronicle Search API: ACCESSIBLE');
|
|
1026
|
+
}
|
|
1027
|
+
// Check detection rules
|
|
1028
|
+
const rulesResult = await gcpApiCall('https://chronicle.googleapis.com/v1alpha/rules', 'GET', undefined, token);
|
|
1029
|
+
if (rulesResult.statusCode === 200) {
|
|
1030
|
+
evidence.push('Chronicle Rules API: ACCESSIBLE');
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
catch (e) {
|
|
1034
|
+
evidence.push(`Chronicle API not enabled or no access: ${e}`);
|
|
1035
|
+
}
|
|
1036
|
+
if (vulnerabilities.length === 0)
|
|
1037
|
+
return null;
|
|
1038
|
+
return {
|
|
1039
|
+
id: 'GCP-CHRONICLE-001',
|
|
1040
|
+
provider: 'gcp',
|
|
1041
|
+
vulnerability: 'Chronicle Security Data Access',
|
|
1042
|
+
severity: 'high',
|
|
1043
|
+
confidence: 0.85,
|
|
1044
|
+
evidence,
|
|
1045
|
+
technique: 'Chronicle API Testing',
|
|
1046
|
+
timestamp: new Date().toISOString(),
|
|
1047
|
+
resource: 'chronicle/logs',
|
|
1048
|
+
exploitability: 'complex',
|
|
1049
|
+
verified: true,
|
|
1050
|
+
aptPhase: 'reconnaissance',
|
|
1051
|
+
remediation: 'Restrict Chronicle API access, implement RBAC',
|
|
1052
|
+
};
|
|
1053
|
+
},
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
id: 'GCP-SECRETMANAGER-001',
|
|
1057
|
+
name: 'Secret Manager Access and Exposure',
|
|
1058
|
+
category: 'Security',
|
|
1059
|
+
aptPhase: 'exploitation',
|
|
1060
|
+
execute: async (config) => {
|
|
1061
|
+
if (!config.projectId)
|
|
1062
|
+
return null;
|
|
1063
|
+
const evidence = [];
|
|
1064
|
+
const vulnerabilities = [];
|
|
1065
|
+
const token = await getGCPAccessToken();
|
|
1066
|
+
try {
|
|
1067
|
+
// List secrets
|
|
1068
|
+
const secretsResult = await gcpApiCall(`https://secretmanager.googleapis.com/v1/projects/${config.projectId}/secrets`, 'GET', undefined, token);
|
|
1069
|
+
if (secretsResult.statusCode === 200) {
|
|
1070
|
+
const secrets = secretsResult.data.secrets || [];
|
|
1071
|
+
evidence.push(`Found ${secrets.length} secrets`);
|
|
1072
|
+
// Check if we can access secret versions
|
|
1073
|
+
for (const secret of secrets.slice(0, 5)) {
|
|
1074
|
+
try {
|
|
1075
|
+
const versionResult = await gcpApiCall(`https://secretmanager.googleapis.com/v1/${secret.name}/versions/latest:access`, 'GET', undefined, token);
|
|
1076
|
+
if (versionResult.statusCode === 200) {
|
|
1077
|
+
vulnerabilities.push(`Can access secret: ${secret.name.split('/').pop()}`);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
catch {
|
|
1081
|
+
evidence.push(`${secret.name.split('/').pop()}: Access denied`);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
catch (e) {
|
|
1087
|
+
evidence.push(`Error: ${e}`);
|
|
1088
|
+
}
|
|
1089
|
+
if (vulnerabilities.length === 0)
|
|
1090
|
+
return null;
|
|
1091
|
+
return {
|
|
1092
|
+
id: 'GCP-SECRETMANAGER-001',
|
|
1093
|
+
provider: 'gcp',
|
|
1094
|
+
vulnerability: 'Secret Manager Secrets Accessible',
|
|
1095
|
+
severity: 'critical',
|
|
1096
|
+
confidence: 0.95,
|
|
1097
|
+
evidence,
|
|
1098
|
+
technique: 'Secret Enumeration',
|
|
1099
|
+
timestamp: new Date().toISOString(),
|
|
1100
|
+
resource: `projects/${config.projectId}/secrets`,
|
|
1101
|
+
exploitability: 'trivial',
|
|
1102
|
+
verified: true,
|
|
1103
|
+
aptPhase: 'exploitation',
|
|
1104
|
+
remediation: 'Restrict secret access, use IAM conditions, enable audit logging',
|
|
1105
|
+
};
|
|
1106
|
+
},
|
|
1107
|
+
},
|
|
1108
|
+
];
|
|
1109
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1110
|
+
// AWS Tests (Skeleton - requires AWS CLI/SDK)
|
|
1111
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1112
|
+
async function getAWSAccessToken() {
|
|
1113
|
+
try {
|
|
1114
|
+
const { stdout } = await execAsync('aws sts get-session-token --output json');
|
|
1115
|
+
const data = JSON.parse(stdout);
|
|
1116
|
+
return data.Credentials?.SessionToken || '';
|
|
1117
|
+
}
|
|
1118
|
+
catch {
|
|
1119
|
+
return '';
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
const AWS_TESTS = [
|
|
1123
|
+
{
|
|
1124
|
+
id: 'AWS-S3-PUBLIC-001',
|
|
1125
|
+
name: 'S3 Bucket Public Access',
|
|
1126
|
+
category: 'Storage',
|
|
1127
|
+
aptPhase: 'reconnaissance',
|
|
1128
|
+
execute: async (config) => {
|
|
1129
|
+
const evidence = [];
|
|
1130
|
+
const vulnerabilities = [];
|
|
1131
|
+
try {
|
|
1132
|
+
const { stdout } = await execAsync('aws s3api list-buckets --output json');
|
|
1133
|
+
const buckets = JSON.parse(stdout).Buckets || [];
|
|
1134
|
+
evidence.push(`Found ${buckets.length} S3 buckets`);
|
|
1135
|
+
for (const bucket of buckets.slice(0, 10)) {
|
|
1136
|
+
try {
|
|
1137
|
+
const { stdout: aclOutput } = await execAsync(`aws s3api get-bucket-acl --bucket ${bucket.Name} --output json`);
|
|
1138
|
+
const acl = JSON.parse(aclOutput);
|
|
1139
|
+
for (const grant of acl.Grants || []) {
|
|
1140
|
+
if (grant.Grantee?.URI?.includes('AllUsers') || grant.Grantee?.URI?.includes('AuthenticatedUsers')) {
|
|
1141
|
+
vulnerabilities.push(`${bucket.Name}: Public via ${grant.Permission}`);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
catch {
|
|
1146
|
+
// Skip inaccessible buckets
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
evidence.push(...vulnerabilities);
|
|
1150
|
+
if (vulnerabilities.length === 0)
|
|
1151
|
+
return null;
|
|
1152
|
+
return {
|
|
1153
|
+
id: 'AWS-S3-PUBLIC-001',
|
|
1154
|
+
provider: 'aws',
|
|
1155
|
+
vulnerability: 'S3 Bucket Public Access',
|
|
1156
|
+
severity: 'critical',
|
|
1157
|
+
confidence: 0.95,
|
|
1158
|
+
evidence,
|
|
1159
|
+
technique: 'ACL Analysis',
|
|
1160
|
+
timestamp: new Date().toISOString(),
|
|
1161
|
+
resource: 's3/buckets',
|
|
1162
|
+
exploitability: 'trivial',
|
|
1163
|
+
verified: true,
|
|
1164
|
+
aptPhase: 'reconnaissance',
|
|
1165
|
+
remediation: 'Enable S3 Block Public Access, review bucket policies',
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
catch (e) {
|
|
1169
|
+
evidence.push(`AWS CLI not configured or error: ${e}`);
|
|
1170
|
+
return null;
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
id: 'AWS-IAM-ADMIN-001',
|
|
1176
|
+
name: 'IAM Users with Admin Access',
|
|
1177
|
+
category: 'IAM',
|
|
1178
|
+
aptPhase: 'reconnaissance',
|
|
1179
|
+
execute: async (config) => {
|
|
1180
|
+
const evidence = [];
|
|
1181
|
+
const vulnerabilities = [];
|
|
1182
|
+
try {
|
|
1183
|
+
const { stdout } = await execAsync('aws iam list-users --output json');
|
|
1184
|
+
const users = JSON.parse(stdout).Users || [];
|
|
1185
|
+
evidence.push(`Found ${users.length} IAM users`);
|
|
1186
|
+
for (const user of users) {
|
|
1187
|
+
try {
|
|
1188
|
+
const { stdout: policiesOutput } = await execAsync(`aws iam list-attached-user-policies --user-name ${user.UserName} --output json`);
|
|
1189
|
+
const policies = JSON.parse(policiesOutput).AttachedPolicies || [];
|
|
1190
|
+
for (const policy of policies) {
|
|
1191
|
+
if (policy.PolicyArn?.includes('AdministratorAccess') || policy.PolicyArn?.includes('PowerUserAccess')) {
|
|
1192
|
+
vulnerabilities.push(`${user.UserName}: Has ${policy.PolicyName}`);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
catch {
|
|
1197
|
+
// Skip inaccessible users
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
evidence.push(...vulnerabilities);
|
|
1201
|
+
if (vulnerabilities.length === 0)
|
|
1202
|
+
return null;
|
|
1203
|
+
return {
|
|
1204
|
+
id: 'AWS-IAM-ADMIN-001',
|
|
1205
|
+
provider: 'aws',
|
|
1206
|
+
vulnerability: 'IAM Users with Excessive Privileges',
|
|
1207
|
+
severity: 'high',
|
|
1208
|
+
confidence: 0.9,
|
|
1209
|
+
evidence,
|
|
1210
|
+
technique: 'Policy Enumeration',
|
|
1211
|
+
timestamp: new Date().toISOString(),
|
|
1212
|
+
resource: 'iam/users',
|
|
1213
|
+
exploitability: 'moderate',
|
|
1214
|
+
verified: true,
|
|
1215
|
+
aptPhase: 'reconnaissance',
|
|
1216
|
+
remediation: 'Apply least privilege, use IAM roles instead',
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
catch (e) {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
id: 'AWS-EC2-SG-001',
|
|
1226
|
+
name: 'Security Groups Open to Internet',
|
|
1227
|
+
category: 'Network',
|
|
1228
|
+
aptPhase: 'reconnaissance',
|
|
1229
|
+
execute: async (config) => {
|
|
1230
|
+
const evidence = [];
|
|
1231
|
+
const vulnerabilities = [];
|
|
1232
|
+
try {
|
|
1233
|
+
const { stdout } = await execAsync('aws ec2 describe-security-groups --output json');
|
|
1234
|
+
const groups = JSON.parse(stdout).SecurityGroups || [];
|
|
1235
|
+
evidence.push(`Found ${groups.length} security groups`);
|
|
1236
|
+
for (const sg of groups) {
|
|
1237
|
+
for (const perm of sg.IpPermissions || []) {
|
|
1238
|
+
for (const range of perm.IpRanges || []) {
|
|
1239
|
+
if (range.CidrIp === '0.0.0.0/0') {
|
|
1240
|
+
const port = perm.FromPort === perm.ToPort ? perm.FromPort : `${perm.FromPort}-${perm.ToPort}`;
|
|
1241
|
+
vulnerabilities.push(`${sg.GroupId}: Open to 0.0.0.0/0 on port ${port}`);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
evidence.push(...vulnerabilities);
|
|
1247
|
+
if (vulnerabilities.length === 0)
|
|
1248
|
+
return null;
|
|
1249
|
+
return {
|
|
1250
|
+
id: 'AWS-EC2-SG-001',
|
|
1251
|
+
provider: 'aws',
|
|
1252
|
+
vulnerability: 'Security Groups Open to Internet',
|
|
1253
|
+
severity: 'critical',
|
|
1254
|
+
confidence: 0.95,
|
|
1255
|
+
evidence,
|
|
1256
|
+
technique: 'Security Group Analysis',
|
|
1257
|
+
timestamp: new Date().toISOString(),
|
|
1258
|
+
resource: 'ec2/security-groups',
|
|
1259
|
+
exploitability: 'trivial',
|
|
1260
|
+
verified: true,
|
|
1261
|
+
aptPhase: 'reconnaissance',
|
|
1262
|
+
remediation: 'Restrict CIDR ranges, use VPC endpoints',
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
catch (e) {
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
},
|
|
1270
|
+
];
|
|
1271
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1272
|
+
// Azure Tests (Skeleton - requires Azure CLI)
|
|
1273
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1274
|
+
const AZURE_TESTS = [
|
|
1275
|
+
{
|
|
1276
|
+
id: 'AZURE-STORAGE-PUBLIC-001',
|
|
1277
|
+
name: 'Storage Account Public Access',
|
|
1278
|
+
category: 'Storage',
|
|
1279
|
+
aptPhase: 'reconnaissance',
|
|
1280
|
+
execute: async (config) => {
|
|
1281
|
+
const evidence = [];
|
|
1282
|
+
const vulnerabilities = [];
|
|
1283
|
+
try {
|
|
1284
|
+
const { stdout } = await execAsync('az storage account list --output json');
|
|
1285
|
+
const accounts = JSON.parse(stdout) || [];
|
|
1286
|
+
evidence.push(`Found ${accounts.length} storage accounts`);
|
|
1287
|
+
for (const account of accounts) {
|
|
1288
|
+
if (account.allowBlobPublicAccess === true) {
|
|
1289
|
+
vulnerabilities.push(`${account.name}: Public blob access enabled`);
|
|
1290
|
+
}
|
|
1291
|
+
if (account.networkRuleSet?.defaultAction === 'Allow') {
|
|
1292
|
+
vulnerabilities.push(`${account.name}: Network default action is Allow`);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
evidence.push(...vulnerabilities);
|
|
1296
|
+
if (vulnerabilities.length === 0)
|
|
1297
|
+
return null;
|
|
1298
|
+
return {
|
|
1299
|
+
id: 'AZURE-STORAGE-PUBLIC-001',
|
|
1300
|
+
provider: 'azure',
|
|
1301
|
+
vulnerability: 'Storage Account Public Access',
|
|
1302
|
+
severity: 'high',
|
|
1303
|
+
confidence: 0.9,
|
|
1304
|
+
evidence,
|
|
1305
|
+
technique: 'Configuration Audit',
|
|
1306
|
+
timestamp: new Date().toISOString(),
|
|
1307
|
+
resource: 'storage/accounts',
|
|
1308
|
+
exploitability: 'moderate',
|
|
1309
|
+
verified: true,
|
|
1310
|
+
aptPhase: 'reconnaissance',
|
|
1311
|
+
remediation: 'Disable public access, configure network rules',
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
catch (e) {
|
|
1315
|
+
return null;
|
|
1316
|
+
}
|
|
1317
|
+
},
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
id: 'AZURE-RBAC-ADMIN-001',
|
|
1321
|
+
name: 'RBAC Owner/Contributor Assignments',
|
|
1322
|
+
category: 'IAM',
|
|
1323
|
+
aptPhase: 'reconnaissance',
|
|
1324
|
+
execute: async (config) => {
|
|
1325
|
+
const evidence = [];
|
|
1326
|
+
const vulnerabilities = [];
|
|
1327
|
+
try {
|
|
1328
|
+
const { stdout } = await execAsync('az role assignment list --all --output json');
|
|
1329
|
+
const assignments = JSON.parse(stdout) || [];
|
|
1330
|
+
evidence.push(`Found ${assignments.length} role assignments`);
|
|
1331
|
+
for (const assignment of assignments) {
|
|
1332
|
+
if (assignment.roleDefinitionName === 'Owner' || assignment.roleDefinitionName === 'Contributor') {
|
|
1333
|
+
if (assignment.scope === '/' || assignment.scope?.split('/').length <= 3) {
|
|
1334
|
+
vulnerabilities.push(`${assignment.principalName}: ${assignment.roleDefinitionName} at ${assignment.scope}`);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
evidence.push(...vulnerabilities);
|
|
1339
|
+
if (vulnerabilities.length === 0)
|
|
1340
|
+
return null;
|
|
1341
|
+
return {
|
|
1342
|
+
id: 'AZURE-RBAC-ADMIN-001',
|
|
1343
|
+
provider: 'azure',
|
|
1344
|
+
vulnerability: 'Broad RBAC Assignments at Subscription Level',
|
|
1345
|
+
severity: 'high',
|
|
1346
|
+
confidence: 0.9,
|
|
1347
|
+
evidence,
|
|
1348
|
+
technique: 'RBAC Analysis',
|
|
1349
|
+
timestamp: new Date().toISOString(),
|
|
1350
|
+
resource: 'rbac/assignments',
|
|
1351
|
+
exploitability: 'moderate',
|
|
1352
|
+
verified: true,
|
|
1353
|
+
aptPhase: 'reconnaissance',
|
|
1354
|
+
remediation: 'Apply least privilege, use resource group scoping',
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
catch (e) {
|
|
1358
|
+
return null;
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
id: 'AZURE-NSG-OPEN-001',
|
|
1364
|
+
name: 'NSG Rules Open to Internet',
|
|
1365
|
+
category: 'Network',
|
|
1366
|
+
aptPhase: 'reconnaissance',
|
|
1367
|
+
execute: async (config) => {
|
|
1368
|
+
const evidence = [];
|
|
1369
|
+
const vulnerabilities = [];
|
|
1370
|
+
try {
|
|
1371
|
+
const { stdout } = await execAsync('az network nsg list --output json');
|
|
1372
|
+
const nsgs = JSON.parse(stdout) || [];
|
|
1373
|
+
evidence.push(`Found ${nsgs.length} NSGs`);
|
|
1374
|
+
for (const nsg of nsgs) {
|
|
1375
|
+
for (const rule of nsg.securityRules || []) {
|
|
1376
|
+
if (rule.sourceAddressPrefix === '*' && rule.direction === 'Inbound' && rule.access === 'Allow') {
|
|
1377
|
+
vulnerabilities.push(`${nsg.name}/${rule.name}: Open to * on port ${rule.destinationPortRange}`);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
evidence.push(...vulnerabilities);
|
|
1382
|
+
if (vulnerabilities.length === 0)
|
|
1383
|
+
return null;
|
|
1384
|
+
return {
|
|
1385
|
+
id: 'AZURE-NSG-OPEN-001',
|
|
1386
|
+
provider: 'azure',
|
|
1387
|
+
vulnerability: 'NSG Rules Open to Internet',
|
|
1388
|
+
severity: 'critical',
|
|
1389
|
+
confidence: 0.95,
|
|
1390
|
+
evidence,
|
|
1391
|
+
technique: 'NSG Analysis',
|
|
1392
|
+
timestamp: new Date().toISOString(),
|
|
1393
|
+
resource: 'network/nsg',
|
|
1394
|
+
exploitability: 'trivial',
|
|
1395
|
+
verified: true,
|
|
1396
|
+
aptPhase: 'reconnaissance',
|
|
1397
|
+
remediation: 'Restrict source addresses, use service tags',
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
catch (e) {
|
|
1401
|
+
return null;
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1404
|
+
},
|
|
1405
|
+
];
|
|
1406
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1407
|
+
// Zero-Day Prediction Engine
|
|
1408
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1409
|
+
function generateZeroDayPredictions(config) {
|
|
1410
|
+
if (!config.includeZeroDay)
|
|
1411
|
+
return [];
|
|
1412
|
+
const predictions = [];
|
|
1413
|
+
const timestamp = new Date().toISOString();
|
|
1414
|
+
const zeroDayHypotheses = [
|
|
1415
|
+
{
|
|
1416
|
+
id: 'ZERODAY-TIMING-001',
|
|
1417
|
+
vulnerability: 'Temporal Coupling in Auth Token Refresh',
|
|
1418
|
+
description: 'Race window during token refresh allows session hijacking',
|
|
1419
|
+
heuristics: ['temporalCoupling', 'trustBoundaryAnalysis'],
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
id: 'ZERODAY-SERIAL-001',
|
|
1423
|
+
vulnerability: 'Deserialization Gadget in API Gateway',
|
|
1424
|
+
description: 'Complex serialization chain allows RCE via crafted payloads',
|
|
1425
|
+
heuristics: ['serializationBoundaries', 'complexityCorrelation'],
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
id: 'ZERODAY-EMERGENT-001',
|
|
1429
|
+
vulnerability: 'Emergent Privilege Escalation via Service Mesh',
|
|
1430
|
+
description: 'Multi-service interaction creates unintended privilege path',
|
|
1431
|
+
heuristics: ['emergentBehaviors', 'trustBoundaryAnalysis'],
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
id: 'ZERODAY-STATE-001',
|
|
1435
|
+
vulnerability: 'Implicit State Dependency Cache Poisoning',
|
|
1436
|
+
description: 'Shared cache state allows cross-tenant data leakage',
|
|
1437
|
+
heuristics: ['implicitStateDependencies', 'errorHandlingAsymmetry'],
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
id: 'ZERODAY-RESOURCE-001',
|
|
1441
|
+
vulnerability: 'Resource Exhaustion via Asymmetric Load',
|
|
1442
|
+
description: 'Unbalanced resource limits enable denial of service',
|
|
1443
|
+
heuristics: ['resourceExhaustion', 'complexityCorrelation'],
|
|
1444
|
+
},
|
|
1445
|
+
];
|
|
1446
|
+
for (const hypothesis of zeroDayHypotheses) {
|
|
1447
|
+
const relevantHeuristics = hypothesis.heuristics.map(h => ZERO_DAY_HEURISTICS[h]);
|
|
1448
|
+
const avgWeight = relevantHeuristics.reduce((sum, h) => sum + h.weight, 0) / relevantHeuristics.length;
|
|
1449
|
+
predictions.push({
|
|
1450
|
+
id: hypothesis.id,
|
|
1451
|
+
provider: config.provider,
|
|
1452
|
+
vulnerability: hypothesis.vulnerability,
|
|
1453
|
+
severity: 'high',
|
|
1454
|
+
confidence: avgWeight * 0.7, // Zero-day predictions have inherent uncertainty
|
|
1455
|
+
evidence: [
|
|
1456
|
+
hypothesis.description,
|
|
1457
|
+
`Based on heuristics: ${hypothesis.heuristics.join(', ')}`,
|
|
1458
|
+
...relevantHeuristics.flatMap(h => h.indicators.slice(0, 2)),
|
|
1459
|
+
],
|
|
1460
|
+
technique: 'Zero-Day Prediction via Heuristic Analysis',
|
|
1461
|
+
timestamp,
|
|
1462
|
+
resource: 'infrastructure',
|
|
1463
|
+
exploitability: 'theoretical',
|
|
1464
|
+
verified: false,
|
|
1465
|
+
aptPhase: 'exploitation',
|
|
1466
|
+
remediation: 'Manual security review recommended',
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
return predictions;
|
|
1470
|
+
}
|
|
1471
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1472
|
+
// Main Audit Engine
|
|
1473
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1474
|
+
export async function runUniversalSecurityAudit(config) {
|
|
1475
|
+
const startTime = new Date();
|
|
1476
|
+
const findings = [];
|
|
1477
|
+
console.log('\n');
|
|
1478
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
1479
|
+
console.log('██ ██');
|
|
1480
|
+
console.log('██ UNIVERSAL SECURITY AUDIT - AGI CORE ██');
|
|
1481
|
+
console.log('██ Live Infrastructure Testing ██');
|
|
1482
|
+
console.log('██ ██');
|
|
1483
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
1484
|
+
console.log(`Provider: ${config.provider.toUpperCase()}`);
|
|
1485
|
+
console.log(`Project/Account: ${config.projectId || config.accountId || config.subscriptionId || 'N/A'}`);
|
|
1486
|
+
console.log(`Organization: ${config.organizationId || 'N/A'}`);
|
|
1487
|
+
console.log(`Timestamp: ${startTime.toISOString()}`);
|
|
1488
|
+
console.log(`Mode: ${config.liveTesting ? 'LIVE TESTING' : 'Configuration Review'}`);
|
|
1489
|
+
console.log('\n');
|
|
1490
|
+
// Select tests based on provider
|
|
1491
|
+
let tests = [];
|
|
1492
|
+
switch (config.provider) {
|
|
1493
|
+
case 'gcp':
|
|
1494
|
+
tests = GCP_TESTS;
|
|
1495
|
+
break;
|
|
1496
|
+
case 'aws':
|
|
1497
|
+
tests = AWS_TESTS;
|
|
1498
|
+
break;
|
|
1499
|
+
case 'azure':
|
|
1500
|
+
tests = AZURE_TESTS;
|
|
1501
|
+
break;
|
|
1502
|
+
case 'custom':
|
|
1503
|
+
// Custom provider uses all available tests
|
|
1504
|
+
tests = [...GCP_TESTS, ...AWS_TESTS, ...AZURE_TESTS];
|
|
1505
|
+
break;
|
|
1506
|
+
}
|
|
1507
|
+
console.log('┌─────────────────────────────────────────────────────────────────────────────┐');
|
|
1508
|
+
console.log('│ EXECUTING SECURITY TESTS │');
|
|
1509
|
+
console.log('└─────────────────────────────────────────────────────────────────────────────┘\n');
|
|
1510
|
+
// Run tests
|
|
1511
|
+
for (const test of tests) {
|
|
1512
|
+
try {
|
|
1513
|
+
console.log(` [${test.category}] ${test.name}...`);
|
|
1514
|
+
const finding = await test.execute(config);
|
|
1515
|
+
if (finding) {
|
|
1516
|
+
findings.push(finding);
|
|
1517
|
+
console.log(` ⚠ FOUND: ${finding.severity.toUpperCase()} - ${finding.vulnerability}`);
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
console.log(` ✓ OK`);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
catch (e) {
|
|
1524
|
+
console.log(` ✗ ERROR: ${e}`);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
// Add zero-day predictions if enabled
|
|
1528
|
+
if (config.includeZeroDay) {
|
|
1529
|
+
console.log('\n');
|
|
1530
|
+
console.log('┌─────────────────────────────────────────────────────────────────────────────┐');
|
|
1531
|
+
console.log('│ ZERO-DAY PREDICTION ENGINE │');
|
|
1532
|
+
console.log('└─────────────────────────────────────────────────────────────────────────────┘\n');
|
|
1533
|
+
const predictions = generateZeroDayPredictions(config);
|
|
1534
|
+
findings.push(...predictions);
|
|
1535
|
+
for (const pred of predictions) {
|
|
1536
|
+
console.log(` [PREDICTION] ${pred.vulnerability}`);
|
|
1537
|
+
console.log(` Confidence: ${(pred.confidence * 100).toFixed(1)}%`);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
const endTime = new Date();
|
|
1541
|
+
const duration = endTime.getTime() - startTime.getTime();
|
|
1542
|
+
// Generate summary
|
|
1543
|
+
const verified = findings.filter(f => f.verified);
|
|
1544
|
+
const summary = {
|
|
1545
|
+
provider: config.provider,
|
|
1546
|
+
startTime: startTime.toISOString(),
|
|
1547
|
+
endTime: endTime.toISOString(),
|
|
1548
|
+
duration,
|
|
1549
|
+
total: findings.length,
|
|
1550
|
+
verified: verified.length,
|
|
1551
|
+
critical: findings.filter(f => f.severity === 'critical').length,
|
|
1552
|
+
high: findings.filter(f => f.severity === 'high').length,
|
|
1553
|
+
medium: findings.filter(f => f.severity === 'medium').length,
|
|
1554
|
+
low: findings.filter(f => f.severity === 'low').length,
|
|
1555
|
+
zeroDay: findings.filter(f => f.exploitability === 'theoretical').length,
|
|
1556
|
+
};
|
|
1557
|
+
// Print summary
|
|
1558
|
+
console.log('\n');
|
|
1559
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
1560
|
+
console.log('██ AUDIT COMPLETE ██');
|
|
1561
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
1562
|
+
console.log(` Total Findings: ${summary.total}`);
|
|
1563
|
+
console.log(` Verified: ${summary.verified}`);
|
|
1564
|
+
console.log(` Critical: ${summary.critical}`);
|
|
1565
|
+
console.log(` High: ${summary.high}`);
|
|
1566
|
+
console.log(` Medium: ${summary.medium}`);
|
|
1567
|
+
console.log(` Low: ${summary.low}`);
|
|
1568
|
+
console.log(` Zero-Day Predictions: ${summary.zeroDay}`);
|
|
1569
|
+
console.log(`\n Duration: ${(duration / 1000).toFixed(2)}s`);
|
|
1570
|
+
if (verified.length > 0) {
|
|
1571
|
+
console.log('\n');
|
|
1572
|
+
console.log('┌─────────────────────────────────────────────────────────────────────────────┐');
|
|
1573
|
+
console.log('│ CONFIRMED VULNERABILITIES │');
|
|
1574
|
+
console.log('└─────────────────────────────────────────────────────────────────────────────┘\n');
|
|
1575
|
+
for (const v of verified) {
|
|
1576
|
+
console.log(` ⚠ [${v.severity.toUpperCase()}] ${v.vulnerability}`);
|
|
1577
|
+
console.log(` ID: ${v.id}`);
|
|
1578
|
+
console.log(` Resource: ${v.resource}`);
|
|
1579
|
+
console.log(` Confidence: ${(v.confidence * 100).toFixed(1)}%`);
|
|
1580
|
+
console.log(` Exploitability: ${v.exploitability}`);
|
|
1581
|
+
if (v.remediation) {
|
|
1582
|
+
console.log(` Remediation: ${v.remediation}`);
|
|
1583
|
+
}
|
|
1584
|
+
console.log('');
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
1588
|
+
return { findings, summary };
|
|
1589
|
+
}
|
|
1590
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1591
|
+
// Multi-Provider Audit
|
|
1592
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1593
|
+
export async function runMultiProviderAudit(configs) {
|
|
1594
|
+
const results = new Map();
|
|
1595
|
+
console.log('\n');
|
|
1596
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
1597
|
+
console.log('██ ██');
|
|
1598
|
+
console.log('██ MULTI-PROVIDER SECURITY AUDIT ██');
|
|
1599
|
+
console.log('██ ██');
|
|
1600
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
1601
|
+
for (const config of configs) {
|
|
1602
|
+
console.log(`\n▶ Starting audit for ${config.provider.toUpperCase()}...\n`);
|
|
1603
|
+
const result = await runUniversalSecurityAudit(config);
|
|
1604
|
+
results.set(config.provider, result);
|
|
1605
|
+
}
|
|
1606
|
+
// Aggregate summary
|
|
1607
|
+
console.log('\n');
|
|
1608
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
1609
|
+
console.log('██ AGGREGATE SUMMARY ██');
|
|
1610
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
1611
|
+
let totalFindings = 0;
|
|
1612
|
+
let totalCritical = 0;
|
|
1613
|
+
let totalHigh = 0;
|
|
1614
|
+
for (const [provider, result] of results) {
|
|
1615
|
+
console.log(` ${provider.toUpperCase()}: ${result.summary.total} findings (${result.summary.critical} critical, ${result.summary.high} high)`);
|
|
1616
|
+
totalFindings += result.summary.total;
|
|
1617
|
+
totalCritical += result.summary.critical;
|
|
1618
|
+
totalHigh += result.summary.high;
|
|
1619
|
+
}
|
|
1620
|
+
console.log(`\n TOTAL: ${totalFindings} findings across ${configs.length} providers`);
|
|
1621
|
+
console.log(` Critical: ${totalCritical}, High: ${totalHigh}`);
|
|
1622
|
+
console.log('\n████████████████████████████████████████████████████████████████████████████████\n');
|
|
1623
|
+
return results;
|
|
1624
|
+
}
|
|
1625
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1626
|
+
// Default Export - Security Audit as Default Capability
|
|
1627
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1628
|
+
export default runUniversalSecurityAudit;
|
|
1629
|
+
// GCP Remediation Functions
|
|
1630
|
+
const GCP_REMEDIATIONS = {
|
|
1631
|
+
'GCP-STORAGE-ACL-001': async (finding, config) => {
|
|
1632
|
+
const details = [];
|
|
1633
|
+
const token = await getGCPAccessToken();
|
|
1634
|
+
// Extract bucket names from evidence
|
|
1635
|
+
const bucketMatches = finding.evidence.filter(e => e.includes('bucket') || e.includes('Legacy ACL') || e.includes('PUBLIC'));
|
|
1636
|
+
for (const match of bucketMatches) {
|
|
1637
|
+
const bucketName = match.split(':')[0].trim();
|
|
1638
|
+
if (!bucketName || bucketName === 'Found')
|
|
1639
|
+
continue;
|
|
1640
|
+
try {
|
|
1641
|
+
// Enable uniform bucket-level access
|
|
1642
|
+
await gcpApiCall(`https://storage.googleapis.com/storage/v1/b/${bucketName}?fields=iamConfiguration`, 'PATCH', {
|
|
1643
|
+
iamConfiguration: {
|
|
1644
|
+
uniformBucketLevelAccess: { enabled: true },
|
|
1645
|
+
publicAccessPrevention: 'enforced',
|
|
1646
|
+
},
|
|
1647
|
+
}, token);
|
|
1648
|
+
details.push(`Fixed: ${bucketName} - Enabled uniform access, enforced public prevention`);
|
|
1649
|
+
}
|
|
1650
|
+
catch (e) {
|
|
1651
|
+
details.push(`Failed: ${bucketName} - ${e}`);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
return {
|
|
1655
|
+
findingId: finding.id,
|
|
1656
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1657
|
+
action: 'Enable uniform bucket-level access and public access prevention',
|
|
1658
|
+
details,
|
|
1659
|
+
timestamp: new Date().toISOString(),
|
|
1660
|
+
rollbackCommand: 'gcloud storage buckets update gs://BUCKET --no-uniform-bucket-level-access',
|
|
1661
|
+
};
|
|
1662
|
+
},
|
|
1663
|
+
'GCP-FIREWALL-OPEN-001': async (finding, config) => {
|
|
1664
|
+
const details = [];
|
|
1665
|
+
const token = await getGCPAccessToken();
|
|
1666
|
+
// Extract firewall rule names from evidence
|
|
1667
|
+
const ruleMatches = finding.evidence.filter(e => e.includes('0.0.0.0/0'));
|
|
1668
|
+
for (const match of ruleMatches) {
|
|
1669
|
+
const ruleName = match.split(':')[0].trim();
|
|
1670
|
+
if (!ruleName || ruleName === 'Found')
|
|
1671
|
+
continue;
|
|
1672
|
+
try {
|
|
1673
|
+
// Delete or restrict the firewall rule
|
|
1674
|
+
// For safety, we'll add a deny rule with higher priority instead of deleting
|
|
1675
|
+
await gcpApiCall(`https://compute.googleapis.com/compute/v1/projects/${config.projectId}/global/firewalls`, 'POST', {
|
|
1676
|
+
name: `block-${ruleName}-remediation`,
|
|
1677
|
+
network: `projects/${config.projectId}/global/networks/default`,
|
|
1678
|
+
priority: 100, // High priority to override
|
|
1679
|
+
direction: 'INGRESS',
|
|
1680
|
+
denied: [{ IPProtocol: 'all' }],
|
|
1681
|
+
sourceRanges: ['0.0.0.0/0'],
|
|
1682
|
+
description: `Auto-remediation: Blocks open access from ${ruleName}`,
|
|
1683
|
+
}, token);
|
|
1684
|
+
details.push(`Fixed: Added blocking rule for ${ruleName}`);
|
|
1685
|
+
}
|
|
1686
|
+
catch (e) {
|
|
1687
|
+
details.push(`Failed: ${ruleName} - ${e}`);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return {
|
|
1691
|
+
findingId: finding.id,
|
|
1692
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1693
|
+
action: 'Add high-priority deny rules to block 0.0.0.0/0 access',
|
|
1694
|
+
details,
|
|
1695
|
+
timestamp: new Date().toISOString(),
|
|
1696
|
+
rollbackCommand: `gcloud compute firewall-rules delete block-*-remediation --project=${config.projectId}`,
|
|
1697
|
+
};
|
|
1698
|
+
},
|
|
1699
|
+
'GCP-VPC-SC-001': async (finding, config) => {
|
|
1700
|
+
// VPC Service Controls require organization-level access, provide guidance
|
|
1701
|
+
return {
|
|
1702
|
+
findingId: finding.id,
|
|
1703
|
+
success: false,
|
|
1704
|
+
action: 'VPC Service Controls configuration requires organization admin',
|
|
1705
|
+
details: [
|
|
1706
|
+
'Remediation requires organization-level permissions',
|
|
1707
|
+
'Recommended: Create access policy and service perimeter',
|
|
1708
|
+
`Command: gcloud access-context-manager policies create --organization=${config.organizationId || 'ORG_ID'} --title="Security Perimeter"`,
|
|
1709
|
+
'Then: gcloud access-context-manager perimeters create NAME --policy=POLICY_ID --resources=projects/PROJECT_NUMBER',
|
|
1710
|
+
],
|
|
1711
|
+
timestamp: new Date().toISOString(),
|
|
1712
|
+
};
|
|
1713
|
+
},
|
|
1714
|
+
'GCP-GKE-SECURITY-001': async (finding, config) => {
|
|
1715
|
+
const details = [];
|
|
1716
|
+
// Extract cluster names from evidence
|
|
1717
|
+
const clusterMatches = finding.evidence.filter(e => e.includes('No Workload Identity') ||
|
|
1718
|
+
e.includes('Shielded Nodes') ||
|
|
1719
|
+
e.includes('No Network Policy') ||
|
|
1720
|
+
e.includes('Master not restricted'));
|
|
1721
|
+
for (const match of clusterMatches) {
|
|
1722
|
+
const clusterName = match.split(':')[0].trim();
|
|
1723
|
+
if (!clusterName)
|
|
1724
|
+
continue;
|
|
1725
|
+
try {
|
|
1726
|
+
// Enable Workload Identity
|
|
1727
|
+
await execAsync(`gcloud container clusters update ${clusterName} --workload-pool=${config.projectId}.svc.id.goog --project=${config.projectId} --quiet`);
|
|
1728
|
+
details.push(`Fixed: ${clusterName} - Enabled Workload Identity`);
|
|
1729
|
+
}
|
|
1730
|
+
catch (e) {
|
|
1731
|
+
details.push(`Failed Workload Identity: ${clusterName} - ${e}`);
|
|
1732
|
+
}
|
|
1733
|
+
try {
|
|
1734
|
+
// Enable Network Policy
|
|
1735
|
+
await execAsync(`gcloud container clusters update ${clusterName} --enable-network-policy --project=${config.projectId} --quiet`);
|
|
1736
|
+
details.push(`Fixed: ${clusterName} - Enabled Network Policy`);
|
|
1737
|
+
}
|
|
1738
|
+
catch (e) {
|
|
1739
|
+
details.push(`Failed Network Policy: ${clusterName} - ${e}`);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return {
|
|
1743
|
+
findingId: finding.id,
|
|
1744
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1745
|
+
action: 'Enable Workload Identity and Network Policy on GKE clusters',
|
|
1746
|
+
details,
|
|
1747
|
+
timestamp: new Date().toISOString(),
|
|
1748
|
+
};
|
|
1749
|
+
},
|
|
1750
|
+
'GCP-SA-KEY-RACE-001': async (finding, config) => {
|
|
1751
|
+
const details = [];
|
|
1752
|
+
const token = await getGCPAccessToken();
|
|
1753
|
+
// Restrict SA key creation via organization policy
|
|
1754
|
+
try {
|
|
1755
|
+
// Set organization policy to disable SA key creation
|
|
1756
|
+
await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:setOrgPolicy`, 'POST', {
|
|
1757
|
+
policy: {
|
|
1758
|
+
constraint: 'constraints/iam.disableServiceAccountKeyCreation',
|
|
1759
|
+
booleanPolicy: { enforced: true },
|
|
1760
|
+
},
|
|
1761
|
+
}, token);
|
|
1762
|
+
details.push('Fixed: Disabled service account key creation via organization policy');
|
|
1763
|
+
}
|
|
1764
|
+
catch (e) {
|
|
1765
|
+
details.push(`Failed: Could not set org policy - ${e}`);
|
|
1766
|
+
details.push('Manual remediation: Enable Workload Identity Federation instead of SA keys');
|
|
1767
|
+
}
|
|
1768
|
+
return {
|
|
1769
|
+
findingId: finding.id,
|
|
1770
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1771
|
+
action: 'Disable service account key creation, use Workload Identity',
|
|
1772
|
+
details,
|
|
1773
|
+
timestamp: new Date().toISOString(),
|
|
1774
|
+
rollbackCommand: `gcloud resource-manager org-policies delete iam.disableServiceAccountKeyCreation --project=${config.projectId}`,
|
|
1775
|
+
};
|
|
1776
|
+
},
|
|
1777
|
+
'GCP-IAM-CROSS-PROJECT-001': async (finding, config) => {
|
|
1778
|
+
const details = [];
|
|
1779
|
+
const token = await getGCPAccessToken();
|
|
1780
|
+
// Get current IAM policy
|
|
1781
|
+
const policyResult = await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:getIamPolicy`, 'POST', { options: { requestedPolicyVersion: 3 } }, token);
|
|
1782
|
+
const policy = policyResult.data;
|
|
1783
|
+
const originalBindings = JSON.stringify(policy.bindings);
|
|
1784
|
+
// Filter out cross-project SAs and public access
|
|
1785
|
+
const newBindings = policy.bindings.map(binding => ({
|
|
1786
|
+
...binding,
|
|
1787
|
+
members: binding.members.filter(member => {
|
|
1788
|
+
if (member === 'allUsers' || member === 'allAuthenticatedUsers') {
|
|
1789
|
+
details.push(`Removed: ${member} from ${binding.role}`);
|
|
1790
|
+
return false;
|
|
1791
|
+
}
|
|
1792
|
+
// Keep cross-project SAs but log them (removing might break dependencies)
|
|
1793
|
+
if (member.startsWith('serviceAccount:') && !member.includes(config.projectId || '')) {
|
|
1794
|
+
details.push(`Warning: Cross-project SA ${member} has ${binding.role} - review manually`);
|
|
1795
|
+
}
|
|
1796
|
+
return true;
|
|
1797
|
+
}),
|
|
1798
|
+
})).filter(binding => binding.members.length > 0);
|
|
1799
|
+
if (JSON.stringify(newBindings) !== originalBindings) {
|
|
1800
|
+
try {
|
|
1801
|
+
await gcpApiCall(`https://cloudresourcemanager.googleapis.com/v1/projects/${config.projectId}:setIamPolicy`, 'POST', {
|
|
1802
|
+
policy: {
|
|
1803
|
+
bindings: newBindings,
|
|
1804
|
+
etag: policy.etag,
|
|
1805
|
+
version: 3,
|
|
1806
|
+
},
|
|
1807
|
+
}, token);
|
|
1808
|
+
details.push('Fixed: Removed public access bindings');
|
|
1809
|
+
}
|
|
1810
|
+
catch (e) {
|
|
1811
|
+
details.push(`Failed to update policy: ${e}`);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
return {
|
|
1815
|
+
findingId: finding.id,
|
|
1816
|
+
success: details.some(d => d.startsWith('Fixed') || d.startsWith('Removed')),
|
|
1817
|
+
action: 'Remove public access (allUsers/allAuthenticatedUsers) from IAM bindings',
|
|
1818
|
+
details,
|
|
1819
|
+
timestamp: new Date().toISOString(),
|
|
1820
|
+
};
|
|
1821
|
+
},
|
|
1822
|
+
'GCP-BIGQUERY-EXPOSURE-001': async (finding, config) => {
|
|
1823
|
+
const details = [];
|
|
1824
|
+
const token = await getGCPAccessToken();
|
|
1825
|
+
// Extract dataset names from evidence
|
|
1826
|
+
const datasetMatches = finding.evidence.filter(e => e.includes('PUBLIC'));
|
|
1827
|
+
for (const match of datasetMatches) {
|
|
1828
|
+
const datasetId = match.split(':')[0].trim();
|
|
1829
|
+
if (!datasetId || datasetId === 'Found')
|
|
1830
|
+
continue;
|
|
1831
|
+
try {
|
|
1832
|
+
// Get current dataset access
|
|
1833
|
+
const detailResult = await gcpApiCall(`https://bigquery.googleapis.com/bigquery/v2/projects/${config.projectId}/datasets/${datasetId}`, 'GET', undefined, token);
|
|
1834
|
+
const data = detailResult.data;
|
|
1835
|
+
// Filter out public access
|
|
1836
|
+
const newAccess = data.access.filter(a => {
|
|
1837
|
+
if (a.specialGroup === 'allAuthenticatedUsers' || a.specialGroup === 'allUsers') {
|
|
1838
|
+
details.push(`Removed: ${a.specialGroup} from ${datasetId}`);
|
|
1839
|
+
return false;
|
|
1840
|
+
}
|
|
1841
|
+
if (a.iamMember?.startsWith('allUsers') || a.iamMember?.startsWith('allAuthenticatedUsers')) {
|
|
1842
|
+
details.push(`Removed: ${a.iamMember} from ${datasetId}`);
|
|
1843
|
+
return false;
|
|
1844
|
+
}
|
|
1845
|
+
return true;
|
|
1846
|
+
});
|
|
1847
|
+
// Update dataset
|
|
1848
|
+
await gcpApiCall(`https://bigquery.googleapis.com/bigquery/v2/projects/${config.projectId}/datasets/${datasetId}`, 'PATCH', { access: newAccess }, token);
|
|
1849
|
+
details.push(`Fixed: ${datasetId} - Removed public access`);
|
|
1850
|
+
}
|
|
1851
|
+
catch (e) {
|
|
1852
|
+
details.push(`Failed: ${datasetId} - ${e}`);
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
return {
|
|
1856
|
+
findingId: finding.id,
|
|
1857
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1858
|
+
action: 'Remove public access from BigQuery datasets',
|
|
1859
|
+
details,
|
|
1860
|
+
timestamp: new Date().toISOString(),
|
|
1861
|
+
};
|
|
1862
|
+
},
|
|
1863
|
+
};
|
|
1864
|
+
// AWS Remediation Functions
|
|
1865
|
+
const AWS_REMEDIATIONS = {
|
|
1866
|
+
'AWS-S3-PUBLIC-001': async (finding, config) => {
|
|
1867
|
+
const details = [];
|
|
1868
|
+
// Extract bucket names from evidence
|
|
1869
|
+
const bucketMatches = finding.evidence.filter(e => e.includes('Public via'));
|
|
1870
|
+
for (const match of bucketMatches) {
|
|
1871
|
+
const bucketName = match.split(':')[0].trim();
|
|
1872
|
+
if (!bucketName || bucketName === 'Found')
|
|
1873
|
+
continue;
|
|
1874
|
+
try {
|
|
1875
|
+
// Enable S3 Block Public Access
|
|
1876
|
+
await execAsync(`aws s3api put-public-access-block --bucket ${bucketName} --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"`);
|
|
1877
|
+
details.push(`Fixed: ${bucketName} - Enabled Block Public Access`);
|
|
1878
|
+
}
|
|
1879
|
+
catch (e) {
|
|
1880
|
+
details.push(`Failed: ${bucketName} - ${e}`);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
return {
|
|
1884
|
+
findingId: finding.id,
|
|
1885
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1886
|
+
action: 'Enable S3 Block Public Access on all buckets',
|
|
1887
|
+
details,
|
|
1888
|
+
timestamp: new Date().toISOString(),
|
|
1889
|
+
rollbackCommand: 'aws s3api delete-public-access-block --bucket BUCKET_NAME',
|
|
1890
|
+
};
|
|
1891
|
+
},
|
|
1892
|
+
'AWS-EC2-SG-001': async (finding, config) => {
|
|
1893
|
+
const details = [];
|
|
1894
|
+
// Extract security group IDs from evidence
|
|
1895
|
+
const sgMatches = finding.evidence.filter(e => e.includes('0.0.0.0/0'));
|
|
1896
|
+
for (const match of sgMatches) {
|
|
1897
|
+
const sgId = match.split(':')[0].trim();
|
|
1898
|
+
if (!sgId || !sgId.startsWith('sg-'))
|
|
1899
|
+
continue;
|
|
1900
|
+
try {
|
|
1901
|
+
// Remove 0.0.0.0/0 ingress rules
|
|
1902
|
+
const { stdout: rulesOutput } = await execAsync(`aws ec2 describe-security-groups --group-ids ${sgId} --output json`);
|
|
1903
|
+
const sg = JSON.parse(rulesOutput).SecurityGroups[0];
|
|
1904
|
+
for (const perm of sg.IpPermissions || []) {
|
|
1905
|
+
for (const range of perm.IpRanges || []) {
|
|
1906
|
+
if (range.CidrIp === '0.0.0.0/0') {
|
|
1907
|
+
await execAsync(`aws ec2 revoke-security-group-ingress --group-id ${sgId} --protocol ${perm.IpProtocol} --port ${perm.FromPort}-${perm.ToPort} --cidr 0.0.0.0/0`);
|
|
1908
|
+
details.push(`Fixed: ${sgId} - Revoked 0.0.0.0/0 on port ${perm.FromPort}`);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
catch (e) {
|
|
1914
|
+
details.push(`Failed: ${sgId} - ${e}`);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
return {
|
|
1918
|
+
findingId: finding.id,
|
|
1919
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1920
|
+
action: 'Revoke 0.0.0.0/0 ingress rules from security groups',
|
|
1921
|
+
details,
|
|
1922
|
+
timestamp: new Date().toISOString(),
|
|
1923
|
+
};
|
|
1924
|
+
},
|
|
1925
|
+
'AWS-IAM-ADMIN-001': async (finding, config) => {
|
|
1926
|
+
// IAM admin removal requires careful review - provide guidance only
|
|
1927
|
+
return {
|
|
1928
|
+
findingId: finding.id,
|
|
1929
|
+
success: false,
|
|
1930
|
+
action: 'IAM admin policy removal requires manual review',
|
|
1931
|
+
details: [
|
|
1932
|
+
'Automatic removal of admin policies could break critical access',
|
|
1933
|
+
'Recommended: Review each user and apply least privilege',
|
|
1934
|
+
'Steps:',
|
|
1935
|
+
'1. aws iam list-attached-user-policies --user-name USER',
|
|
1936
|
+
'2. aws iam detach-user-policy --user-name USER --policy-arn ARN',
|
|
1937
|
+
'3. Create custom policy with minimum required permissions',
|
|
1938
|
+
],
|
|
1939
|
+
timestamp: new Date().toISOString(),
|
|
1940
|
+
};
|
|
1941
|
+
},
|
|
1942
|
+
};
|
|
1943
|
+
// Azure Remediation Functions
|
|
1944
|
+
const AZURE_REMEDIATIONS = {
|
|
1945
|
+
'AZURE-STORAGE-PUBLIC-001': async (finding, config) => {
|
|
1946
|
+
const details = [];
|
|
1947
|
+
// Extract storage account names from evidence
|
|
1948
|
+
const accountMatches = finding.evidence.filter(e => e.includes('Public') || e.includes('Allow'));
|
|
1949
|
+
for (const match of accountMatches) {
|
|
1950
|
+
const accountName = match.split(':')[0].trim();
|
|
1951
|
+
if (!accountName || accountName === 'Found')
|
|
1952
|
+
continue;
|
|
1953
|
+
try {
|
|
1954
|
+
// Disable public blob access
|
|
1955
|
+
await execAsync(`az storage account update --name ${accountName} --allow-blob-public-access false`);
|
|
1956
|
+
details.push(`Fixed: ${accountName} - Disabled public blob access`);
|
|
1957
|
+
// Set network default action to Deny
|
|
1958
|
+
await execAsync(`az storage account update --name ${accountName} --default-action Deny`);
|
|
1959
|
+
details.push(`Fixed: ${accountName} - Set network default to Deny`);
|
|
1960
|
+
}
|
|
1961
|
+
catch (e) {
|
|
1962
|
+
details.push(`Failed: ${accountName} - ${e}`);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
return {
|
|
1966
|
+
findingId: finding.id,
|
|
1967
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1968
|
+
action: 'Disable public access and restrict network rules',
|
|
1969
|
+
details,
|
|
1970
|
+
timestamp: new Date().toISOString(),
|
|
1971
|
+
rollbackCommand: 'az storage account update --name ACCOUNT --allow-blob-public-access true --default-action Allow',
|
|
1972
|
+
};
|
|
1973
|
+
},
|
|
1974
|
+
'AZURE-NSG-OPEN-001': async (finding, config) => {
|
|
1975
|
+
const details = [];
|
|
1976
|
+
// Extract NSG rule info from evidence
|
|
1977
|
+
const ruleMatches = finding.evidence.filter(e => e.includes('Open to *'));
|
|
1978
|
+
for (const match of ruleMatches) {
|
|
1979
|
+
const parts = match.split('/');
|
|
1980
|
+
const nsgName = parts[0]?.trim();
|
|
1981
|
+
const ruleName = parts[1]?.split(':')[0]?.trim();
|
|
1982
|
+
if (!nsgName || !ruleName)
|
|
1983
|
+
continue;
|
|
1984
|
+
try {
|
|
1985
|
+
// Delete the permissive rule
|
|
1986
|
+
await execAsync(`az network nsg rule delete --nsg-name ${nsgName} --name ${ruleName} --resource-group RESOURCE_GROUP`);
|
|
1987
|
+
details.push(`Fixed: ${nsgName}/${ruleName} - Deleted open rule`);
|
|
1988
|
+
}
|
|
1989
|
+
catch (e) {
|
|
1990
|
+
details.push(`Failed: ${nsgName}/${ruleName} - ${e}`);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
return {
|
|
1994
|
+
findingId: finding.id,
|
|
1995
|
+
success: details.some(d => d.startsWith('Fixed')),
|
|
1996
|
+
action: 'Delete NSG rules open to all sources',
|
|
1997
|
+
details,
|
|
1998
|
+
timestamp: new Date().toISOString(),
|
|
1999
|
+
};
|
|
2000
|
+
},
|
|
2001
|
+
'AZURE-RBAC-ADMIN-001': async (finding, config) => {
|
|
2002
|
+
// RBAC removal requires manual review
|
|
2003
|
+
return {
|
|
2004
|
+
findingId: finding.id,
|
|
2005
|
+
success: false,
|
|
2006
|
+
action: 'RBAC assignment removal requires manual review',
|
|
2007
|
+
details: [
|
|
2008
|
+
'Automatic removal of Owner/Contributor roles could break access',
|
|
2009
|
+
'Recommended: Review each assignment and scope down',
|
|
2010
|
+
'Steps:',
|
|
2011
|
+
'1. az role assignment list --all',
|
|
2012
|
+
'2. az role assignment delete --assignee PRINCIPAL --role ROLE --scope SCOPE',
|
|
2013
|
+
'3. Create resource-group-scoped assignments instead',
|
|
2014
|
+
],
|
|
2015
|
+
timestamp: new Date().toISOString(),
|
|
2016
|
+
};
|
|
2017
|
+
},
|
|
2018
|
+
};
|
|
2019
|
+
/**
|
|
2020
|
+
* Apply automatic remediations for all confirmed vulnerabilities
|
|
2021
|
+
*/
|
|
2022
|
+
export async function remediateFindings(findings, config, options = {}) {
|
|
2023
|
+
console.log('\n');
|
|
2024
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
2025
|
+
console.log('██ ██');
|
|
2026
|
+
console.log('██ AUTOMATIC REMEDIATION ENGINE ██');
|
|
2027
|
+
console.log('██ Fixing Confirmed Vulnerabilities ██');
|
|
2028
|
+
console.log('██ ██');
|
|
2029
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
2030
|
+
if (options.dryRun) {
|
|
2031
|
+
console.log(' MODE: DRY RUN - No changes will be made\n');
|
|
2032
|
+
}
|
|
2033
|
+
const results = [];
|
|
2034
|
+
let fixed = 0;
|
|
2035
|
+
let failed = 0;
|
|
2036
|
+
let skipped = 0;
|
|
2037
|
+
// Only remediate verified findings
|
|
2038
|
+
const verifiedFindings = findings.filter(f => f.verified && f.exploitability !== 'theoretical');
|
|
2039
|
+
console.log(` Findings to remediate: ${verifiedFindings.length}\n`);
|
|
2040
|
+
for (const finding of verifiedFindings) {
|
|
2041
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.vulnerability}`);
|
|
2042
|
+
console.log(` ID: ${finding.id}`);
|
|
2043
|
+
// Select remediation function based on provider
|
|
2044
|
+
let remediationFn;
|
|
2045
|
+
switch (finding.provider) {
|
|
2046
|
+
case 'gcp':
|
|
2047
|
+
remediationFn = GCP_REMEDIATIONS[finding.id];
|
|
2048
|
+
break;
|
|
2049
|
+
case 'aws':
|
|
2050
|
+
remediationFn = AWS_REMEDIATIONS[finding.id];
|
|
2051
|
+
break;
|
|
2052
|
+
case 'azure':
|
|
2053
|
+
remediationFn = AZURE_REMEDIATIONS[finding.id];
|
|
2054
|
+
break;
|
|
2055
|
+
}
|
|
2056
|
+
if (!remediationFn) {
|
|
2057
|
+
console.log(` ⊘ No automatic remediation available`);
|
|
2058
|
+
console.log(` Manual: ${finding.remediation || 'See documentation'}\n`);
|
|
2059
|
+
skipped++;
|
|
2060
|
+
results.push({
|
|
2061
|
+
findingId: finding.id,
|
|
2062
|
+
success: false,
|
|
2063
|
+
action: 'No automatic remediation available',
|
|
2064
|
+
details: [finding.remediation || 'Manual remediation required'],
|
|
2065
|
+
timestamp: new Date().toISOString(),
|
|
2066
|
+
});
|
|
2067
|
+
continue;
|
|
2068
|
+
}
|
|
2069
|
+
if (options.dryRun) {
|
|
2070
|
+
console.log(` [DRY RUN] Would apply remediation`);
|
|
2071
|
+
console.log(` Action: ${finding.remediation}\n`);
|
|
2072
|
+
skipped++;
|
|
2073
|
+
continue;
|
|
2074
|
+
}
|
|
2075
|
+
try {
|
|
2076
|
+
console.log(` Applying remediation...`);
|
|
2077
|
+
const result = await remediationFn(finding, config);
|
|
2078
|
+
results.push(result);
|
|
2079
|
+
if (result.success) {
|
|
2080
|
+
console.log(` ✓ FIXED`);
|
|
2081
|
+
for (const detail of result.details.slice(0, 3)) {
|
|
2082
|
+
console.log(` ${detail}`);
|
|
2083
|
+
}
|
|
2084
|
+
fixed++;
|
|
2085
|
+
}
|
|
2086
|
+
else {
|
|
2087
|
+
console.log(` ⚠ PARTIAL/FAILED`);
|
|
2088
|
+
for (const detail of result.details.slice(0, 3)) {
|
|
2089
|
+
console.log(` ${detail}`);
|
|
2090
|
+
}
|
|
2091
|
+
failed++;
|
|
2092
|
+
}
|
|
2093
|
+
if (result.rollbackCommand) {
|
|
2094
|
+
console.log(` Rollback: ${result.rollbackCommand}`);
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
catch (e) {
|
|
2098
|
+
console.log(` ✗ ERROR: ${e}`);
|
|
2099
|
+
failed++;
|
|
2100
|
+
results.push({
|
|
2101
|
+
findingId: finding.id,
|
|
2102
|
+
success: false,
|
|
2103
|
+
action: 'Remediation failed',
|
|
2104
|
+
details: [`Error: ${e}`],
|
|
2105
|
+
timestamp: new Date().toISOString(),
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
console.log('');
|
|
2109
|
+
}
|
|
2110
|
+
// Summary
|
|
2111
|
+
console.log('████████████████████████████████████████████████████████████████████████████████');
|
|
2112
|
+
console.log('██ REMEDIATION COMPLETE ██');
|
|
2113
|
+
console.log('████████████████████████████████████████████████████████████████████████████████\n');
|
|
2114
|
+
console.log(` Total: ${verifiedFindings.length}`);
|
|
2115
|
+
console.log(` Fixed: ${fixed}`);
|
|
2116
|
+
console.log(` Failed: ${failed}`);
|
|
2117
|
+
console.log(` Skipped: ${skipped}`);
|
|
2118
|
+
console.log('\n████████████████████████████████████████████████████████████████████████████████\n');
|
|
2119
|
+
return {
|
|
2120
|
+
total: verifiedFindings.length,
|
|
2121
|
+
fixed,
|
|
2122
|
+
failed,
|
|
2123
|
+
skipped,
|
|
2124
|
+
results,
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Run full security audit with automatic remediation
|
|
2129
|
+
*/
|
|
2130
|
+
export async function runSecurityAuditWithRemediation(config, options = {}) {
|
|
2131
|
+
// Run the audit
|
|
2132
|
+
const audit = await runUniversalSecurityAudit(config);
|
|
2133
|
+
// Apply remediations if requested
|
|
2134
|
+
if (options.autoFix && audit.findings.length > 0) {
|
|
2135
|
+
const remediation = await remediateFindings(audit.findings, config, { dryRun: options.dryRun });
|
|
2136
|
+
return { audit, remediation };
|
|
2137
|
+
}
|
|
2138
|
+
return { audit };
|
|
2139
|
+
}
|
|
2140
|
+
// Auto-detect provider and run audit
|
|
2141
|
+
export async function runDefaultSecurityAudit() {
|
|
2142
|
+
// Try to detect provider from environment
|
|
2143
|
+
let provider = 'custom';
|
|
2144
|
+
let projectId;
|
|
2145
|
+
let accountId;
|
|
2146
|
+
let subscriptionId;
|
|
2147
|
+
// Check for GCP
|
|
2148
|
+
try {
|
|
2149
|
+
const { stdout } = await execAsync('gcloud config get-value project 2>/dev/null');
|
|
2150
|
+
if (stdout.trim()) {
|
|
2151
|
+
provider = 'gcp';
|
|
2152
|
+
projectId = stdout.trim();
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
catch { /* not GCP */ }
|
|
2156
|
+
// Check for AWS
|
|
2157
|
+
if (provider === 'custom') {
|
|
2158
|
+
try {
|
|
2159
|
+
const { stdout } = await execAsync('aws sts get-caller-identity --output json 2>/dev/null');
|
|
2160
|
+
const data = JSON.parse(stdout);
|
|
2161
|
+
if (data.Account) {
|
|
2162
|
+
provider = 'aws';
|
|
2163
|
+
accountId = data.Account;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
catch { /* not AWS */ }
|
|
2167
|
+
}
|
|
2168
|
+
// Check for Azure
|
|
2169
|
+
if (provider === 'custom') {
|
|
2170
|
+
try {
|
|
2171
|
+
const { stdout } = await execAsync('az account show --output json 2>/dev/null');
|
|
2172
|
+
const data = JSON.parse(stdout);
|
|
2173
|
+
if (data.id) {
|
|
2174
|
+
provider = 'azure';
|
|
2175
|
+
subscriptionId = data.id;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
catch { /* not Azure */ }
|
|
2179
|
+
}
|
|
2180
|
+
console.log(`Auto-detected provider: ${provider.toUpperCase()}`);
|
|
2181
|
+
return runUniversalSecurityAudit({
|
|
2182
|
+
provider,
|
|
2183
|
+
projectId,
|
|
2184
|
+
accountId,
|
|
2185
|
+
subscriptionId,
|
|
2186
|
+
liveTesting: true,
|
|
2187
|
+
includeZeroDay: true,
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
//# sourceMappingURL=universalSecurityAudit.js.map
|