Back to skill

Security audit

Qlik Cloud

Security checks for vulnerabilities and agentic risk

Overview

This Qlik Cloud skill is purpose-aligned, but its scripts handle powerful API credentials and tenant-changing actions with unsafe shell/Python patterns that merit review before installation.

Review before installing. Use a least-privilege Qlik API key, store it in a secret manager or runtime environment rather than TOOLS.md, require an https:// Qlik tenant, and avoid invoking these scripts with untrusted questions, IDs, or tenant endpoints until the shell/Python interpolation and temporary-file issues are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qlik-alert-get.sh:27
Finding

Arbitrary Python Code Execution Through Unsafe Shell Variable Interpolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qlik-alert-get.sh:21
Finding

Bearer API Key Can Be Transmitted Over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Predictable Shared Temporary File Enables Symlink and Race Attacks

Content
View full analysis
/dev/null || echo "") ``` ### Technical Analysis The script writes the HTTP response to a fixed filename in the globally writable `/tmp` directory. It neither creates the file securely nor verifies its ownership and type before use. A local attacker can pre-create the path as a symbolic link. When curl opens the output path, it may truncate or overwrite the linked target using the Agent account's permissions. The predictable filename also creates a race between concurrent script executions, allowing one invocation to overwrite or consume another invocation's response. The file is not removed after use, which can retain response data beyond the script's lifetime. Its effective permissions depend on the process umask and prior file state. ### Attack Path 1. A local attacker predicts the fixed path `/tmp/qlik_delete_response.txt`. 2. The attacker creates that path as a symbolic link to a file writable by the Agent account, or repeatedly replaces the path during execution. 3. The Agent runs `qlik-app-delete.sh`. 4. Curl opens the predictable path and writes the tenant response. 5. The linked target may be truncated or overwritten. 6. Alternatively, a concurrent process replaces or reads the response file, causing response tampering or disclosure. ### Impact Assessment Potential impact includes: - Overwriting or truncating files writable by the Agent account. - Corrupting script output through cross-process response substitution. - Disclosing API response content to another local process. - Retaining deletion-r ...[truncated 251 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:10
Finding

Setup Documentation Encourages Plaintext Storage of a Long-Lived API Key

Content
View full analysis
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 (68)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description substantially overstates the functionality relative to the supplied code chunk. The script only retrieves a limited list of Qlik apps accessible to the current user and formats selected fields from the response. While this behavior is consistent with a small subset of the declared domain (Qlik app management), it does not support the claimed breadth of 37 tools or the many listed capabilities. There is no undeclared harmful behavior; the mismatch is that the declared purpose is far broader than what the code actually implements.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description claims a comprehensive Qlik Cloud integration with 37 tools covering many product areas. However, the supplied code chunk only implements one narrow capability: listing AutoML experiments. While AutoML is one of the declared areas, the chunk does not evidence the broad set of other capabilities named in the description. This is therefore a description-to-code mismatch at the level of scope and primary represented functionality for the supplied chunk. There is no sign of unrelated or hidden behavior beyond calling the Qlik ML experiments API and transforming the response.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents a broad, multi-tool Qlik Cloud integration for many administrative and analytics functions. The actual code chunk performs one specific task: listing Qlik apps and identifying duplicate names. While this behavior is related to Qlik app management at a high level, it does not substantiate the declared breadth or primary purpose of the skill. There is no evidence here of the many other claimed capabilities. This is therefore a material description-to-behavior mismatch due to overbroad declared functionality versus narrowly implemented behavior in the supplied code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Yes, there is a material mismatch. The description claims a comprehensive Qlik Cloud integration with many capabilities across analytics, management, AI, and governance features. The actual code chunk is narrowly scoped: it checks that QLIK_TENANT and QLIK_API_KEY are set, calls the current-user endpoint, and formats the response as a health-check result. While health checks are one of the declared features, the supplied code does not substantiate the much broader declared purpose. The primary implemented purpose is tenant connectivity and basic identity/status validation, not a full 37-tool Qlik platform integration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code is clearly related to Qlik Cloud and specifically to one declared area: reloads. However, the declared description presents a much broader capability set and emphasizes a complete integration with 37 tools. This code chunk only performs one narrow action: cancelling a reload via POST /api/v1/reloads/{id}/actions/cancel. There is no evidence here of the many other advertised capabilities. Because the described scope and primary capability breadth materially exceed what this supplied code chunk actually does, this is a description-behavior mismatch for the provided chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description portrays a comprehensive Qlik Cloud integration with many distinct capabilities, while the actual code chunk implements only a narrow reload-status check. Although reloads are one listed area in the declared purpose, this specific code does not substantiate the much broader claims. There is no evidence here of search, app management, Insight Advisor, automations, AutoML, Qlik Answers AI, data alerts, spaces, users, licenses, files, or lineage functionality. The code does access Qlik Cloud consistently, so the mismatch is not about unrelated resources; it is about the description materially overstating the implemented capabilities in the supplied chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk has a much narrower scope than the declared description. Its sole function is to trigger a reload for a specified Qlik app and report success or error details. While reloads are mentioned in the declared purpose, the description represents a large, full-featured Qlik Cloud integration with many unrelated capabilities that are not implemented here. That makes the description inaccurate for this supplied code chunk. There is no evidence of unrelated malicious behavior, but there is a clear description-versus-behavior mismatch due to substantial overclaiming of capabilities and a materially different breadth of purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code does interact with Qlik Cloud, so it is within the same general product area, but its actual behavior is much narrower than the declared purpose. This chunk only performs a tenant/current-user info lookup via /api/v1/users/me and formats the response. It does not implement health checks, app management, reloads, natural language queries, automations, AutoML, Qlik Answers AI, alerts, spaces, licenses, data files, or lineage. Given the evaluation criteria, this is a material description-versus-behavior mismatch because the declared purpose describes a broad multi-tool integration, whereas the provided code chunk only exposes a specific user/tenant info retrieval capability.

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 31)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 72)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 142)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 162)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 165)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 20)May include surrounding context.

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

# Get apps list and pipe directly to Python
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.