Back to skill

Security audit

hoseo-lms

Security checks for vulnerabilities and agentic risk

Overview

This skill openly includes LMS automation, but its read-only framing understates that automated lecture playback may affect attendance or progress records and it handles LMS passwords in unsafe ways.

Review carefully before installing. Only use this if you are authorized by your institution to automate LMS lecture playback, and assume playback may update attendance or progress records. Avoid storing your LMS password in plaintext or passing it with --pw; use a separate low-risk environment and rotate credentials if you already followed those examples. Do not run with unlimited lecture playback unless you deliberately intend that scope.

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

other

Error
Location
SKILL.md:22
Finding

Playback automation contradicts the declared read-only behavior

Content
View full analysis
0 and state["current"] >= state["duration"] - 1): info(f"Completed: {lecture_title}") return "done" if state["paused"] and state["duration"] > 0: debug(f"Video paused, resuming: {lecture_title}") _start_playback(video_frame) ``` The course-processing loop repeatedly operates on unfinished lectures: ```python result = watch_lecture(page, lecture, timeout_seconds=timeout_seconds) if result == "unavailable": skipped_lectures.add(title_key) elif result == "done": watched_count += 1 limit_str = f"/{limit_lectures}" if limit_lectures > 0 else "/unlimited" info(f"[{course['class_name']}] Watched: {watched_count}{limit_str}") ``` ### Technical Analysis The code logs into the LMS, identifies unfinished lectures, opens their authenticated video players, starts playback, automatically resumes paused or stalled videos, and waits until each video reaches its end. Even though the Python code does not directly call a named attendance-submission endpoint, authenticated LMS video players commonly send progress events, heartbeat requests, or completion ...[truncated 1629 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/auto_attend.py:568
Finding

LMS password can be exposed through command-line arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/auto_attend.py:519
Finding

Chromium sandbox is disabled while processing authenticated web content

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Executable third-party dependencies are not reproducibly pinned

Content
View full analysis
=1.40 ``` The setup instructions also install the latest available global CLI package: ```bash npm i -g clawhub ``` ### Technical Analysis The lower-bound-only Playwright requirement allows dependency resolution to select versions that were not reviewed with this project. There is no lockfile or integrity hash to make installation reproducible. The global npm installation similarly selects the current registry version and gives that package installation-time and runtime access under the user's account. Global installation increases the potential effect on the user's environment. The project history contains no evidence that these package names are typosquatted or currently malicious; the finding concerns unsafe version and integrity controls rather than a confirmed malicious package. ### Attack Path 1. An upstream package account, release pipeline, or registry artifact is compromised, or a future release introduces malicious behavior. 2. A user installs the project dependencies using the documented commands. 3. The package manager resolves a newer, unreviewed version because no exact version or integrity constraint is enforced. 4. Package installation hooks or imported runtime code execute with the installing user's privileges. 5. The compromised dependency accesses files, credentials, or network resources available to that user. ### Impact Assessment A compromised dependency could execute arbitrary code with the privileges of the user performing installation or running the Skill. This could expose the LMS credentials file, course data, browser session information, and other user-accessible files. The documentation does not instruct users to install these dependencies as root. However ...[truncated 113 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
README.md:28
Finding

Plaintext credential files may initially be created with permissive permissions

