Back to skill

Security audit

MAL-Updater

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for MyAnimeList syncing, but it handles long-lived account tokens and unattended actions with a few concrete scoping weaknesses users should review before installing.

Install only if you are comfortable giving the skill local access to MAL, Crunchyroll, and HIDIVE credentials and allowing an optional user-level background daemon to sync on your behalf. Use default profile names, avoid passing untrusted --profile values, keep auto-remediation disabled unless you have reviewed the exact maintenance commands, and review service behavior before enabling unattended operation.

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

T09 · Insecure Skill Coding Practices

Warning
Location
src/mal_updater/crunchyroll_auth.py:72
Finding

Unsanitized Provider Profile Allows Token and State Path Traversal

Content
View full analysis
CrunchyrollStatePaths: root = config.state_dir / "crunchyroll" / profile return CrunchyrollStatePaths( root=root, refresh_token_path=root / "refresh_token.txt", device_id_path=root / "device_id.txt", session_state_path=root / "session.json", sync_boundary_path=root / "sync_boundary.json", ) ``` ```python def resolve_hidive_state_paths(config: AppConfig, profile: str = "default") -> HidiveStatePaths: root = config.state_dir / "hidive" / profile return HidiveStatePaths( root=root, access_token_path=root / "authorisation_token.txt", refresh_token_path=root / "refresh_token.txt", session_state_path=root / "session.json", sync_boundary_path=root / "sync_boundary.json", ) ``` The `profile` value is exposed through provider CLI `--profile` arguments and is used directly as a filesystem path component. ### Technical Analysis Neither provider validates that `profile` is a simple profile identifier. A value containing `..` can escape the intended provider state directory. An absolute path is more severe because `pathlib` discards the preceding path components when joining it, making the absolute profile path the effective root. Authentication and snapshot operations subsequently create this directory and write fixed-name files beneath it. These files include provider refresh tokens, HIDIVE access tokens, device identifiers, session metadata, and synchronization boundaries. Although secret-writing functions apply mode `0600`, that protection does not restore containment. A token can still be placed in an unintended directory ...[truncated 1527 chars]
Remediation
View remediation
str: if profile in {".", ".."} or not PROFILE_RE.fullmatch(profile): raise ValueError("Invalid provider profile name") return profile ``` 2. Explicitly reject: - Absolute paths. - `/` and `\` path separators. - `.` and `..`. - Empty names. - Control characters and excessively long values. 3. Enforce path containment after resolution: ```python provider_root = (config.state_dir / "crunchyroll").resolve() root = (provider_root / validate_profile(profile)).resolve() if not root.is_relative_to(provider_root): raise ValueError("Provider profile escapes the state directory") ``` 4. Apply the same centralized validation to both Crunchyroll and HIDIVE instead of implementing provider-specific checks. 5. Add regression tests covering: - `../../escape` - `..` - Absolute paths - Embedded separators - Valid identifiers such as `default`, `family-1`, and `profile_2` 6. Where feasible, use directory file descriptors or equivalent safe-open patterns to reduce symlink-based path redirection risks. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
src/mal_updater/auth.py:49
Finding

OAuth Callback Listener Is Exposed on All Interfaces and Can Be Remotely Terminated

Content
View full analysis
MAL auth failed

State mismatch. Return to the terminal.

") self.server.done.set() return ``` ### Technical Analysis The OAuth redirect URI uses `127.0.0.1`, but the callback server binds to `0.0.0.0` by default. Consequently, port `8765` may accept traffic through every available IPv4 network interface rather than only through loopback. OAuth state validation correctly prevents an attacker from substituting an authorization code without knowing the generated state. However, the handler treats the first callback with an invalid state as a terminal error and signals the main authentication flow to stop. Therefore, any party that can reach the listening port can terminate the one-shot flow without knowing the state value. The vulnerability affects availability rather than OAuth token confidentiality or integrity. ### Attack Path 1. A user starts `mal-auth-login`, which opens the callback server on `0.0.0.0:8765`. 2. An attacker on a network capable of reaching the ho ...[truncated 998 chars]
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (403)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description describes a substantial operational skill for managing and troubleshooting MAL-Updater with provider integrations and system/service features. The supplied code chunk only adjusts Python's module search path, likely as test scaffolding in conftest.py. That behavior is materially different from the declared primary purpose and does not implement or expose the described capabilities. This is therefore a clear description/behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a full MAL-Updater operational skill with provider integrations and operational features. The supplied code chunk does not implement any of those behaviors. It only adjusts Python's module search path at interpreter startup by inserting the repository root and src directory into sys.path. While this could be a supporting bootstrap detail, the chunk itself does not reflect the declared primary purpose and instead performs a narrow environment setup function unrelated to the advertised end-user capabilities. Therefore this chunk is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk is specifically a MAL API client module. It talks only to MyAnimeList endpoints, manages OAuth tokens, performs anime search/detail lookups, fetches the current user, updates list status, and records request telemetry. While 'guarded auth' is partially supported via OAuth/PKCE and token handling, the broader declared description claims a multi-provider sync/recommendation/operations skill for OpenClaw hosts with Crunchyroll and HIDIVE support, review triage, health checks, bootstrap auditing, and systemd daemon support. None of those broader host-management or provider-integration capabilities appear in this code. This is therefore a description-behavior mismatch: the actual code is a narrow MAL client component rather than the broad multi-provider operational skill described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes a substantial operational skill for installing, auditing, operating, or troubleshooting MAL-Updater. The actual code chunk is only a minimal tests/init.py file containing a package docstring for test fixtures/helpers. This is materially different from the declared purpose and shows none of the claimed capabilities. While this may be a harmless supporting file within a larger project, evaluating this chunk alone, the description does not accurately represent what the supplied code actually does.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script explicitly treats recommended command arguments containing a slash or ending in .sh as direct executable paths and passes them to subprocess.run(). That means health-check output can cause arbitrary filesystem-resident programs or scripts to be executed, which is a strong command execution primitive if an attacker can influence the recommendation payload or place a script at a predictable path.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

