other
- Location
SKILL.md:86- Finding
Mandatory External Delivery May Expose Sensitive Financial Reports
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its crypto tax-reporting purpose, but it requires external delivery of sensitive tax reports and CSVs without clear consent or privacy controls.
Review this skill before installing if you will use it with real financial records. Confirm where store_deliverable stores files, whether URLs are public or permanent, and require explicit approval before uploading reports or CSVs. Treat generated CSVs as untrusted when opening them in spreadsheet software, and verify tax calculations with a professional before relying on them.
SKILL.md:86Mandatory External Delivery May Expose Sensitive Financial Reports
src/index.ts:85Incorrect US Tax-Year Calculation Collects and Processes Two Calendar Years
src/index.ts:1747Report Generator Silently Falls Back to FIFO for Invalid Cost-Basis Methods
src/index.ts:1762Unescaped Report Fields Permit Spreadsheet Formula Injection
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- **Saltant API** — historical balance snapshots (liquid, staked, lending, yield farm)
- **Metal X API** — DEX trade history in CSV format (only filled trades)
- **Hyperion API** — raw on-chain transfer/action history
- **CoinGecko API** — historical and current crypto prices (set `COINGECKO_API_KEY` in .env for full historical access)
### Transfer Categories
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- **Saltant API** — historical balance snapshots (liquid, staked, lending, yield farm)
- **Metal X API** — DEX trade history in CSV format (only filled trades)
- **Hyperion API** — raw on-chain transfer/action history
- **CoinGecko API** — historical and current crypto prices (set `COINGECKO_API_KEY` in .env for full historical access)
### Transfer Categories
The skill declares network and environment-related capabilities implicitly but does not constrain them with an explicit tool scope or allowed-tools list. That increases the chance of unintended tool access or capability creep, which is especially risky in a skill that handles financial data and later instructs external uploads.
The documentation states that all tools are read-only, but the workflow later requires uploading files and calling a delivery action. This mismatch can mislead operators and reviewers into underestimating the skill's ability to transmit data externally, creating consent and security risks around sensitive tax information.
The claim that all tools are read-only is directly contradicted by later mandatory upload and delivery instructions. Contradictory security-relevant documentation is dangerous because users may trust the earlier statement and unknowingly authorize exfiltration of financial records.
The skill instructs uploading tax reports and CSV exports to external storage/delivery endpoints without a user-facing warning about sending sensitive financial information. Tax reports can contain wallet history, balances, gains, and income events, so transmitting them without clear disclosure or consent creates a significant privacy and data-handling risk.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
function getCoinGeckoConfig() {
const apiKey = process.env.COINGECKO_API_KEY || '';
if (!apiKey) {
return { baseUrl: 'https://api.coingecko.com/api/v3', headers: {}, hasKey: false };
}
if (apiKey.startsWith('CG-')) {
// Pro API key
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
function getCoinGeckoConfig() {
const apiKey = process.env.COINGECKO_API_KEY || '';
if (!apiKey) {
return { baseUrl: 'https://api.coingecko.com/api/v3', headers: {}, hasKey: false };
}
if (apiKey.startsWith('CG-')) {
// Pro API key
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
function getCoinGeckoConfig() {
const apiKey = process.env.COINGECKO_API_KEY || '';
if (!apiKey) {
return { baseUrl: 'https://api.coingecko.com/api/v3', headers: {}, hasKey: false };
}
if (apiKey.startsWith('CG-')) {
// Pro API key
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
function getCoinGeckoConfig() {
const apiKey = process.env.COINGECKO_API_KEY || '';
if (!apiKey) {
return { baseUrl: 'https://api.coingecko.com/api/v3', headers: {}, hasKey: false };
}
if (apiKey.startsWith('CG-')) {
// Pro API key
The report-generation tool automatically transmits the supplied account identifier and associated activity lookups to multiple external services (Saltant, MetalX, and potentially CoinGecko-derived pricing paths) without any explicit consent, disclosure, or host allowlisting visible at the tool boundary. Even if the data is blockchain-related and partly public, bundling account-linked tax activity through third-party endpoints can expose sensitive financial profiling and may violate user expectations or privacy requirements.
The header comment explicitly says 'All tools are read-only (query APIs + calculate),' which contradicts the later use of fs.mkdirSync and fs.writeFileSync to persist rate data. This is an active contradiction in the skill's own documentation about side effects.
The module doc comment states 'All tools are read-only' and the manifest describes tax reporting, but the implementation adds filesystem-based persistence by loading and saving a JSON cache. This goes beyond purely querying APIs and calculating results because it modifies local state on disk across runs.
Line L1789 formats all currency values with toLocaleString('en-NZ', ...), which forces a specific locale even when the user selected US via the region parameter. This is a natural-language locale policy issue because the skill imposes a locale without user opt-in or justification.
The formatter uses toLocaleString('en-NZ', ...) for currency presentation regardless of the selected region or any user locale preference. This forces a specific language/locale choice in natural-language output and can conflict with organizational policy requiring user choice or justified locale constraints.
Detected: suspicious.env_credential_access