Content
View full analysis
~/.config/hoseo_lms/credentials.json { "id": "HOSEO_STUDENT_ID", "pw": "HOSEO_PASSWORD" } EOF chmod 600 ~/.config/hoseo_lms/credentials.json ``` The Skill instructions use the same sequence: ```bash cat << 'EOF' > ~/.config/hoseo_lms/credentials.json { "id": "YOUR_STUDENT_ID", "pw": "YOUR_PASSWORD" } EOF ``` The permission change is documented later: ```bash chmod 600 ~/.config/hoseo_lms/credentials.json ``` ### Technical Analysis The file is created using the process's current umask and only restricted afterward. On systems with a permissive umask, the resulting file may initially be readable by group members or other local users. There is therefore a time-of-creation exposure window before `chmod 600` runs. The password remains stored in plaintext after permissions are corrected. Mode `0600` is an appropriate Unix permission for this design, but it should be applied atomically at creation time. The Windows instructions do not establish an equivalent restrictive ACL. ### Attack Path 1. A user follows the documented setup instructions on a multi-user system with a permissive umask. 2. The shell creates `credentials.json` with broader permissions than intended. 3. Before the subsequent `chmod` completes, a local process monitoring the directory opens and reads the file. 4. The process recovers the student's LMS identifier and password. 5. The attacker uses the credentials to access the victim's LMS account. The exploitation window may be short, and the attack requires local access and suitable directory traversal permissions. ### Impact Assessment Successful exploitation exposes the plaintext LMS credentials. The attacker may obtain the victim's LMS a ...[truncated 266 chars]
Remediation
View remediation
~/.config/hoseo_lms/credentials.json <<'EOF' { "id": "YOUR_STUDENT_ID", "pw": "YOUR_PASSWORD" } EOF ``` 2. Alternatively, create the file atomically with mode `0600` using a small setup utility. 3. Verify ownership and reject credential files that are group-readable, world-readable, symlinks, or owned by another user. 4. On Windows, apply an ACL limited to the current account instead of assuming default permissions are sufficient. 5. Prefer an operating-system credential manager over long-term plaintext password storage. 6. Avoid real password examples in documentation. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (44)

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README and metadata describe the skill as an LMS data aggregation/reporting tool, but the documented behavior explicitly includes automatically replaying unattended lectures. This is a materially different capability that can be used to falsify attendance or violate LMS terms, making the skill riskier than its stated purpose suggests.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The README directs users to store raw LMS credentials in a plaintext JSON file under the home directory. If the host is compromised, backups are exposed, or file permissions are misconfigured, an attacker could obtain valid institutional credentials and access the student's LMS account.

Content

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

bash
mkdir -p ~/.config/hoseo_lms

cat << 'EOF' > ~/.config/hoseo_lms/credentials.json
{
  "id": "HOSEO_STUDENT_ID",
  "pw": "HOSEO_PASSWORD"

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

Although the README applies restrictive permissions, it still normalizes long-term storage of a reusable LMS password in a local file. The core risk remains credential theft from malware, endpoint compromise, backups, or accidental disclosure.

Content

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

} EOF

chmod 600 ~/.config/hoseo_lms/credentials.json

text

---

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The Windows instructions likewise store the student's LMS ID and password in a plaintext credentials.json file. On shared or poorly secured systems, this can expose institutional credentials and enable unauthorized access to academic records or LMS actions.

Content

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

"id": "학번", "pw": "비밀번호" } "@ | Out-File -Encoding UTF8 "$env:USERPROFILE.config\hoseo_lms\credentials.json"

text

</details>

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Auto-attendance via Playwright is not necessary for simple data aggregation/reporting and expands the skill into active account automation. In this LMS context, that capability can be used to simulate course participation, exposing the user to account sanctions and creating clear abuse potential.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The manifest presents the skill as a data aggregation/reporting tool, but the documentation clearly includes automated LMS login and browser-driven lecture playback that can affect attendance/completion state. This mismatch is dangerous because it obscures materially different behavior from users, reviewers, and policy systems that may approve the skill under a less sensitive category.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest presents the skill as a data aggregation/reporting tool, but the documentation clearly includes automated LMS login and browser-driven lecture playback that can affect attendance/completion state. This mismatch is dangerous because it obscures materially different behavior from users, reviewers, and policy systems that may approve the skill under a less sensitive category.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The skill explicitly supports obtaining a student ID from a local credentials file, indicating direct access to stored authentication material. Access to plaintext credentials is highly sensitive because compromise of the host, logs, or mis-scoped agent actions can expose an LMS account.

