Back to skill

Security audit

qlik

Security checks for vulnerabilities and agentic risk

Overview

This Qlik Cloud skill mostly matches its stated purpose, but it needs review because its scripts can expose the API key or run unintended local code if inputs or tenant settings are unsafe.

Install only after reviewing and preferably fixing the shell scripts. Use a minimally scoped Qlik API key, set QLIK_TENANT only to the exact HTTPS Qlik Cloud tenant you control, avoid storing long-lived keys in broadly readable files, and do not expose these scripts to untrusted queries or IDs until Python interpolation and temporary-file handling are hardened.

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
scripts/qlik-search.sh:21
Finding

Arbitrary Python Code Execution Through Unsafe Argument Interpolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qlik-health.sh:15
Finding

Bearer Token Disclosure Through Unvalidated or Plaintext Tenant URLs

Content
View full analysis
``` Using `http://` exposes the token to passive and active network interception. Allowing an arbitrary HTTPS hostname sends the token directly to that host. The `-L` option also enables redirects; redirect behavior should be constrained even where a particular curl version protects sensitive headers during cross-host redirects. Communication with the configured Qlik tenant is necessary for the declared functionality, but accepting plaintext HTTP and unrestricted destinations is not necessary and violates least-privilege credential handling. ### Attack Path 1. An attacker modifies the `QLIK_TENANT` environment variable, influences a generated configuration, or persuades an operator to use an attacker-controlled tenant URL. 2. The script accepts the value because it begins with `http`. 3. The script invokes `curl` and attaches `QLIK_API_KEY` as a bearer token. 4. If the destination is attacker-controlled, the attacker receives the token directly. 5. If plaintext HTTP is used, an on-path attacker can captur ...[truncated 1037 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qlik-app-delete.sh:24
Finding

Predictable Temporary File Enables Symlink Overwrite and Response Tampering

Content
View full analysis
/dev/null || echo "") python3 -c " import json import sys app_id = '$APP_ID' http_code = '$HTTP_CODE' response = '''$RESPONSE''' timestamp = '$TIMESTAMP' ``` ### Technical Analysis The deletion script writes its HTTP response to the fixed, globally predictable path: ```text /tmp/qlik_delete_response.txt ``` Shared temporary directories are generally writable by other local users and processes. An attacker can create the target as a symbolic link before execution or replace it during execution. Because the script neither creates the file securely nor verifies its ownership and type, `curl` may follow the link and write through it. The file is also never removed. It can persist after execution and may expose Qlik API error details to another process, depending on the file mode and system configuration. A local attacker can additionally populate or replace the file to manipulate the response consumed by the script. The response is subsequently interpolated into Python source, compounding the separate Python injection weakness if attacker-controlled content contains terminating triple quotes. ### Attack Path 1. A local attacker predicts the fixed `/tmp/qlik_delete_response.txt` path. 2. Before the Skill runs, the attacker creates that path as a symbolic link to a file writable by the Skill’s operating-system account. 3. The Agent invokes `qlik-app-delete.sh`. 4. `curl -o` opens the predictable path and may follow the symbolic link. 5. The HTTP response overwrites or corrupts the linked target file. 6. Altern ...[truncated 1078 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (76)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code implements a narrow app-listing function only. It authenticates with QLIK_TENANT and QLIK_API_KEY, calls Qlik Cloud app/item listing endpoints, optionally filters by space, and formats the returned app metadata. There is no evidence in this code chunk of the many other declared capabilities such as health checks, app management beyond listing, reload execution, Insight Advisor queries, automations, AutoML, Qlik Answers AI, alerts, user/license management, file handling, or lineage. This is a material description-versus-behavior mismatch because the declared purpose describes a broad 37-tool integration, while the actual code chunk performs just one limited listing operation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code implements one narrow Qlik Cloud app-auditing utility: it reads tenant/API key environment variables, calls the apps listing endpoint, and analyzes duplicate app names. This fits only a small slice of 'app management' or health/audit behavior. It does not implement the vast majority of the declared capabilities, such as search, reload operations, natural-language analytics, automations, AutoML, Qlik Answers AI, alerts, spaces, users, licenses, data files, or lineage. The description therefore materially overstates and misrepresents the actual behavior and primary purpose of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description claims a comprehensive Qlik Cloud integration with many operational and analytics features, but the code chunk only checks connectivity and fetches the current user profile from Qlik Cloud. While health checks are one declared feature, the supplied code does not substantiate the broader declared purpose and instead represents a much narrower skill. This is a material description-versus-behavior mismatch due to the substantially overstated scope and primary capability set.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code only performs one specific reload-related function: fetch reload status for a provided reload ID using Qlik tenant and API key credentials. While this behavior is within the broad declared domain of Qlik Cloud and reloads, the declared description claims a complete 37-tool integration spanning many unrelated capabilities that are not present here. This is a material description-versus-behavior mismatch because the actual code chunk has a much narrower primary purpose than the declared functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk has a narrow, specific function: POST to the Qlik Cloud reloads API to trigger an app reload and report the result. The declared description presents a much broader skill with many capabilities across the Qlik platform. While app reloads are one listed capability, this code alone does not accurately represent the declared scope and primary purpose. There is no evidence of unrelated or dangerous undeclared behavior, but there is a substantial description-to-behavior mismatch because the implementation is far more limited than advertised.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code is narrowly focused on searching Qlik Cloud items via the /api/v1/items endpoint and formatting the results. It does not implement the wide range of capabilities claimed in the description, such as management operations, reloads, AI features, lineage, or user/license handling. While search is one of the declared capabilities, the declared description presents the skill as a complete multi-tool Qlik integration, whereas this code chunk represents only a small subset of that functionality. Therefore the description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description presents a comprehensive Qlik Cloud integration with many operational and analytics capabilities. The actual code only retrieves current-user and tenant-related information from a single Qlik API endpoint. While this behavior is within the general Qlik Cloud domain, it does not substantiate the declared breadth or primary purpose of the skill. This is a material description-to-behavior mismatch because the code chunk supports only a small subset of the claimed functionality.

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 26)May include surrounding context.

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **Actual data values** (KPIs, numbers, trends) | `qlik-insight.sh` | "what is total sales", "which store has lowest stock" |

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 · scripts/qlik-alert-get.sh (reported line 24)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/data-alerts/${ALERT_ID}" | python3 -c "

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 · scripts/qlik-alert-trigger.sh (reported line 24)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL -X POST \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/data-alerts/${ALERT_ID}/actions/evaluate" | python3 -c "

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 · scripts/qlik-alerts.sh (reported line 19)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/data-alerts?limit=${LIMIT}" | python3 -c "

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 · scripts/qlik-answers-ask.sh (reported line 36)May include surrounding context.

