Back to skill

Security audit

Azure DevOps Reports

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Azure DevOps reporting tool, but it can access sensitive work data and has under-scoped invocation and report-generation risks users should review before installing.

Install only if you are comfortable giving the skill a least-privilege Azure DevOps PAT and storing generated reports locally. Use explicit Azure DevOps prompts, review generated files before sharing, avoid opening CSV/XLSX reports from untrusted work-item data with formula execution enabled, and prefer pinning the Python dependency plus confining Excel input/output paths before routine use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/utils.js:19
Finding

CSV Formula Injection Through Azure DevOps Work Item Fields

Content
View full analysis
{ const text = value == null ? '' : String(value); if (/[",\n]/.test(text)) return '"' + text.replace(/"/g, '""') + '"'; return text; }; ``` The affected data originates from Azure DevOps fields normalized without spreadsheet-specific sanitization in `scripts/workitems.js:26-45`: ```javascript function normalizeWorkItem(item) { const fields = item.fields || {}; const assigned = assignedToParts(fields['System.AssignedTo']); return { id: item.id, title: fields['System.Title'] || '', state: fields['System.State'] || '', type: fields['System.WorkItemType'] || '', assignedTo: assigned.assignedTo, assignedToEmail: assigned.assignedToEmail, project: fields['System.TeamProject'] || '', iterationPath: fields['System.IterationPath'] || '', areaPath: fields['System.AreaPath'] || '', priority: fields['Microsoft.VSTS.Common.Priority'] ?? '', createdDate: fields['System.CreatedDate'] || '', changedDate: fields['System.ChangedDate'] || '', closedDate: fields['Microsoft.VSTS.Common.ClosedDate'] || '', originalEstimate: fields['Microsoft.VSTS.Scheduling.OriginalEstimate'] ?? '', remainingWork: fields['Microsoft.VSTS.Scheduling.RemainingWork'] ?? '', storyPoints: fields['Microsoft.VSTS.Scheduling.StoryPoints'] ?? '', }; } ``` ### Technical Analysis The CSV encoder escapes commas, quotation marks, and newlines, but it does not neutralize strings beginning with spreadsheet formula indicators such as `=`, `+`, `-`, or `@`. Tab and carriage-return prefixes can also be used to bypass simplistic filtering in some spreadsheet applications. Fields such as work-item titles, assignee names, p ...[truncated 1331 chars]
Remediation
View remediation
{ const text = neutralizeSpreadsheetValue(value); return /[",\n]/.test(text) ? '"' + text.replace(/"/g, '""') + '"' : text; }; ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/build_excel_report.py:44
Finding

Excel Formula Injection Through Untrusted Report Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/build_excel_report.py:132
Finding

Workbook Generator Bypasses the Declared Output-Directory Restriction

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned XlsxWriter Dependency Creates Supply-Chain and Reproducibility Risk

Content
View full analysis
Remediation
View remediation
`. - Generate and verify cryptographic hashes using a locked requirements file and install with `pip --require-hashes`. - Perform dependency updates through a controlled review process. - Use a dedicated virtual environment rather than installing into a shared Python environment. - Retain the exact lock file used during security review so subsequent installations are reproducible. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code is narrowly focused on the Azure DevOps team iterations API (teamsettings/iterations) and returns iteration metadata for a specified project/team. The declared description emphasizes project/team/member lists, saved queries, work items, WIQL reporting, and Excel/CSV/chart exports. Iteration/sprint retrieval is adjacent to work-item reporting, but it is not explicitly described, and the primary behavior of this chunk is materially narrower and different from the stated capability set. This is best treated as a description-behavior mismatch for this specific code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The code is focused narrowly on work item retrieval and reporting through WIQL and saved query IDs. It can run ad hoc WIQL, execute a saved query by ID, and produce a predefined 'closed last week' report, which aligns with part of the declared work-item/WIQL reporting functionality. However, the declared description substantially overstates the implemented behavior: this code does not read project lists, team lists, team members, or saved query listings, and it does not export spreadsheet-ready Excel/CSV outputs or generate summaries/charts. Because the declared purpose presents a broader skill whose capabilities are not represented by this supplied code chunk, this chunk is a partial implementation and therefore a mismatch against the full declared description.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

md
- `scripts/teams.js` — list teams in a project and team members

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 108)May include surrounding context.

md
- `scripts/teams.js` — list teams in a project and team members

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 114)May include surrounding context.

md
- `scripts/teams.js` — list teams in a project and team members

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 85)May include surrounding context.

md
- `scripts/iterations.js` — list team iterations / current sprint

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 120)May include surrounding context.

md
- `scripts/iterations.js` — list team iterations / current sprint

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 126)May include surrounding context.

md
- `scripts/iterations.js` — list team iterations / current sprint

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 86)May include surrounding context.

md
- `scripts/queries.js` — list saved queries and inspect a query definition

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 132)May include surrounding context.

md
- `scripts/queries.js` — list saved queries and inspect a query definition

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 138)May include surrounding context.

md
- `scripts/queries.js` — list saved queries and inspect a query definition

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 88)May include surrounding context.

md
- `scripts/export-report.js` — export JSON/CSV data bundles

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 174)May include surrounding context.

md
- `scripts/export-report.js` — export JSON/CSV data bundles

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 180)May include surrounding context.

md
- `scripts/export-report.js` — export JSON/CSV data bundles

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 190)May include surrounding context.

md
- `scripts/export-report.js` — export JSON/CSV data bundles

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config.js (reported line 5)May include surrounding context.

js
const path = require('path');

const SKILL_DIR = path.resolve(__dirname, '..');
const ENV_PATH = path.join(SKILL_DIR, '.env');
const DEFAULT_OUTPUT_DIR = path.join(SKILL_DIR, 'output');

function parseEnvFile(filePath) {

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language examples are broad enough to be triggered by ordinary conversation, which can cause the agent to invoke this Azure DevOps skill unexpectedly. In a read-focused reporting skill, unintended invocation can still expose project metadata, team membership, sprint details, or work-item data and can also cause unplanned local report generation containing sensitive business information.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The broad plain-English trigger phrases can cause the skill to activate for loosely related user requests, which increases the chance of unintended access to Azure DevOps data and unnecessary use of the PAT-backed workflow. In a skill that reads potentially sensitive organizational project, team, and work-item data, overbroad invocation logic expands the effective attack surface and can lead to data exposure through mistaken routing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README mentions exporting JSON and generating Excel reports but does not prominently warn that these outputs contain Azure DevOps data written to local disk. Users may assume the skill is only performing transient read operations, when in fact it persists potentially sensitive project and work-item information in files that could be retained, indexed, shared, or accessed by other local processes.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified without a version pin, which makes builds non-reproducible and allows future installs to pull in unexpected upstream changes. If a compromised or breaking release of xlsxwriter is published, this skill could inherit vulnerable or malicious code during installation.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
xlsxwriter

Static analysis

No suspicious patterns detected.