These lines execute the selected remediation command with subprocess.run(check=True) based on values parsed from the health-check JSON, without any interactive confirmation gate. In the context of an ops skill that may run unattended under systemd, this makes the issue more dangerous because compromised recommendations can trigger immediate action in an automation context.

Content

No source excerpt is available for this finding.

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/mal_updater/cli.py (reported line 1400)May include surrounding context.

python
):
        warnings.append({"code": "missing_hidive_state", "detail": "HIDIVE authorisation token or refresh token is missing"})
    if not secrets.client_id or not secrets.access_token or not secrets.refresh_token:
        warnings.append({"code": "missing_mal_auth_material", "detail": "MAL client id/access token/refresh token are not all present"})
    missing_automation_units = automation_installation.get("missing_units") if isinstance(automation_installation, dict) else None
    outdated_automation_units = automation_installation.get("outdated_units") if isinstance(automation_installation, dict) else None
    disabled_automation_services = automation_installation.get("disabled_services") if isinstance(automation_installation, dict) else None

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/mal_updater/cli.py (reported line 4109)May include surrounding context.

python
):
        warnings.append({"code": "missing_hidive_state", "detail": "HIDIVE authorisation token or refresh token is missing"})
    if not secrets.client_id or not secrets.access_token or not secrets.refresh_token:
        warnings.append({"code": "missing_mal_auth_material", "detail": "MAL client id/access token/refresh token are not all present"})
    missing_automation_units = automation_installation.get("missing_units") if isinstance(automation_installation, dict) else None
    outdated_automation_units = automation_installation.get("outdated_units") if isinstance(automation_installation, dict) else None
    disabled_automation_services = automation_installation.get("disabled_services") if isinstance(automation_installation, dict) else None

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/mal_updater/cli.py (reported line 4111)May include surrounding context.

python
):
        warnings.append({"code": "missing_hidive_state", "detail": "HIDIVE authorisation token or refresh token is missing"})
    if not secrets.client_id or not secrets.access_token or not secrets.refresh_token:
        warnings.append({"code": "missing_mal_auth_material", "detail": "MAL client id/access token/refresh token are not all present"})
    missing_automation_units = automation_installation.get("missing_units") if isinstance(automation_installation, dict) else None
    outdated_automation_units = automation_installation.get("outdated_units") if isinstance(automation_installation, dict) else None
    disabled_automation_services = automation_installation.get("disabled_services") if isinstance(automation_installation, dict) else None

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Printing the PKCE code verifier to stdout exposes a live authentication secret to anyone with access to terminal output, shell history capture, logging sinks, or remote session transcripts. Because this value is used to redeem the OAuth authorization code, its disclosure can directly compromise the OAuth flow.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

After OAuth succeeds, the CLI prints the exact path where the persisted access token was stored, and likewise for the refresh token. While it does not expose token values, disclosing token storage locations can aid local attackers and creates unnecessary sensitive metadata leakage into logs and operator transcripts.

Content

Scanner excerpt · src/mal_updater/cli.py (reported line 1778)May include surrounding context.

python
return 1

    print()
    print(f"Persisted access token to {persisted.access_token_path}")
    if token.refresh_token:
        print(f"Persisted refresh token to {persisted.refresh_token_path}")
    else:

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The token refresh command reveals where refreshed access and refresh tokens are stored. This unnecessarily advertises credential storage locations and can expose sensitive filesystem details through logs or copied command output.

Content

Scanner excerpt · src/mal_updater/cli.py (reported line 1809)May include surrounding context.

python
print(str(exc), file=sys.stderr)
        return 1

    print(f"Persisted access token to {persisted.access_token_path}")
    if token.refresh_token:
        print(f"Persisted refresh token to {persisted.refresh_token_path}")

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 · references/MAL_OAUTH.md (reported line 35)May include surrounding context.

md
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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/mal_updater/config.py (reported line 29)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_auth.py (reported line 56)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_auth.py (reported line 71)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_auth_config.py (reported line 150)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 54)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 119)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 190)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 289)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 368)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 470)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 547)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

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 · tests/test_mapping_sync.py (reported line 612)May include surrounding context.

python
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_SECONDS = 22.5
DEFAULT_CRUNCHYROLL_REQUEST_SPACING_JITTER_SECONDS = 7.5
DEFAULT_MAL_CLIENT_ID_FILE = "mal_client_id.txt"
DEFAULT_MAL_CLIENT_SECRET_FILE = "mal_client_secret.txt"
DEFAULT_MAL_ACCESS_TOKEN_FILE = "mal_access_token.txt"
DEFAULT_MAL_REFRESH_TOKEN_FILE = "mal_refresh_token.txt"
DEFAULT_DB_FILE = "mal_updater.sqlite3"

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/hidive-provider-recon.md:39

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/mal_updater/cli.py:1788

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/mal_updater/crunchyroll_auth.py:24

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/mal_updater/crunchyroll_snapshot.py:124

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/mal_updater/hidive_auth.py:21

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
tests/test_crunchyroll_snapshot.py:61