Back to skill

Security audit

Keplerjai Dingtalk Attendance

Security checks for vulnerabilities and agentic risk

Overview

This DingTalk attendance skill mostly matches its stated purpose, but it handles sensitive employee data with unsafe command execution and dependency-install behavior that needs review before use.

Install only after review by someone authorized to handle employee attendance data. Patch the Excel export to use argument-based process execution, remove automatic pip installs, pin dependencies, restrict output directories and file permissions, protect the .env file, and avoid running scheduled jobs as a privileged account.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:326
Finding
Shell Command Injection Through Configurable Output Directory## Vulnerability Details **File Location**: `index.js:39-47`, `index.js:278-287`, and `index.js:326-345` **Vulnerability Type**: OS command injection through shell-based process execution **Risk Level**: High ### Vulnerable Code ```javascript const config = { appKey: process.env.DINGTALK_APP_KEY || fileConfig.appKey, appSecret: process.env.DINGTALK_APP_SECRET || fileConfig.appSecret, agentId: process.env.DINGTALK_AGENT_ID || fileConfig.agentId, appId: process.env.DINGTALK_APP_ID || fileConfig.appId, outputDir: process.env.OUTPUT_DIR || fileConfig.outputDir || './data/attendance', outputFormat: process.env.OUTPUT_FORMAT || fileConfig.outputFormat || 'json', notifyChannel: process.env.NOTIFY_CHANNEL || fileConfig.notifyChannel || 'webchat', userFetchConcurrency: process.env.USER_FETCH_CONCURRENCY || fileConfig.userFetchConcurrency || 4, attendanceFetchConcurrency: process.env.ATTENDANCE_FETCH_CONCURRENCY || fileConfig.attendanceFetchConcurrency || 8 }; ``` ```javascript function exportData(data, filename) { const outputDir = path.resolve(__dirname, config.outputDir || './data/attendance'); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } const filepath = path.join(outputDir, filename); fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf-8'); console.log(`📁 Data saved to: ${filepath}`); return filepath; } ``` ```javascript function exportToExcel(jsonFile) { return new Promise((resolve, reject) => { const pythonScript = path.join(__dirname, 'export_excel.py'); const pythonCmd = jsonFile ? `python "${pythonScript}" "${jsonFile}"` : `python "${pythonScript}"`; console.log(' Executing: ', pythonCmd); exec(pythonCmd, { cwd: __dirname }, (error, stdout, stderr) => { if (error) { console.error(' Excel export failed:', error.message); reject(error); ...[truncated 2726 chars]
Remediation
## Remediation Suggestions Replace shell-string execution with an argument-based API that does not invoke a shell: ```javascript const { execFile } = require('child_process'); execFile( 'python', [pythonScript, jsonFile], { cwd: __dirname, shell: false }, callback ); ``` Additional hardening should include: 1. Resolve `OUTPUT_DIR` against a fixed, administrator-approved base directory. 2. Reject paths that escape the approved directory after canonicalization. 3. Do not accept arbitrary output paths from untrusted environment or configuration sources. 4. Avoid logging full commands or sensitive paths unnecessarily. 5. Run the Skill under a dedicated, unprivileged operating-system account. 6. Add tests using paths containing quotes, spaces, semicolons, command substitutions, and platform-specific shell metacharacters.

T08 · Insecure Dependencies

