Back to skill

Security audit

EWS Skill

Security checks for vulnerabilities and agentic risk

Overview

This calendar skill does what it says, but it handles Exchange credentials and sensitive meeting data in ways that need review before installation.

Install only if you trust the configured Exchange URL and can protect the local machine. Prefer the keyring setup with interactive password entry, avoid .env and --password usage, use HTTPS Exchange endpoints only, and do not write debug XML or output files into shared directories.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
ews-calendar.sh:116
Finding
Exchange credentials can be transmitted to an unvalidated or plaintext endpoint<![CDATA[ ## Vulnerability Details **File Location**: `ews-calendar.sh`, lines 116-122 **Vulnerability Type**: Unvalidated credential destination and missing transport security enforcement **Risk Level**: High ### Vulnerable Code ```bash response=$(curl -s -w "\n%{http_code}" \ -X POST \ -H "Content-Type: text/xml; charset=utf-8" \ --ntlm \ -u "${EWS_USER}:${EWS_PASS}" \ --data "$soap_body" \ "$EWS_URL" 2>&1) ``` ### Technical Analysis The script retrieves the Exchange password from the operating-system keyring and supplies it to `curl` for NTLM authentication. Authentication to an Exchange server is required for the declared calendar functionality, but the destination is controlled entirely through `EWS_URL`. The script does not validate that the URL: - Uses HTTPS. - Refers to an approved Exchange host. - Uses an expected port. - Is not an attacker-controlled endpoint. Consequently, a configuration error or unauthorized modification of the environment or OpenClaw configuration can cause the Skill to initiate NTLM authentication against an unintended server. NTLM does not ordinarily place the literal password directly in the HTTP request, but authentication exchanges over an untrusted connection can still enable credential capture, offline attacks, or relay attacks. A plaintext HTTP endpoint also lacks confidentiality and integrity protection for SOAP requests and responses. The network communication itself is necessary for the Skill, and no separate exfiltration endpoint was identified. The security issue is that the sensitive authentication flow is not restricted to a trusted, encrypted destination. ### Attack Path 1. An attacker who can modify the Skill environment or OpenClaw configuration changes `EWS_URL` to an attacker-controlled HTTP or HTTPS endpoint. 2. The user invokes `ews-calendar-secure.sh`. 3. The wrapper retrieves the user's Exchange password from the OS keyring and exports it as `EWS_PASS`. 4. `ews-calendar.sh` ...[truncated 897 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse and validate `EWS_URL` before retrieving or using credentials. 2. Reject every scheme except `https://` by default. 3. Support an administrator-configured allowlist of approved Exchange hostnames and ports. 4. Reject URLs containing unexpected user-info components or malformed hostnames. 5. Do not provide silent fallback to HTTP. If legacy HTTP support is unavoidable, require an explicit opt-in setting and display a prominent warning. 6. Retain normal TLS certificate validation and do not introduce `curl -k` or `--insecure`. 7. Where supported, replace NTLM/password authentication with modern token-based authentication. 8. Document that anyone able to modify `EWS_URL` can redirect the authentication attempt and must therefore be treated as having access to sensitive configuration. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
ews-calendar.sh:100
Finding
Sensitive calendar responses are written without owner-only permission enforcement<![CDATA[ ## Vulnerability Details **File Location**: `ews-calendar.sh`, lines 100-105 and 390-391 **Vulnerability Type**: Insecure storage of sensitive output **Risk Level**: Medium ### Vulnerable Code ```bash DEBUG_XML="" save_debug_xml() { if [[ -n "$DEBUG_XML" ]]; then echo "$1" > "$DEBUG_XML" log "Saved raw XML to $DEBUG_XML" fi } ``` ```bash if [[ -n "$OUTPUT_FILE" ]]; then echo "$json_output" > "$OUTPUT_FILE" log "Output written to $OUTPUT_FILE" else echo "$json_output" fi ``` ### Technical Analysis The `--debug-xml` option writes the raw EWS response to a caller-selected path, while `--output` writes the generated calendar JSON to a caller-selected path. The script does not set a restrictive `umask`, securely create the destination, or explicitly set owner-only permissions. The resulting permissions therefore depend on the invoking process's umask and the state of an existing destination file. On a multi-user system with a permissive umask, newly created output can be readable by other local users. Existing files may retain broader permissions. The saved data can contain: - Meeting subjects and schedules. - Organizer email addresses. - Meeting locations. - Full event body text. - Conference and document links. - Raw EWS item identifiers and response metadata. The debug XML is especially sensitive because it preserves the unprocessed server response. ### Attack Path 1. The Skill runs on a shared system under a permissive umask, or the user selects a shared directory such as `/tmp`. 2. The user invokes the Skill with `--output FILE` or `--debug-xml FILE`. 3. The shell creates or truncates the selected file without enforcing owner-only permissions. 4. Calendar content is written to the file. 5. Another local user or process reads the file through its group/world-readable permissions. A related local file risk exists when writing to attacker-influenced locations because ordinary shell redirection follows symbol ...[truncated 777 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` near the beginning of the script before creating any files. 2. Create output files securely and explicitly set permissions to `0600`. 3. Refuse to overwrite symbolic links and validate that the destination is a regular file. 4. Prefer atomic creation with a securely created temporary file in the destination directory, followed by a controlled rename. 5. Warn users that `--debug-xml` stores raw, sensitive mailbox content. 6. Require explicit confirmation before overwriting an existing debug or output file. 7. Recommend storage only in private user-owned directories and provide deletion guidance. 8. Consider making debug XML capture unavailable unless a dedicated debug setting is enabled. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
ews-calendar-setup.sh:97
Finding
Password command-line option exposes Exchange credentials through process and shell metadata<![CDATA[ ## Vulnerability Details **File Location**: `ews-calendar-setup.sh`, lines 97-99 **Vulnerability Type**: Secret supplied through command-line arguments **Risk Level**: Medium ### Vulnerable Code The setup interface advertises the password argument: ```bash Options: -u, --user USER Domain\username (required) -p, --password PASS Password (will prompt if not provided) ``` The argument parser then stores the command-line value: ```bash -p|--password) PASSWORD="$2" shift 2 ;; ``` The help text also demonstrates plaintext command-line use: ```bash $(basename "$0") -u "DOMAIN\\jsmith" -p "mypassword" ``` ### Technical Analysis Although the password is ultimately stored in an OS-managed keyring, the optional `--password` interface permits it to be supplied directly in the process argument vector. Command-line secrets can be exposed through: - Shell history. - Process inspection tools while the setup command is running. - Process accounting and endpoint monitoring. - Audit logs. - Terminal session recording. - Automation logs and copied command transcripts. This bypasses much of the protection gained from using the keyring. The script already implements a hidden interactive prompt using `read -s`, so the command-line password option is unnecessary for normal operation and exceeds the minimum exposure required by the declared setup functionality. ### Attack Path 1. A user follows the documented example and runs the setup script with `--password`. 2. The plaintext password is included in the shell command and process argument vector. 3. The command is saved in shell history, captured by monitoring software, or observed by a local process-inspection mechanism. 4. An attacker with access to that record obtains the Exchange password. 5. The attacker authenticates directly to Exchange or any other service where the password has been reused. ### Impact Assessment This can compromise the user's Exchange credentials independently ...[truncated 401 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `-p` and `--password` command-line options. 2. Remove the plaintext password example from the help output and documentation. 3. Continue using `read -s` for interactive credential entry. 4. If non-interactive setup is required, accept the secret through a protected file descriptor or stdin with clear safeguards rather than through argv. 5. Ensure automation does not echo or log the supplied secret. 6. Clear the shell variable containing the password after the keyring operation where practical. 7. Advise users who previously used `--password` to remove affected shell-history entries and rotate the exposed password. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (65)

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- **curl** - HTTP requests
- **xmllint** - XML parsing (part of libxml2)
- **macOS**: Keychain Access (built-in)
- **Linux**: libsecret-tools + gnome-keyring

### Linux Setup
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% 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
# Debian/Ubuntu
sudo apt install libsecret-tools gnome-keyring

# Fedora
sudo dnf install libsecret gnome-keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Or create a `.env` file and source it:

```bash
source .env
./ews-calendar.sh --date today
```
Confidence
98% confidence
Finding
The `.env`-sourcing example directly supports local plaintext secret storage and shell ingestion of credentials. In practice, such files are often world-readable, accidentally committed, included in archives, or accessed by other local processes/users, making credential theft more likely in enterprise environments where EWS accounts may expose sensitive calendar data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims to extract calendar events, but it also documents retrieving full event bodies, extracting links, writing results to arbitrary files, saving raw XML, and loading credentials from a local .env file. This broadens the data-access and exfiltration surface beyond simple metadata retrieval and increases risk of exposing sensitive meeting content and credentials.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims to extract calendar events, but it also documents retrieving full event bodies, extracting links, writing results to arbitrary files, saving raw XML, and loading credentials from a local .env file. This broadens the data-access and exfiltration surface beyond simple metadata retrieval and increases risk of exposing sensitive meeting content and credentials.

Credential Access

High
Category
Privilege Escalation
Content
{baseDir}/
├── SKILL.md                 # This file
├── ews-calendar.sh          # Main script (reads from env or .env)
├── ews-calendar-secure.sh   # Wrapper that gets password from keyring
├── ews-calendar-setup.sh    # Store credentials in keyring
├── templates/
│   ├── find-items.xml       # SOAP template for finding calendar items
Confidence
84% confidence
Finding
The file list explicitly states that the main script reads from env or .env, which means the skill package supports a weaker credential path alongside the keyring wrapper. In this context, the issue is not credential access itself but the presence of an insecure secret-loading mechanism that can lead to plaintext storage or accidental exposure.

Credential Access

High
Category
Privilege Escalation
Content
2. Fill in your credentials
3. Run: `./ews-calendar.sh --date today`

**Warning:** This stores password in plaintext. Use keyring for production.
Confidence
89% confidence
Finding
The standalone section confirms that users may place credentials in a .env file and only then warns about plaintext storage. In context, this materially increases credential exposure risk because passwords may persist on disk, enter backups, or be accidentally shared.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="ews-calendar"

# Detect OS and get password from keyring
get_password() {
    local user="${EWS_USER:-}"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="ews-calendar"

# Detect OS and get password from keyring
get_password() {
    local user="${EWS_USER:-}"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="ews-calendar"

# Detect OS and get password from keyring
get_password() {
    local user="${EWS_USER:-}"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="ews-calendar"

# Detect OS and get password from keyring
get_password() {
    local user="${EWS_USER:-}"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="ews-calendar"

# Detect OS and get password from keyring
get_password() {
    local user="${EWS_USER:-}"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.