Back to skill

Security audit

Nex DepCheck

Security checks for vulnerabilities and agentic risk

Overview

This dependency-checking skill is not malicious, but its main security check can miss dependencies while reporting a clean result.

Install only if you want a lightweight local import scanner. Do not rely on it as the sole gate for publishing or approving skills, because it can miss dynamic or unusual imports and may falsely report a project as clean; review suspicious code manually or use a stronger parser-based scanner as well.

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

T09 · Insecure Skill Coding Practices

Warning
Location
lib/scanner.py:43
Finding

External Dependency Checks Can Be Bypassed Through Dynamic or Unrecognized Import Syntax

Content
View full analysis

Vulnerability Details

File Location: lib/scanner.py, lines 43–54 and line 124
Vulnerability Type: Incomplete static analysis resulting in dependency-check bypass
Risk Level: Medium

Vulnerable Code

python
for line in content.splitlines():
    line = line.strip()
    from_match = re.match(r'^from\s+([\w.]+)\s+import', line)
    if from_match:
        imports.append(from_match.group(1))
        continue
    import_match = re.match(r'^import\s+([\w., ]+)', line)
    if import_match:
        for mod in import_match.group(1).split(','):
            mod = mod.strip().split(' as ')[0].strip()
            if mod and re.match(r'^[\w.]+$', mod):
                imports.append(mod)

The final status is derived solely from the external imports found by this parser:

python
'clean': len(external) == 0,

Technical Analysis

The scanner identifies imports by applying regular expressions to individual source lines instead of parsing Python syntax. This only recognizes conventional import and from ... import ... statements that begin on a scanned line.

External dependencies loaded through mechanisms such as importlib.import_module(), __import__(), dynamically executed source, or an import statement following another statement on the same line are not recognized. For example, a scanned file could contain:

python
import importlib
package = importlib.import_module("requests")

The scanner would identify importlib as a standard-library module but would not identify requests as an external dependency. Because the clean result is calculated solely from the resulting external list, the skill can incorrectly report the scanned project as clean.

This is a fail-open condition: unsupported syntax, dynamic imports, and some incomplete analyses are interpreted as an absence of external dependencies rather than as an indeterminate scan requiring manual review.

...[truncated 1683 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the line-oriented regular-expression parser with ast.parse() and walk all ast.Import and ast.ImportFrom nodes. This correctly handles indentation, semicolon-separated statements, aliases, parenthesized imports, and multiline syntax.
  2. Inspect calls to common dynamic import mechanisms:
    • __import__("module")
    • importlib.import_module("module")
    • Aliases that can be resolved statically
  3. Extract module names when these calls use constant string arguments.
  4. If a dynamic import target cannot be resolved statically, return an explicit warning or indeterminate status instead of reporting the project as clean.
  5. Treat syntax errors, decoding failures, and unreadable files as scan failures. Do not silently interpret them as files with no dependencies.
  6. Add regression tests covering conventional imports, multiline imports, semicolon-separated imports, constant-string dynamic imports, unresolved dynamic imports, malformed Python files, and unreadable files.
  7. Distinguish results such as clean, external dependencies found, and incomplete analysis so users cannot mistake partial coverage for verified stdlib-only compliance.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill advertises shell-based setup and functionality that reads files and may perform network-related actions, but it declares no explicit tool scope or permission boundaries. That creates an authorization ambiguity where an agent platform could overgrant capabilities or invoke the skill without clear limits on filesystem, shell, or network access.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrases are broad and map to common requests about checking imports or dependencies, which increases the chance the skill is invoked unintentionally in unrelated conversations. Unintended activation matters here because the skill can scan directories and files, potentially exposing local code structure or causing broader-than-expected filesystem access.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · lib/config.py (reported line 28)May include surrounding context.

python
'mmap', 'modulefinder', 'multiprocessing', 'netrc', 'nis', 'nntplib',
    'numbers', 'operator', 'optparse', 'os', 'ossaudiodev', 'parser',
    'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil',
    'platform', 'plistlib', 'poplib', 'posix', 'posixpath', 'pprint',
    'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr',
    'pydoc', 'queue', 'quopri', 'random', 're', 'readline', 'reprlib',
    'resource', 'rlcompleter', 'runpy', 'sched', 'secrets', 'select',

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The example phrase "Check all my skills for external deps" is a broad request pattern that could collide with everyday auditing or review requests. The documentation does not pair it with boundaries or clarifying conditions that limit invocation to this dependency-checking skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This shell script creates a file under $HOME/.local/bin and makes it executable, which is a user-environment modification. Although the script logs the action after the fact, there is no prior warning, confirmation prompt, or explanatory comment/docstring before performing the write.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.