T09 · Insecure Skill Coding Practices
- Location
src/dialogue.ts:63- Finding
Unbounded In-Memory Session and Answer Storage Enables Denial of Service
- Content
View full analysis
{ // Input validation only checks whether a decision was provided if (!userInput || userInput.trim().length === 0) { return '❌ Please provide a decision description'; } // The complete input is stored before detector length validation const context = this.dialogue.createSession(sessionId, userInput); ``` Session creation inserts every session directly into an unbounded process-wide map: ```typescript // src/dialogue.ts:63-80 createSession(sessionId: string, userInput: string): DialogueContext { const context: DialogueContext = { sessionId, state: DialogueState.START, userInput, selectedModels: [], currentModelIndex: 0, currentQuestionIndex: 0, answers: {}, createdAt: Date.now(), updatedAt: Date.now() }; this.contexts.set(sessionId, context); return context; } ``` Answers are accepted and retained without type, size, or aggregate limits: ```typescript // src/index.ts:164-184 async handleAnswer(sessionId: string, answer: string): Promise { const context = this.dialogue.getContext(sessionId); if (!context) { return '❌ Session does not exist; start an analysis first'; } const models = this.recommender.recommend(context.selectedModels); const current = this.dialogue.getCurrentQuestion(sessionId, models); if (!current) { return '❌ Unable to obtain the current question'; } this.dialogue.recordAnswer( sessionId, current.model.id, context.currentQuestionI ...[truncated 3984 chars]- Remediation
View remediation
