Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
SecurityTelemetry.test.tsโ€ข7.2 kB
/** * Tests for Security Telemetry * * Issue #1269: Enhanced telemetry for memory injection protection * @jest-environment node */ import { describe, it, expect, beforeEach } from '@jest/globals'; import { SecurityTelemetry } from '../../../../../src/security/telemetry/SecurityTelemetry.js'; describe('SecurityTelemetry', () => { beforeEach(() => { // Clear telemetry data before each test SecurityTelemetry.clearOldData(0); }); describe('Attack Recording', () => { it('should record blocked attack attempts', () => { SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'System prompt override', 'CRITICAL', 'content_validation' ); const metrics = SecurityTelemetry.getMetrics(); expect(metrics.totalBlockedAttempts).toBe(1); expect(metrics.criticalAttacksBlocked).toBe(1); }); it('should track multiple attack vectors', () => { // Record different types of attacks SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'System prompt override', 'CRITICAL', 'content_validation' ); SecurityTelemetry.recordBlockedAttack( 'UNICODE_ATTACK', 'Direction override detected', 'HIGH', 'unicode_validation' ); SecurityTelemetry.recordBlockedAttack( 'YAML_BOMB', 'Recursive reference detected', 'CRITICAL', 'yaml_validation' ); const metrics = SecurityTelemetry.getMetrics(); expect(metrics.totalBlockedAttempts).toBe(3); expect(metrics.uniqueAttackVectors).toBe(3); expect(metrics.criticalAttacksBlocked).toBe(2); expect(metrics.highSeverityBlocked).toBe(1); }); it('should aggregate repeated attack patterns', () => { // Same attack pattern multiple times for (let i = 0; i < 5; i++) { SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'System prompt override', 'CRITICAL', 'content_validation' ); } const metrics = SecurityTelemetry.getMetrics(); expect(metrics.totalBlockedAttempts).toBe(5); expect(metrics.topAttackVectors[0].count).toBe(5); expect(metrics.topAttackVectors[0].type).toBe('CONTENT_INJECTION'); }); }); describe('Metrics and Reporting', () => { it('should calculate hourly distribution', () => { // Record attacks at different times SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'Test pattern', 'HIGH', 'test' ); const metrics = SecurityTelemetry.getMetrics(); expect(metrics.attacksPerHour).toHaveLength(24); expect(metrics.attacksPerHour[23]).toBe(1); // Most recent hour }); it('should generate security report', () => { // Add some test data SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'System prompt override', 'CRITICAL', 'content_validation' ); SecurityTelemetry.recordBlockedAttack( 'UNICODE_ATTACK', 'Mixed script detected', 'MEDIUM', 'unicode_validation' ); const report = SecurityTelemetry.generateReport(); expect(report).toContain('Security Telemetry Report'); expect(report).toContain('Total Blocked Attacks (24h): 2'); expect(report).toContain('Critical: 1'); expect(report).toContain('Medium: 1'); }); it('should track top attack vectors', () => { // Create various attack patterns const attacks = [ { type: 'CONTENT_INJECTION', pattern: 'System override', count: 10 }, { type: 'UNICODE_ATTACK', pattern: 'Direction marks', count: 5 }, { type: 'YAML_BOMB', pattern: 'Recursive ref', count: 3 }, { type: 'DATA_EXFILTRATION', pattern: 'Export API keys', count: 8 } ]; for (const attack of attacks) { for (let i = 0; i < attack.count; i++) { SecurityTelemetry.recordBlockedAttack( attack.type, attack.pattern, 'HIGH', 'test' ); } } const metrics = SecurityTelemetry.getMetrics(); expect(metrics.topAttackVectors[0].count).toBe(10); expect(metrics.topAttackVectors[0].blockedPatterns).toContain('System override'); }); }); describe('Attack Pattern Analysis', () => { it('should retrieve patterns by attack type', () => { SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'System prompt override', 'CRITICAL', 'test' ); SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'Instruction override', 'CRITICAL', 'test' ); SecurityTelemetry.recordBlockedAttack( 'UNICODE_ATTACK', 'Direction marks', 'HIGH', 'test' ); const injectionPatterns = SecurityTelemetry.getAttackPatternsByType('CONTENT_INJECTION'); expect(injectionPatterns).toHaveLength(2); expect(injectionPatterns).toContain('System prompt override'); expect(injectionPatterns).toContain('Instruction override'); const unicodePatterns = SecurityTelemetry.getAttackPatternsByType('UNICODE_ATTACK'); expect(unicodePatterns).toHaveLength(1); expect(unicodePatterns).toContain('Direction marks'); }); }); describe('Timeline Analysis', () => { it('should generate attack timeline', () => { // Record attacks SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'Test', 'CRITICAL', 'test' ); SecurityTelemetry.recordBlockedAttack( 'UNICODE_ATTACK', 'Test', 'HIGH', 'test' ); const timeline = SecurityTelemetry.getAttackTimeline(1); expect(timeline).toHaveLength(1); // The timeline shows attacks in the most recent hour (0th element) // Both attacks were recorded in the same millisecond, so both are in current hour expect(timeline[0].count).toBe(2); expect(timeline[0].severity.CRITICAL).toBe(1); expect(timeline[0].severity.HIGH).toBe(1); }); }); describe('Data Management', () => { it('should export telemetry data', () => { SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'Test pattern', 'HIGH', 'test', { additional: 'metadata' } ); const exportData = SecurityTelemetry.exportData(); expect(exportData.history).toHaveLength(1); expect(exportData.vectors).toHaveLength(1); expect(exportData.metrics.totalBlockedAttempts).toBe(1); expect(exportData.history[0].metadata).toEqual({ additional: 'metadata' }); }); it('should clear old telemetry data', () => { // Record an attack SecurityTelemetry.recordBlockedAttack( 'CONTENT_INJECTION', 'Test', 'HIGH', 'test' ); // Clear all data (0 days to keep) SecurityTelemetry.clearOldData(0); const metrics = SecurityTelemetry.getMetrics(); expect(metrics.totalBlockedAttempts).toBe(0); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DollhouseMCP/DollhouseMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server