sh
# If no thread ID, create one first
if [[ -z "$THREAD_ID" ]]; then
  THREAD_NAME="Conversation: ${TIMESTAMP}"
  THREAD_RESPONSE=$(curl -sL -X POST \
    -H "Authorization: Bearer ${QLIK_API_KEY}" \
    -H "Content-Type: application/json" \
    -d "{\"name\": \"${THREAD_NAME}\"}" \

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 · scripts/qlik-answers-ask.sh (reported line 51)May include surrounding context.

sh
fi

# Invoke the question on the thread
RESPONSE=$(curl -sL -X POST \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{\"input\":{\"prompt\":$(echo "$QUESTION" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read().strip()))'),\"promptType\":\"thread\",\"includeText\":true}}" \

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 · scripts/qlik-answers-assistants.sh (reported line 19)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/assistants?limit=${LIMIT}" | python3 -c "

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 · scripts/qlik-app-create.sh (reported line 36)May include surrounding context.

sh
fi
BODY="$BODY}}"

curl -sL -X POST \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "$BODY" \

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 · scripts/qlik-app-fields.sh (reported line 25)May include surrounding context.

sh
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

# Get app metadata which includes table/field info
curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/apps/${APP_ID}/data/metadata" | python3 -c "

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 · scripts/qlik-app-get.sh (reported line 24)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/apps/${APP_ID}" | python3 -c "

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 · scripts/qlik-app-lineage.sh (reported line 24)May include surrounding context.

sh
TENANT="${QLIK_TENANT%/}"
[[ "$TENANT" != http* ]] && TENANT="https://$TENANT"

curl -sL \
  -H "Authorization: Bearer ${QLIK_API_KEY}" \
  -H "Content-Type: application/json" \
  "${TENANT}/api/v1/apps/${APP_ID}/data/lineage" | python3 -c "

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 · scripts/qlik-apps.sh (reported line 55)May include surrounding context.

sh
# Use /items API for space filtering (personal or specific space)
  URL="${TENANT}/api/v1/items?resourceType=app&spaceId=${SPACE}&limit=${LIMIT}"
  
  curl -sL \
    -H "Authorization: Bearer ${QLIK_API_KEY}" \
    -H "Content-Type: application/json" \
    "$URL" | python3 -c "

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 · scripts/qlik-apps.sh (reported line 98)May include surrounding context.

sh
"
else
  # Use /apps API for all apps (no space filter)
  curl -sL \
    -H "Authorization: Bearer ${QLIK_API_KEY}" \
    -H "Content-Type: application/json" \
    "${TENANT}/api/v1/apps?limit=${LIMIT}" | python3 -c "

Static analysis

No suspicious patterns detected.