Warning
Location
export_excel.py:25
Finding
Automatic Runtime Installation of an Unpinned Python Dependency## Vulnerability Details **File Location**: `export_excel.py:25-31` and `requirements.txt:1` **Vulnerability Type**: Unsafe runtime dependency retrieval and non-reproducible dependency pinning **Risk Level**: Medium ### Vulnerable Code ```python try: from openpyxl import load_workbook except ImportError: print("Installing required dependency openpyxl...") os.system('pip install openpyxl -q') from openpyxl import load_workbook ``` The corresponding dependency specification is: ```text openpyxl>=3.1.0 ``` ### Technical Analysis If `openpyxl` is unavailable, normal report-generation execution invokes `pip install openpyxl -q` through the operating-system shell. This performs network retrieval and installation at runtime rather than failing safely and requiring an explicit, controlled setup step. The installation command does not specify an exact version, package hash, trusted index, isolated environment, or deployment lock. The requirement file also permits any version at or above 3.1.0. Consequently, the effective code installed and imported can change after the Skill has been reviewed. The package name itself is legitimate and no malicious dependency was identified in the repository. The risk arises from mutable runtime retrieval, potentially untrusted pip index configuration, and immediate import of the downloaded package. ### Attack Path 1. The Skill runs in an environment where `openpyxl` is not installed. 2. An attacker controls or compromises the configured pip index, package mirror, DNS/network path, or package-resolution configuration. 3. The exporter invokes `pip install openpyxl -q` automatically. 4. Pip retrieves and installs the dependency selected by the active configuration. 5. The exporter immediately imports the installed package. 6. Malicious package initialization code executes with the privileges of the Skill process. A less severe failure mode is an upstream inco ...[truncated 615 chars]
Remediation
## Remediation Suggestions 1. Remove automatic package installation from `export_excel.py`. 2. If `openpyxl` is missing, terminate with a clear error directing the operator to the documented setup process. 3. Pin an explicitly reviewed version instead of using a lower-bound-only constraint. 4. Use hash verification, such as a requirements file generated for `pip install --require-hashes`. 5. Install dependencies in a dedicated virtual environment during deployment. 6. Use an explicitly trusted package index and prevent untrusted pip configuration from silently changing the source. 7. Run dependency installation separately from report processing and without access to production credentials or attendance data.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:278
Finding
Sensitive Attendance Records Written Without Explicit Restrictive Permissions## Vulnerability Details **File Location**: `index.js:278-287` and `index.js:450-464` **Vulnerability Type**: Insecure local storage of sensitive employee information **Risk Level**: Medium ### Vulnerable Code ```javascript function exportData(data, filename) { const outputDir = path.resolve(__dirname, config.outputDir || './data/attendance'); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } const filepath = path.join(outputDir, filename); fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf-8'); console.log(`📁 Data saved to: ${filepath}`); return filepath; } ``` The written object contains employee identities and detailed attendance information: ```javascript const outputData = { mode: mode, startDate: startDate, endDate: endDate, exportTime: moment().format('YYYY-MM-DD HH:mm:ss'), summary: { totalDepartments: departments.length, totalUsers: users.length, usersWithAttendance: usersWithAttendance, totalRecords: totalRecords, totalDays: dateRange.length }, users: users, attendanceReports: reports }; const jsonFile = exportData(outputData, `${exportNameBase}.json`); ``` ### Technical Analysis The Skill intentionally stores HR data locally, which is consistent with its declared functionality. However, it creates the output directory and file without explicit restrictive permission modes. Node.js file creation normally begins with a permissive base mode that is reduced by the process umask. On systems with a permissive or incorrectly configured umask, the resulting JSON file may be readable by other local users or processes. The same concern applies to the output directory, which is created without an explicit mode. The data includes employee names, user identifiers, attendance results, approval or leave details, date ranges, and aggregate organizational statistics. These records wa ...[truncated 1229 chars]
Remediation
## Remediation Suggestions Create the output directory and files with explicit owner-only permissions: ```javascript if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true, mode: 0o700 }); } fs.writeFileSync( filepath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600, flag: 'w' } ); fs.chmodSync(filepath, 0o600); ``` Also apply the following controls: 1. Verify and, where appropriate, correct permissions on pre-existing output directories and files. 2. Restrict the output path to an administrator-approved location. 3. Run the Skill under a dedicated account with minimal filesystem access. 4. Define retention and secure-deletion policies for attendance exports. 5. Consider encryption at rest where reports are retained or copied to shared storage. 6. Avoid placing generated reports in world-readable shared directories. 7. Apply equivalent permission controls to generated Excel files.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (38)

Credential Access

High
Category
Privilege Escalation
Content
Windows PowerShell 可使用:

```powershell
Copy-Item .env.example .env
```

编辑 `.env`,填入你的钉钉应用信息:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Windows PowerShell 可使用:

```powershell
Copy-Item .env.example .env
```

编辑 `.env`,填入你的钉钉应用信息:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Windows PowerShell 可使用:

```powershell
Copy-Item .env.example .env
```

编辑 `.env`,填入你的钉钉应用信息:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Windows PowerShell 可使用:

```powershell
Copy-Item .env.example .env
```

编辑 `.env`,填入你的钉钉应用信息:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Windows PowerShell 可使用:

```powershell
Copy-Item .env.example .env
```

编辑 `.env`,填入你的钉钉应用信息:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
cd keplerjai-dingtalk-attendance
cp .env.example .env
```

### ✅ 步骤 3: 编辑配置
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
cd keplerjai-dingtalk-attendance
cp .env.example .env
```

### ✅ 步骤 3: 编辑配置
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The finding indicates the advertised network-fetch/save/push workflow is not what actually occurs, and that the real behavior centers on local aggregation and console reporting. Such divergence is risky because security reviewers and users may approve a skill based on a false operational model, while hidden analysis or transformation logic handles potentially sensitive attendance records in unreviewed ways.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The finding indicates the advertised network-fetch/save/push workflow is not what actually occurs, and that the real behavior centers on local aggregation and console reporting. Such divergence is risky because security reviewers and users may approve a skill based on a false operational model, while hidden analysis or transformation logic handles potentially sensitive attendance records in unreviewed ways.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The finding indicates the advertised network-fetch/save/push workflow is not what actually occurs, and that the real behavior centers on local aggregation and console reporting. Such divergence is risky because security reviewers and users may approve a skill based on a false operational model, while hidden analysis or transformation logic handles potentially sensitive attendance records in unreviewed ways.