Content

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

md
| Flag | Default | Type | Description |
|------|---------|------|-------------|
| `--id` | credentials.json | string | Student ID |
| `--pw` | credentials.json | string | Password |
| `--course` | all | string | Course name filter |
| `--limit-lectures` | 0 | int | Number of videos to play (0=all) |

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The password field defaults to a local credentials file, meaning the tool is designed to read stored plaintext secrets for authentication. This is dangerous because any broader-than-necessary file access, backup leakage, or user mishandling can disclose reusable account credentials.

Content

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

md
| Flag | Default | Type | Description |
|------|---------|------|-------------|
| `--id` | credentials.json | string | Student ID |
| `--pw` | credentials.json | string | Password |
| `--course` | all | string | Course name filter |
| `--limit-lectures` | 0 | int | Number of videos to play (0=all) |
| `--max-week` | 15 | int | Final week to scan |

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The setup instructions direct users to create a persistent credentials file, normalizing storage of reusable LMS credentials on disk. Persistent local secrets materially increase exposure to malware, accidental sharing, backups, and endpoint compromise.

Content

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

mkdir -p ~/.config/hoseo_lms

text

**Step 2: Create credentials.json using terminal**

#### Option A: Using cat (Linux/Mac)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This example writes the student ID and password directly into a plaintext JSON file under the user's home directory. Even with later permission guidance, the practice creates a sensitive credential artifact that may be indexed, backed up, or exposed by other local processes.

Content

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

Option A: Using cat (Linux/Mac)

bash
cat << 'EOF' > ~/.config/hoseo_lms/credentials.json
{
  "id": "YOUR_STUDENT_ID",
  "pw": "YOUR_PASSWORD"

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The example includes a realistic password value in documentation, reinforcing insecure copy-paste behavior and normalizing plaintext secret handling. Users may imitate this pattern and leave credentials exposed in shell transcripts or documentation artifacts.

Content

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

Example:

bash
cat << 'EOF' > ~/.config/hoseo_lms/credentials.json
{
  "id": "20231234",
  "pw": "mypassword123"

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

Using echo to write credentials to a file is especially risky because the full secret may be captured in shell history in addition to being stored on disk. This creates multiple disclosure channels for the same password.

Content

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

Option B: Using echo (Linux/Mac/Windows)

bash
echo '{"id":"YOUR_STUDENT_ID","pw":"YOUR_PASSWORD"}' > ~/.config/hoseo_lms/credentials.json

Example:

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This concrete echo example embeds a real-looking password directly in the command line, exposing it to shell history, process inspection, and screen recording. It is a strong instance of unsafe credential handling in documentation.

Content

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

Example:

bash
echo '{"id":"20231234","pw":"mypassword123"}' > ~/.config/hoseo_lms/credentials.json

Option C: Using PowerShell (Windows)

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The PowerShell example also stores reusable credentials in a plaintext file, creating persistent local exposure on Windows systems. While it may avoid shell history issues relative to some one-liners, it still establishes a sensitive credential artifact on disk.

Content

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

"id": "YOUR_STUDENT_ID", "pw": "YOUR_PASSWORD" } "@ | Out-File -Encoding UTF8 "$env:USERPROFILE.config\hoseo_lms\credentials.json"

text

Example:

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The example again includes a realistic password written to disk, which is unsafe and may be copied verbatim into insecure environments. Repetition of this pattern increases the likelihood of user credential exposure.

Content

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

"id": "20231234", "pw": "mypassword123" } "@ | Out-File -Encoding UTF8 "$env:USERPROFILE.config\hoseo_lms\credentials.json"

text

#### Option D: Manual creation with text editor (All OS)

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

Manual instructions to create a plaintext credentials.json file encourage persistent storage of account secrets without technical safeguards beyond discretionary permissions. This increases the attack surface for any local compromise or accidental sharing.

Content

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

