Back to skill

Security audit

A Share Daily Report

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real A-share report generator, but it broadly loads workspace secrets and uses some unsafe data-source and publishing patterns that should be reviewed before installation.

Review before installing. Use it only in a dedicated workspace or virtual environment, avoid a shared .env containing unrelated credentials, disable Feishu publishing unless you intend reports to be sent externally, and remove or restrict logs if they may contain token prefixes or recipient IDs. Prefer official HTTPS data sources and do not follow the documented external tushare-skills import guidance unless you have separately reviewed that package.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/data_fetcher.py:39
Finding

Workspace-Level Environment File Is Loaded with Override Enabled

Content
View full analysis
Remediation
View remediation
/.env`, rather than traversing into the shared workspace. 2. Prefer explicit configuration injection by the invoking runtime. 3. Remove `override=True`; use `override=False` so trusted process variables retain precedence. 4. Do not import an entire environment file when only specific values are required. Parse and validate an allowlist containing only: - `MX_APIKEY` - `MX_APIKEY_BACKUP` - `TUSHARE_TOKEN` 5. Keep secrets in a dedicated secret manager where available. 6. Construct a minimal `env` dictionary for subprocesses instead of allowing them to inherit the complete process environment. 7. Restrict `.env` permissions to the owning user and document the exact secret scope the Skill requires. 8. Add tests confirming that unrelated variables are neither loaded nor overridden. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/data_fetcher.py:25
Finding

API Token Prefixes and Full Feishu Recipient Identifiers Are Written to Logs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/data_fetcher.py:753
Finding

Financial Market Data Is Retrieved over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
DATA_SOURCES.md:65
Finding

Documentation Recommends an Externally Installed Skill with an Embedded Token over an Unofficial Plaintext Endpoint

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (67)

Tainted flow: 'headers' from os.getenv (line 675, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 575)May include surrounding context.

python
url = 'https://mkapi2.dfcfs.com/finskillshub/api/claw/news-search'
                    headers = {'Content-Type': 'application/json', 'apikey': api_key}
                    payload = {'query': f'A股 {date_str} 财经新闻'}
                    return requests.post(url, json=payload, headers=headers, timeout=15)

                resp = _do_news_request(mx_api_key)
                if resp.status_code == 200:

Tainted flow: 'headers' from os.getenv (line 675, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 689)May include surrounding context.

python
query, key = query_key
                    logger.info(f"[DEBUG] 查询期指: {query}")
                    payload = {"toolQuery": query}
                    r = requests.post(url, json=payload, headers=headers, timeout=12)
                    if r.status_code == 200:
                        return key, r.json()
                    return key, None

Tainted flow: 'mx_apikey' from os.getenv (line 669, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 724)May include surrounding context.

python
try:
                import requests as _req
                url2 = "https://mkapi2.dfcfs.com/finskillshub/api/claw/query"
                resp2 = _req.post(url2, json={"toolQuery": "上证50 最新价 涨跌幅"},
                                  headers={"apikey": mx_apikey}, timeout=10)
                if resp2.status_code == 200:
                    d2 = resp2.json()

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

Automatically loading a .env during object initialization gives a generic data-fetching component implicit credential-access capability before any specific feature requires it. In an agent skill context, eager secret access is more dangerous because the component may run in shared workspaces and gain visibility into credentials unrelated to the requested task.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 21)May include surrounding context.

python
def __init__(self, config):
        self.config = config
        # 确保 .env 文件被加载(支持子进程环境)
        self._load_env()
        self._init_akshare()
        self._init_tushare()

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The _load_env helper exists specifically to import secrets from a parent .env into process environment, which expands the module’s credential access beyond its stated role. In a plugin-like environment this can expose unrelated tokens to code paths that also perform outbound requests and logging.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 39)May include surrounding context.

python
logger.warning("⚠️ TUSHARE_TOKEN 未设置,资金流向数据可能无法获取")

    def _load_env(self):
        """加载 .env 文件到环境变量"""
        try:
            from dotenv import load_dotenv
            # 向上 3 级:scripts/ → a-share-daily-report/ → skills/ → workspace-trader/

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

Reading ../../../.env and overriding existing variables is a concrete overreach of credential scope and configuration authority. If deployed in a larger workspace, the module can pull in and replace unrelated secrets, creating both confidentiality and integrity risks across the environment.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 43)May include surrounding context.

python
try:
            from dotenv import load_dotenv
            # 向上 3 级:scripts/ → a-share-daily-report/ → skills/ → workspace-trader/
            dotenv_path = os.path.join(os.path.dirname(__file__), '..', '..', '..', '.env')
            dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · DATA_SOURCES.md (reported line 215)May include surrounding context.

md
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 168)May include surrounding context.

md
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 262)May include surrounding context.

md
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · TODO.md (reported line 63)May include surrounding context.

md
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 47)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 49)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 51)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/publisher.py (reported line 181)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/publisher.py (reported line 188)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 232)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 235)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 246)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 304)May include surrounding context.

python
dotenv_path = os.path.normpath(dotenv_path)
            if os.path.exists(dotenv_path):
                load_dotenv(dotenv_path, override=True)  # 覆盖已存在的环境变量
                logger.debug(f"✅ 已加载 .env 文件: {dotenv_path}")
            else:
                logger.warning(f"⚠️ .env 文件不存在: {dotenv_path}")
        except ImportError:

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

Re-loading the .env immediately before external API use reinforces the pattern of broad, implicit credential acquisition at call time. In context, this makes the skill more dangerous because secret access is tightly coupled with outbound network activity, increasing the chance that unrelated workspace credentials are used by plugin code without explicit operator intent.

Content

Scanner excerpt · scripts/data_fetcher.py (reported line 668)May include surrounding context.

python
sources = []

        # 优先级1:使用 mx-data Skill(需要 MX_APIKEY)
        self._load_env()  # 确保 .env 已加载
        mx_apikey = os.getenv('MX_APIKEY')
        logger.info(f"[DEBUG] MX_APIKEY状态: {'已设置' if mx_apikey else '未设置'}")
        if mx_apikey:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/publisher.py (reported line 182)May include surrounding context.

python
return user_id

        # 优先级4: 从 .env 文件加载
        dotenv_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), '..', '..', '.env')
        if os.path.exists(dotenv_path):
            from dotenv import load_dotenv
            load_dotenv(dotenv_path)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 233)May include surrounding context.

python
return user_id

        # 优先级4: 从 .env 文件加载
        dotenv_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), '..', '..', '.env')
        if os.path.exists(dotenv_path):
            from dotenv import load_dotenv
            load_dotenv(dotenv_path)

Credential Access

High
Category
Privilege Escalation
Confidence
79% confidence
Finding

The script reads the MX_APIKEY environment variable to verify configuration and prints whether it is set plus its length. Although it does not print the secret value, it does access credential material and disclose metadata about secret presence, which can aid environment reconnaissance in shared logs or untrusted execution contexts. In this skill context, the behavior is operationally motivated and less dangerous than active exfiltration, but it is still a real information-exposure concern.

Content

Scanner excerpt · scripts/verify_data_sources.py (reported line 238)May include surrounding context.

python
checks.append(('.env 文件', env_exists))

    if env_exists:
        print("   ✅ .env 文件存在")
        # 检查 MX_APIKEY
        mx_apikey = os.environ.get('MX_APIKEY')
        if mx_apikey:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The architecture explicitly includes creating Feishu documents, sending Feishu messages, and generating PDFs, but the design shown here provides no user-facing consent, data-classification controls, or warning that report contents may be transmitted to external services. If report content later includes sensitive inputs, watchlists, internal analysis, or API-derived data, this creates a real risk of unintended external disclosure through document publishing and chat delivery.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document discloses concrete local environment details, installed skills, and the presence of configured credentials, which increases operational exposure and helps an attacker understand what services and secrets are available. Even though it does not print the token values themselves, confirming that token-backed services and API keys are present is sensitive reconnaissance data and exceeds what is necessary in public-facing usage documentation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.