Back to skill

Security audit

Microsoft 365 Graph Openclaw

Security checks for vulnerabilities and agentic risk

Overview

This Microsoft 365/OpenClaw skill is coherent, but its broad persistent Microsoft 365 access, privileged setup scripts, background services, and credential-handling weaknesses require manual review before use.

Install only if you are comfortable granting persistent read/write access to mail, calendar, contacts, and OneDrive under the authenticated Microsoft account. Before running setup, review the sudo scripts, prefer a tenant-owned app registration, restrict token file permissions, avoid anonymous/edit share links unless intentional, rotate any tokens printed into logs, and run the webhook services on a host where systemd, journal, and process visibility are appropriately locked down.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/utils.py:13
Finding

OAuth access and refresh tokens are stored without restrictive filesystem permissions

Content
View full analysis
None: with AUTH_FILE.open("w", encoding="utf-8") as f: json.dump(data, f, indent=2) ``` ### Technical Analysis The authentication state contains Microsoft Graph access and refresh tokens. The code creates the state directory and authentication file using process-default permissions rather than explicitly enforcing owner-only access. Under a common `umask` of `022`, a newly created file can receive mode `0644`, making it readable by other local users. The containing directory may similarly be created with mode `0755`. A refresh token is particularly sensitive because it can be exchanged repeatedly for new access tokens until revoked. The implementation also writes directly to the final path instead of using a protected temporary file followed by an atomic replacement. It does not verify that the destination is owned by the expected user or reject symbolic links. ### Attack Path 1. A user completes the device-code login flow. 2. `save_auth_state()` writes the access token and refresh token to `state/graph_auth.json`. 3. The host has a permissive default `umask`, resulting in a file readable by another local account. 4. The local attacker reads the authentication file. 5. The attacker submits the refresh token to the Microsoft identity token endpoint using the recorded client and tenant identifiers. 6. The attacker receives a valid Graph access token and invokes APIs covered by the granted scopes. ### Impact Assessment A successful attacker can obtain the same delegated Microsoft Graph privileges as the authenticated user ...[truncated 491 chars]
Remediation
View remediation
None: temp_path = AUTH_FILE.with_suffix(".tmp") fd = os.open(temp_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) try: with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) f.flush() os.fsync(f.fileno()) os.replace(temp_path, AUTH_FILE) os.chmod(AUTH_FILE, 0o600) finally: if temp_path.exists(): temp_path.unlink() ``` Existing installations should immediately change permissions on `state/` and `state/graph_auth.json` and rotate tokens if unauthorized local access may have occurred. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/utils.py:108
Finding

Graph bearer token can be transmitted to an unrestricted URL