Option D: Manual creation with text editor (All OS)

  1. Create ~/.config/hoseo_lms/ directory
  2. Create credentials.json file
  3. Enter content:
json
{

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

Although chmod 600 is protective, this line still confirms the existence of a persistent plaintext credentials file whose sensitivity must be managed. The underlying risk is the credential file itself, not the permission command.

Content

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

Step 3: Set secure permissions

bash
chmod 600 ~/.config/hoseo_lms/credentials.json

(Not required on Windows - file permissions handled by OS)

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements automated lecture playback and attendance completion behavior that is materially different from the declared skill purpose of LMS data aggregation/reporting. The code logs into the LMS, opens lecture popups, forces autoplay, and waits until videos complete, indicating intentional functionality for bypassing normal attendance participation expectations and concealing the skill’s true capability.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The code accesses a local credentials.json file to retrieve LMS credentials, implying plaintext credential storage and automated use of sensitive authentication material. In the context of a misrepresented auto-attendance tool, this is more dangerous because the credentials enable direct account access to an academic system and could be reused or exfiltrated by adjacent code changes.

Content

Scanner excerpt · src/auto_attend.py (reported line 516)May include surrounding context.

python
password = password or creds["pw"]
        except FileNotFoundError as e:
            error(str(e))
            error("Provide --id/--pw or create credentials.json")
            return 1

    with sync_playwright() as pw:

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The runtime flow explicitly launches a browser, logs into the LMS, enumerates courses, and processes lectures for unattended completion, which is not justified by a reporting-only tool. In context, this hidden capability increases risk because it can be used to fraudulently satisfy course attendance requirements and evade administrative controls.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The CLI help text explicitly instructs users to fall back to credentials.json for the student ID, reinforcing an insecure credential-storage pattern. While this line is documentation/help text rather than the credential read itself, it operationalizes unsafe handling of authentication data and encourages broader use of a sensitive local file.

Content

Scanner excerpt · src/auto_attend.py (reported line 569)May include surrounding context.

python
def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="Hoseo LMS Playwright auto-attend")
    parser.add_argument("--id", dest="user_id", default="", help="Student ID (falls back to credentials.json)")
    parser.add_argument("--pw", dest="password", default="", help="Password (falls back to credentials.json)")
    parser.add_argument("--course", default="", help="Course name keyword or course ID")
    parser.add_argument("--limit-lectures", type=int, default=0, help="Max lectures to watch (0=unlimited)")

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The CLI help text explicitly encourages using credentials.json for the password fallback, normalizing plaintext local password storage for LMS access. This increases the likelihood of unsafe secret handling and accidental disclosure through local compromise, backups, or repository mistakes.

Content

Scanner excerpt · src/auto_attend.py (reported line 570)May include surrounding context.

python
def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="Hoseo LMS Playwright auto-attend")
    parser.add_argument("--id", dest="user_id", default="", help="Student ID (falls back to credentials.json)")
    parser.add_argument("--pw", dest="password", default="", help="Password (falls back to credentials.json)")
    parser.add_argument("--course", default="", help="Course name keyword or course ID")
    parser.add_argument("--limit-lectures", type=int, default=0, help="Max lectures to watch (0=unlimited)")
    parser.add_argument("--max-week", type=int, default=15, help="Max week number to scan")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · src/hoseo_utils/constants.py (reported line 4)May include surrounding context.

python
BASE_URL = "https://learn.hoseo.ac.kr"
USER_AGENT = "Mozilla/5.0"

CREDENTIALS_PATH = "~/.config/hoseo_lms/credentials.json"
DATA_PATH = "~/.config/hoseo_lms/data.json"

LMS_PATHS = {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README instructs users to store LMS credentials and collect academic activity data, but it does not provide an explicit warning about handling sensitive personal and educational information. In the LMS context, this can lead users to persist credentials and student data without understanding privacy, account-security, or local compromise risks.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.