T09 · Insecure Skill Coding Practices
- Location
scripts/merge_abilities.py:10- Finding
Predictable Shared Temporary File Allows Ability Database Poisoning
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a Dota 2 coaching skill that mostly reads bundled game data, with optional manual update scripts that fetch public game data and rewrite local databases.
Install only if you want a Chinese-language Dota 2 coaching skill. Normal use should read bundled data locally. Run the update scripts only when you intentionally want to refresh the game databases, preferably from the skill directory and not as root; avoid the merge scripts unless you trust the /tmp dotabase JSON files they consume.
scripts/merge_abilities.py:10Predictable Shared Temporary File Allows Ability Database Poisoning
scripts/merge_items.py:11Predictable Shared Temporary File Allows Item Database Poisoning
The trigger list includes broad generic phrases such as "dota", "dota2", and "dota攻略", which can easily appear in normal conversation and cause unintended activation. While this skill is game-related and not handling sensitive operations, ambiguous activation can still produce unwanted responses, context hijacking, or accidental invocation during unrelated chats about the game.
The trigger list contains very broad terms such as "dota" and "dota2", which can cause the skill to activate in many unrelated conversations that merely mention the game. Over-triggering can lead to unintended invocation, response hijacking, or interference with other skills, especially in multi-skill environments where routing is based on keyword matching.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
on the level of Exort.",
"impact_damage": "55/75/95/115/135/155/175/195/215"
},
{
"key": "invoker_sun_strike",
"name": "阳炎冲击",
"mc": "175",
"cd": "23",
"behavior": "",
"scepter_grants": false,
"shard_grants": false,
"cast_range": "0",
"bkbpierce": "Yes",
"desc": "Sends a catastrophic ray of fierce energy from the sun at any targeted location, incinerating all enemies standing beneath it once it reaches the earth. Deals damage based on the level of Exort, however this damage is spread evenly over all enemies hit."
},
{
"key": "invoker_forge_spirit",
"name": "熔炉精灵",
"mc": "75",
"cd": "27",
"behavior": "",
"scepter_grants": false,
"shard_grants": false,
"cast_range": null,
"bkbpierce": "No",
"desc": "Invoker forges a spirit embodying the strength of fire and fortitude of ice. Damage a
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
on the level of Exort.",
"impact_damage": "55/75/95/115/135/155/175/195/215"
},
{
"key": "invoker_sun_strike",
"name": "阳炎冲击",
"mc": "175",
"cd": "23",
"behavior": "",
"scepter_grants": false,
"shard_grants": false,
"cast_range": "0",
"bkbpierce": "Yes",
"desc": "Sends a catastrophic ray of fierce energy from the sun at any targeted location, incinerating all enemies standing beneath it once it reaches the earth. Deals damage based on the level of Exort, however this damage is spread evenly over all enemies hit."
},
{
"key": "invoker_forge_spirit",
"name": "熔炉精灵",
"mc": "75",
"cd": "27",
"behavior": "",
"scepter_grants": false,
"shard_grants": false,
"cast_range": null,
"bkbpierce": "No",
"desc": "Invoker forges a spirit embodying the strength of fire and fortitude of ice. Damage a
This code's natural-language strings are entirely in Chinese, including the module description and runtime status messages, with no indication that the skill is intentionally region-specific or that users can select another language. That creates a locale-policy concern because the skill implicitly forces one language without opt-in.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def fetch_ability_details():
url = "https://api.opendota.com/api/constants/abilities"
result = subprocess.run(['curl', '-s', url], capture_output=True, text=True)
return json.loads(result.stdout)
def get_ability_field(ability_data, key, attrib_header_keyword=None):
This code performs a file write that modifies the local heroes_db.json database, but there is no confirmation prompt and no explicit user-facing warning near the write operation. Although the top docstring says the script merges data into the file, the actual overwrite behavior is safety-relevant and should be more clearly disclosed at execution time or through stronger inline warning language.
The module docstring states the script is for Dota 2 hero/item queries in Chinese, and the script's usage and output strings are consistently hard-coded in Chinese. This creates a natural-language locale policy issue because the skill forces a specific language without any visible opt-in, alternative locale, or documented region-specific justification.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def fetch_item_popularity(hero_id):
url = f'https://api.opendota.com/api/heroes/{hero_id}/itemPopularity'
try:
result = subprocess.run(
['curl', '-sL', url, '-H', 'User-Agent: Mozilla/5.0', '--max-time', '15'],
capture_output=True, text=True, timeout=20
)
This JSON dataset contains user-facing localized_name values in Chinese, beginning at L0006 and continuing throughout the file, with no indication that language selection is optional or contextually limited. Under the stated policy, forcing a specific locale in natural-language content without opt-in is a policy violation.
The script performs a file write to a fixed path, replacing the existing abilities database in place. While the module docstring describes usage, there is no explicit warning, confirmation prompt, or inline notice at the write site that existing data will be overwritten.
This Python file contains natural-language content entirely in Chinese, including the module description and runtime messages, but it does not indicate that the skill is region-specific or provide any user opt-in for language/locale. Under the policy for natural-language violations, forcing a specific language without choice is reportable across all file types.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def curl_json(url, timeout=30):
"""用 curl 拉取 JSON"""
result = subprocess.run(
['curl', '-sL', url, '-H', 'User-Agent: Mozilla/5.0', '--max-time', str(timeout)],
capture_output=True, text=True, timeout=timeout + 5
)
This JSON file consists entirely of Chinese-language strings for hero talent text, indicating a hard-coded locale choice. Because no accompanying in-file note documents that this is a region-specific localization dataset or offers any language selection, it constitutes a natural-language locale policy concern under the stated rule.
This Python file contains natural-language content entirely in Chinese in the module docstring and later prints Chinese-only status messages, which imposes a specific language on users/operators. Under the policy, forced language or locale without user opt-in or a documented justification is a natural-language policy violation.