Content
View full analysis
requests.Response: headers = kwargs.pop("headers", {}) headers["Authorization"] = f"Bearer {get_access_token()}" headers.setdefault("Accept", "application/json") if "json" in kwargs and "Content-Type" not in headers: headers["Content-Type"] = "application/json" kwargs["headers"] = headers resp = requests.request(method, url, timeout=60, **kwargs) if resp.status_code == 401: # token might be expired; refresh once refresh_access_token(force=True) headers["Authorization"] = f"Bearer {get_access_token()}" resp = requests.request(method, url, timeout=60, **kwargs) resp.raise_for_status() return resp def graph_url(path: str) -> str: if path.startswith("http"): return path if not path.startswith("/"): path = "/" + path return GRAPH_BASE_URL + path ``` ```python def download_file(item_id: str, remote: str, local: Path) -> None: if not item_id: if not remote: raise SystemExit("Provide --item-id or --remote.") item_id = resolve_item_path(remote) metadata = authorized_request("GET", graph_url(f"/me/drive/items/{item_id}")) download_url = metadata.json()["@microsoft.graph.downloadUrl"] resp = authorized_request("GET", download_url) local.write_bytes(resp.content) ``` ### Technical Analysis `authorized_request()` unconditionally attaches the Microsoft Graph bearer token to any URL passed to it. Meanwhile, `graph_url()` treats every string beginning with `http` as an already complete destination without validating its scheme or hostname. The OneDrive download operation obtains an `@microsoft.graph.dow ...[truncated 1620 chars]
Remediation
View remediation
requests.Response: parsed = urlparse(url) if parsed.scheme != "https" or parsed.hostname != "graph.microsoft.com": raise ValueError("Authenticated Graph requests must target graph.microsoft.com") return authorized_request(method, url, **kwargs) def download_preauthenticated(url: str) -> requests.Response: parsed = urlparse(url) if parsed.scheme != "https": raise ValueError("Download URL must use HTTPS") response = requests.get(url, timeout=60, allow_redirects=False) response.raise_for_status() return response ``` Microsoft's documented set of OneDrive storage hosts should be allowlisted if redirect handling is required. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/utils.py:20
Finding

Authentication always requests full-suite Microsoft 365 permissions

Content
View full analysis
None: scopes = list(DEFAULT_SCOPES) client_id = args.client_id or DEFAULT_CLIENT_ID tenant_id = args.tenant_id or DEFAULT_TENANT ``` The Skill documentation additionally states that scope override is disabled and that the Skill always uses `DEFAULT_SCOPES`. ### Technical Analysis The device-code authentication flow always requests the complete permission set, even when a user needs only mail, calendar, contacts, or another isolated feature. The repository's own `docs/permission-profiles.md` defines narrower profiles, but the implementation does not allow those profiles to be selected during login. `offline_access` further increases the consequences because it permits acquisition of a refresh token. Combining persistent delegated access with unrelated read/write privileges creates a substantially broader compromise boundary than necessary for single-purpose deployments. This behavior exceeds the minimum privileges required for individual declared workflows. For example, a mail-only webhook deployment does not require OneDrive, calendar, or contacts write access. ### Attack Path 1. A user installs the Skill only to process mail notifications. 2. The device-login flow requests mail, mail sending, calendar, files, contacts, and offline access permissions. 3. The user consents because narrower runtime profiles cannot be selected. 4. An attacker later steals the token file, captures an access token, or compromises the worker process. 5. The attacker uses permissions unrelated ...[truncated 850 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mail_webhook_adapter.py:101
Finding

Public webhook adapter buffers unbounded request bodies

Content
View full analysis
None: if not self._validate_path(): self._send_json(404, {"error": "not_found"}) return if self._maybe_validation_handshake(): return length = int(self.headers.get("Content-Length", "0")) raw = self.rfile.read(length) if length else b"{}" try: payload = json.loads(raw.decode("utf-8")) except json.JSONDecodeError: self._send_json(400, {"error": "invalid_json"}) return events, rejected = parse_notification_events(payload, expected_client_state) accepted = enqueue_events(queue_file, events) self._send_json(202, {"accepted": accepted, "rejected": rejected}) ``` ### Technical Analysis The adapter is intended to receive traffic from the public Internet through Caddy. It parses the client-provided `Content-Length` value and reads that number of bytes into memory without a maximum size. Validation of `clientState` occurs only after the complete body has been read and decoded as JSON. Therefore, an unauthenticated client does not need to know the shared client state to consume memory, occupy a handler thread, or force expensive JSON parsing. Because the service uses `ThreadingHTTPServer`, concurrent large or slow requests can create multiple threads and amplify resource exhaustion. No application-level read timeout, concurrency bound, rate limit, or request-size limit is configured in the reviewed code. ### Attack Path 1. The attacker discovers the public `/graph/mail` endpoint. 2. The attacker opens many concurrent POST requests. 3. Each request declares a very large `Content-Length` or transmits a large JSON document slowly. 4. The threaded server allocates handlers and waits for or buffers each body. 5. Memory, CPU, f ...[truncated 645 chars]
Remediation
View remediation
MAX_BODY_BYTES: self._send_json(413, {"error": "payload_too_large"}) return raw = self.rfile.read(length) ``` The reverse proxy should enforce an equal or smaller limit so oversized traffic is rejected before reaching Python. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mail_webhook_adapter.py:125
Finding

Webhook authentication secrets are exposed through logs and process arguments