Ae1

High
Category
analysis-evasion
Content
- 确认 `.env` 文件在本技能根目录,与 `index.js` 同级。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
from openpyxl import load_workbook
except ImportError:
    print("正在安装必要依赖 openpyxl...")
    os.system('pip install openpyxl -q')
    from openpyxl import load_workbook
Confidence
97% confidence
Finding
The script invokes a shell command at runtime to install a dependency with os.system('pip install openpyxl -q'). Executing package installation from within the program expands the attack surface to the local shell, package index, and environment configuration, and can result in unintended code execution or environment modification if pip resolution is tampered with or if the script runs with elevated privileges.

Credential Access

High
Category
Privilege Escalation
Content
const dotenv = require('dotenv');

// 加载 .env(优先)
dotenv.config({ path: path.join(__dirname, '.env') });

function loadJsonConfig(configPath) {
  if (!fs.existsSync(configPath)) {
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Known Vulnerable Dependency: axios==1.15.0 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2026-42044 (Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `pars) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
The lockfile pins axios to 1.15.0, and the supplied advisory set indicates multiple known high-severity issues affecting that version. In this skill’s context, axios is likely used to fetch DingTalk attendance data and may handle authentication tokens, so request/response tampering or credential theft would be particularly dangerous if the vulnerable code paths are reached.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
88% confidence
Finding
The lockfile includes form-data 4.0.5, which the finding reports as affected by a CRLF injection issue in multipart field names and filenames. This becomes more relevant if the skill constructs multipart requests from untrusted input, because malformed headers could alter downstream request structure or enable request-smuggling-style effects against integrated services.

Known Vulnerable Dependency: axios==1.15.0 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2026-42044 (Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `pars) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
The package depends on axios 1.15.0, which is flagged with multiple known advisories, including prototype-pollution-related response tampering and credential theft scenarios. Because this skill interacts with the DingTalk platform and likely handles access tokens and employee attendance data, exploitation could compromise confidentiality or integrity of API traffic and harvested records.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The guide instructs operators to request directory and attendance permissions and retrieve employee IDs, names, and attendance records, but it provides no privacy, minimization, or access-control guidance for handling this sensitive HR data. In the context of an attendance-export skill, this omission increases the risk of over-collection, unauthorized disclosure, and non-compliant use of personal employee information.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README instructs users to export detailed attendance records to local JSON and Excel files, which can contain sensitive employee personal data such as names, timestamps, leave records, and locations, but it does not warn about privacy handling, access control, retention, or secure storage. In an HR/attendance context this increases the risk of unauthorized disclosure or mishandling of regulated personnel data.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The instructions explicitly encourage exporting employee attendance records to a local directory and optionally automating daily collection, but they provide no warning that this is sensitive personnel data or guidance on secure storage, access control, retention, or encryption. In the context of employee attendance data, this omission increases the risk of privacy breaches, unauthorized internal access, and noncompliance with organizational or legal data-handling requirements.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill instructs the agent to read local .env secrets, access files, and run shell commands, but it does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, this creates an authorization gap where sensitive operations may be performed without transparent user review, increasing the chance of unintended secret access or filesystem actions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document explicitly instructs users to export and locally store employee attendance-related data, including employee names and user IDs, but provides no warning about the sensitivity of personnel/attendance data, retention limits, access controls, or compliance obligations. In the context of an attendance integration, this increases the risk of privacy violations, unauthorized internal disclosure, and insecure handling of employee records once attendance permissions are enabled.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The guide explicitly documents exporting employee attendance data, leave records, punch times, and locations to local JSON and Excel files, but it provides no warning about handling sensitive personal data or limiting access to the generated files. In an HR/attendance context, these exports contain identifiable workforce activity data that could be exposed through insecure storage, sharing, backups, or endpoint compromise.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Automatically installing dependencies during execution is not necessary for an attendance-export skill and violates the principle of least surprise. It causes side effects beyond data export, including network access and package execution, which may be abused in compromised environments or break controlled production setups.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code installs a package automatically without prior confirmation from the user or administrator. This creates an unexpected privileged action path, especially risky on managed hosts or CI/automation runners where the script may modify the environment or execute unreviewed package installation logic.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The manifest describes fetching DingTalk attendance data and saving it locally or pushing it to a channel. While exporting data is in scope, spawning a subprocess via child_process.exec introduces command execution capability beyond the stated purpose and is not necessary to justify from the manifest alone.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:335

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.js:39