T09 · Insecure Skill Coding Practices
- Location
index.js:85- Finding
Configured API credentials are exposed in policy query results
- Content
View full analysis
Vulnerability Details
File Location:
index.js:85-86,index.js:95-105, andindex.js:114-123; the vulnerable configuration pattern is documented inREADME.md:53-55andREADME.md:85-90.
Vulnerability Type: Sensitive credential exposure through returned application data
Risk Level: MediumVulnerable Code
README.md:53-55instructs users to store API keys directly indataSources:javascript dataSources: { investment: process.env.INVESTMENT_API_KEY || '[replace with your API key]', trade: process.env.TRADE_API_KEY || '[replace with your API key]' }index.js:85-86retrieves that configured value:javascript const dataSource = this.config.dataSources[category]; const policies = await this.fetchFromDataSource(dataSource, category, options);index.js:95-105places the value in each policy record:javascript async fetchFromDataSource(dataSource, category, options) { const policies = [{ title: this.config.language === 'zh-CN' ? '${name} investment policy' : '${name} Investment Policy', description: this.config.language === 'zh-CN' ? '${name} latest investment policies and regulations' : 'Latest investment policies and regulations in ${name}', effectiveDate: '2026-01-01', authority: this.config.language === 'zh-CN' ? '${name} government' : '${name} Government', dataSource,index.js:114-123also places the value in the top-level response:javascript return { country: this.t('country'), category: this.t('categories', category), totalPolicies: policies.length, policies: policies, lastUpdated: new Date().toISOString(), dataSource, language: this.config.language };Technical Analysis
The documentation defines
dataSourcesas a place to supply environment-derived API keys. The implementation does not keep those credentials confined to an authentication boundary. Inst ...[truncated 2087 chars]- Remediation
View remediation
Remediation Suggestions
-
Separate source identity, endpoint information, and authentication material:
javascript dataSources: { investment: { id: 'investment-policy-api', url: process.env.INVESTMENT_API_URL, apiKey: process.env.INVESTMENT_API_KEY } } -
Use the credential only inside the network authentication layer. Never add
apiKey, authorization headers, tokens, or raw configuration objects to returned policy records. -
Return only a non-sensitive source identifier when provenance is needed:
javascript return { country: this.t('country'), category: this.t('categories', category), totalPolicies: policies.length, policies, lastUpdated: new Date().toISOString(), sourceId: source.id, language: this.config.language }; -
Ensure cached objects contain policy data only and do not contain credentials or authorization headers.
-
Add automated tests that configure a unique sentinel secret, execute every public method, serialize the results, and assert that the sentinel does not appear.
-
Apply response redaction to sensitive field names such as
apiKey,token,secret, andauthorizationas defense in depth. -
Update the documentation to distinguish API endpoints from API keys and explain that credentials must never be returned, logged, or embedded in policy data.
-
Rotate any real credentials that may already have been exposed through returned results, application logs, telemetry, or downstream agent transcripts.
-