Content
View full analysis
None: client_state = args.client_state or secrets.token_urlsafe(24) queue_file = Path(args.queue_file).expanduser().resolve() print("Starting Graph mail webhook adapter") print(f"- listen: http://{args.host}:{args.port}{args.path}") print(f"- queue: {queue_file}") print(f"- clientState: {client_state}") print("Use this same clientState when creating subscriptions.") ``` ```ini [Service] Type=simple EnvironmentFile=$ENV_FILE WorkingDirectory=$REPO_ROOT ExecStart=$PYTHON_BIN $WORKER_SCRIPT loop --session-key \${OPENCLAW_SESSION_KEY} --hook-url \${OPENCLAW_HOOK_URL} --hook-token \${OPENCLAW_HOOK_TOKEN} Restart=always RestartSec=3 ``` ```bash echo "Setup and validation completed. Summary:" echo "- Domain: https://$DOMAIN$ADAPTER_PATH" echo "- Client state: $CLIENT_STATE" echo "- Subscription ID: $SUBSCRIPTION_ID" echo "- Env file: $ENV_FILE" ``` ### Technical Analysis The Graph webhook `clientState` is treated as a secret elsewhere in the project, but the adapter prints it during startup. Under systemd, standard output normally enters the journal, creating a persistent copy available to users or services with journal-reading privileges. The end-to-end setup script also prints the same value to its terminal output, where it may be captured by automation logs or screenshots. The worker's OpenClaw hook token is expanded into the `ExecStart` command line. Depending on operating-system process visibility and systemd tooling, command arguments can be exposed through process inspection, service status output, diagnostics, or monitoring agents. Although `/etc/default/graph-mail-webhook` is set to mode `0 ...[truncated 1594 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (79)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SECURITY.md (reported line 11)May include surrounding context.

md
- Dedicated OpenClaw hook token for webhook auth
- Graph `clientState` validation for notification integrity
- Local queue + dedupe before agent wake-up
- No dependency on `curl | bash` installers in project scripts

## Supported release line

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a broad Microsoft 365 integration centered on webhook wake signals and managing multiple resource types (mail, calendar, OneDrive, contacts). This code chunk does not implement webhook handling or any Outlook/calendar/contacts behavior. Its actual purpose is much narrower: direct OneDrive file management through Microsoft Graph. While OneDrive is part of the declared scope, the primary declared emphasis on webhook-based wake signals and inbox polling is not reflected here, and the implemented sharing-link capability is an undeclared OneDrive-specific action. Therefore the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The supplied code only implements Outlook mail access through Microsoft Graph: listing messages, fetching a single message, optionally including body content, and modifying message state by marking as read or moving to a folder. The declared description emphasizes a broader Microsoft 365 Graph skill with webhook-based wake signals and management of mail, calendar, OneDrive, and contacts. No webhook or wake-signal behavior appears in this chunk, and no calendar, OneDrive, or contacts handling is present. Additionally, the code includes message mutation capabilities (mark-read and move), which go beyond simple inbox polling reduction. While this chunk may be one component of a larger skill, taken on its own it does not accurately represent the declared broader purpose.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · references/drive.md (reported line 40)May include surrounding context.

text

- `saveToSentItems` is `True` by default. Use `--no-save-copy` to disable.
- Attachments are sent as `fileAttachment` and are limited on this endpoint; for large files, implement upload session flow.

## Useful folder IDs

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · references/mail.md (reported line 26)May include surrounding context.

text

- `saveToSentItems` is `True` by default. Use `--no-save-copy` to disable.
- Attachments are sent as `fileAttachment` and are limited on this endpoint; for large files, implement upload session flow.

## Useful folder IDs

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Displaying the full OPENCLAW_SESSION_KEY is a direct secret disclosure issue. In a diagnostic script, this is especially risky because operators often paste outputs into tickets, chats, or monitoring systems, turning a local secret into a broadly distributed credential leak.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
92% confidence
Finding

Creating a sharing link changes access control on a remote file and can expose data beyond the intended audience, especially if anonymous links are allowed. In an agent skill context, this is more dangerous because an LLM or automation layer could trigger external sharing as a side effect without a clear human confirmation step.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/setup_mail_webhook_ec2.sh (reported line 118)May include surrounding context.

sh
echo "[1/7] Installing dependencies..."
run_cmd apt-get update -y
run_cmd apt-get install -y python3 python3-pip curl gnupg debian-keyring debian-archive-keyring apt-transport-https
ok "Dependencies installed"

if [[ "$DRY_RUN" == "true" ]] || ! command -v caddy >/dev/null 2>&1; then

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The script downloads a third-party repository GPG key and apt source definition over the network and immediately trusts them as root, then installs packages from that repository. If the source is compromised, redirected, or replaced, this can lead to arbitrary package installation and full system compromise on the EC2 host.

Content

Scanner excerpt · scripts/setup_mail_webhook_ec2.sh (reported line 126)May include surrounding context.

sh
if [[ "$DRY_RUN" == "true" ]]; then
    info "[DRY-RUN] install Caddy and apt repo configuration"
  else
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list >/dev/null
    apt-get update -y
    apt-get install -y caddy

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises extensive capabilities including environment access, file read/write, network access, and shell execution, but does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, this weakens reviewability and least-privilege enforcement, making it easier for a broad-privilege skill to be installed or invoked without operators understanding its effective access.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill instructs users to run a repository-provided shell script with sudo, which grants the script full root privileges to modify system configuration and services. Even though the document warns that these setup scripts are privileged and recommends dry-run/manual review, executing untrusted or insufficiently reviewed repo scripts as root creates a meaningful privilege-escalation and host-compromise risk.

Content

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

  • state/mail_webhook_dedupe.json
  • Automated EC2 bootstrap (Caddy + systemd + renew timer):
    bash
    sudo bash scripts/setup_mail_webhook_ec2.sh \
      --domain graphhook.example.com \
      --hook-url http://127.0.0.1:18789/hooks/wake \
      --hook-token "<OPENCLAW_HOOK_TOKEN>" \
    

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

This one-command setup flow uses sudo for a script that can write to /etc, systemd units, and potentially alter running services, giving the repository code root-level control over the host. The context makes this somewhat less suspicious because the privilege need is openly disclosed and related to system setup, but it remains dangerous if the script is malicious, compromised, or insufficiently reviewed.

Content

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

  • Use --dry-run to preview all privileged writes and service actions before applying changes.
  • One-command setup (steps 2..6):
    bash
    sudo bash scripts/run_mail_webhook_e2e_setup.sh \
      --domain graphhook.example.com \
      --hook-token "<OPENCLAW_HOOK_TOKEN>" \
      --hook-url "http://127.0.0.1:18789/hooks/wake" \
    

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
93% confidence
Finding

This sudo-invoked automation can also patch OpenClaw configuration and restart OpenClaw services, expanding impact beyond generic system setup into modification of agent runtime behavior. If abused or compromised, it could alter hook configuration, redirect traffic, weaken authentication, or persist malicious changes via service definitions, making the privilege boundary especially sensitive.

Content

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

  • Output ends with READY_FOR_PUSH: YES when setup is fully validated.
  • Include OpenClaw hook config in automation:
    bash
    sudo bash scripts/run_mail_webhook_e2e_setup.sh \
      --domain graphhook.example.com \
      --hook-token "<OPENCLAW_HOOK_TOKEN>" \
      --configure-openclaw-hooks \
    

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
82% confidence
Finding

Even the smoke-test path is documented as a sudo shell invocation, which normalizes elevated execution for repository automation and increases the chance users will run complex scripts as root without adequate review. The stated purpose is operational testing rather than stealthy behavior, but the trust model is still risky because root execution of testing code can modify system state or be extended to do so.

Content

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

text
- **Minimal-input smoke tests**:
  ```bash
  sudo bash scripts/run_mail_webhook_smoke_tests.sh \
    --domain graphhook.example.com \
    --create-subscription \
    --test-email tar.alitar@outlook.com

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · docs/minimal-setup.md (reported line 61)May include surrounding context.

4. Run one setup command

This script installs Caddy and systemd units (adapter/worker/timer), creates the Graph subscription, and persists runtime values.

bash
sudo bash scripts/run_mail_webhook_e2e_setup.sh \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · docs/troubleshooting.md (reported line 13)May include surrounding context.

md
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/mail_webhook_adapter.md (reported line 123)May include surrounding context.

md
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/diagnose_mail_webhook_e2e.sh (reported line 103)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/diagnose_mail_webhook_e2e.sh (reported line 104)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/diagnose_mail_webhook_e2e.sh (reported line 265)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/diagnose_mail_webhook_e2e.sh (reported line 266)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/run_mail_webhook_e2e_setup.sh (reported line 15)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/run_mail_webhook_e2e_setup.sh (reported line 167)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/run_mail_webhook_e2e_setup.sh (reported line 333)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/run_mail_webhook_e2e_setup.sh (reported line 335)May include surrounding context.

sh
1) Verify active subscription resource (`me/messages` recommended).
2) Verify notification URL is public HTTPS and reachable.
3) Check adapter service and reverse proxy status.
4) Run `sudo bash scripts/diagnose_mail_webhook_e2e.sh --domain <your-domain> --repo-root "$(pwd)"` for full pipeline checks.

## Subscription has `clientState: null`

Static analysis

No suspicious patterns detected.