Back to skill

Security audit

Claw Store 1.3.3

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it should be reviewed because it stores persistent agent memory using wallet credentials while exposing too much local secret-bearing environment data to a Node dependency chain.

Review before installing. Use a dedicated Jackal wallet and API key, run it from a clean environment without unrelated cloud or repository tokens, avoid placing secrets in a parent .env, and do not store highly sensitive memory unless you accept cross-session retention. Dependencies should be installed and audited explicitly rather than during normal use, and the vulnerable/deprecated Node dependency tree should be upgraded before trusting this with valuable wallet-backed storage.

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)

T08 · Insecure Dependencies

Error
Location
jackal-memory/package-lock.json:42
Finding

Deprecated Cryptographic Dependencies May Place Wallet Private Keys at Risk

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
jackal-memory/client.py:367
Finding

Automatic Runtime Dependency Installation Executes Third-Party Lifecycle Scripts

Content
View full analysis
None: """Install node_modules next to jackal-client.js on first use.""" if not _JACKAL_CLIENT.exists(): print("[jackal-memory] jackal-client.js not found — skill installation may be incomplete.", file=sys.stderr) sys.exit(1) if not _NODE_MODULES.exists(): print("[jackal-memory] Installing Jackal dependencies (first run — takes ~30s)...", file=sys.stderr) r = subprocess.run( ["npm", "install", "--prefix", str(_SKILL_DIR)], capture_output=True, text=True, ) if r.returncode != 0: print(f"[jackal-memory] npm install failed:\n{r.stderr}", file=sys.stderr) sys.exit(1) print("[jackal-memory] Dependencies installed.", file=sys.stderr) ``` The locked dependency graph contains a package with an installation script: ```json "node_modules/@jackallabs/protobufjs": { "version": "7.4.0-patch.1", "resolved": "https://registry.npmjs.org/@jackallabs/protobufjs/-/protobufjs-7.4.0-patch.1.tgz", "integrity": "sha512-ACM190ahvbOaYuXwaHN+Hj6Yitfb0eFAfe1GkBuptE3c7KWW9K4ccGKZ39ww2AsYb5TBEvMWJyUMVFrP1m60KA==", "hasInstallScript": true, "license": "BSD-3-Clause" } ``` ### Technical Analysis When `node_modules` is absent, ordinary `save` or `load` operations automatically invoke `npm install`. NPM installation normally permits package lifecycle scripts, meaning third-party package code can execute with the same operating-system privileges as the Skill. The lockfile pins currently resolved artifacts with integrity hashes, which reduces—but does not eliminate—supply-chain risk. It does not sandbox l ...[truncated 1718 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
jackal-memory/client.py:387
Finding

Node Subprocess Inherits All Environment Secrets and Loads Additional Parent .env Data

Content
View full analysis
str: """Upload base64-encoded ciphertext to the user's own Jackal VFS. Returns CID.""" mnemonic = _jackal_mnemonic() if not mnemonic: print("[jackal-memory] No Jackal wallet found. Run: python client.py walletgen", file=sys.stderr) sys.exit(1) address = _mnemonic_to_jackal_address(mnemonic) env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address} r = subprocess.run( ["node", str(_JACKAL_CLIENT), "upload", key], input=data_b64, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, ) ``` Download path: ```python def _jackal_download(key: str) -> str: """Download ciphertext from the user's own Jackal VFS. Returns base64 ciphertext.""" mnemonic = _jackal_mnemonic() if not mnemonic: print("[jackal-memory] No Jackal wallet found.", file=sys.stderr) sys.exit(1) address = _mnemonic_to_jackal_address(mnemonic) safe_key = re.sub(r'[^a-zA-Z0-9._-]', '_', key) cid = f"Home/jackal-memory/{safe_key}" env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address} r = subprocess.run( ["node", str(_JACKAL_CLIENT), "download", cid], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, ) ``` The Node helper additionally loads arbitrary variables from a parent `.env` file: ```javascript const fs = require('fs'); const path = require('path'); const envPath = path.join(__dirname, '..', '.env'); if (fs.existsSync(envPath)) { for (const ...[truncated 2478 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
jackal-memory/client.py:51
Finding

Secret Files Are Created Before Restrictive Permissions Are Applied

Content
View full analysis
None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(value) os.chmod(path, 0o600) ``` This function stores both the AES encryption key and the wallet mnemonic: ```python _KEY_FILE = pathlib.Path.home() / ".config" / "jackal-memory" / "key" _WALLET_FILE = pathlib.Path.home() / ".config" / "jackal-memory" / "jackal-mnemonic" ``` ### Technical Analysis `Path.write_text()` creates or truncates the target file using permissions determined by the process umask. The code applies mode `0600` only after the write has completed. On systems with a permissive umask, the secret may initially be created with group-readable or world-readable permissions. There is therefore a time-of-check/time-of-use window in which another local process or user may open and read the file before `chmod()` restricts it. The separate `write_text()` and `chmod()` operations are also not atomic. Existing symbolic links or unexpected filesystem state are not explicitly rejected, increasing the risk when the configuration directory is writable or manipulable by another principal. ### Attack Path 1. The user invokes key or wallet generation. 2. `_write_secret_file()` creates the key or mnemonic file using default creation permissions. 3. Before `os.chmod(path, 0o600)` executes, a local attacker monitoring the directory opens the file. 4. The attacker reads the encryption key or wallet mnemonic. 5. The attacker uses the mnemonic to control wallet-backed storage or uses the AES key to decrypt memory ciphertext obtained from storage. This path requires local access and favorable filesystem permissions or timing, so it is less severe than direct remote secret disclosure. ### Impact Asses ...[truncated 398 chars]
Remediation
View remediation
None: path.parent.mkdir(parents=True, exist_ok=True, mode=0o700) flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL fd = os.open(path, flags, 0o600) try: with os.fdopen(fd, "w", encoding="utf-8") as handle: handle.write(value) handle.flush() os.fsync(handle.fileno()) except Exception: path.unlink(missing_ok=True) raise ``` 2. Set the configuration directory to mode `0700` and verify its ownership before writing. 3. Reject symbolic links and unexpected non-regular target files. 4. For safe replacement of an existing secret, write to a securely created temporary file in the same directory and use `os.replace()` after validation. 5. Add tests using a permissive umask to confirm that secret files are never observable with permissions broader than `0600`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (28)

Known Vulnerable Dependency: protobufjs==6.11.4 — 11 advisory(ies): CVE-2026-44294 (protobuf.js: Denial of service from crafted field names in generated code); CVE-2026-44293 (protobuf.js: Code injection through bytes field defaults in generated toObject c); CVE-2026-44289 (protobuf.js: Denial of service through unbounded protobuf recursion) +8 more

Critical
Category
Supply Chain
Confidence
96% confidence
Finding

protobufjs 6.11.4 is a significant transitive risk because the cited advisories include denial of service and possible code-generation/injection issues. This skill depends on protobuf-heavy blockchain/storage client libraries, so parsing attacker-influenced messages or schemas is part of the normal threat surface and increases the practical relevance of these issues.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: protobufjs==7.5.4 — 12 advisory(ies): CVE-2026-44294 (protobuf.js: Denial of service from crafted field names in generated code); CVE-2026-44293 (protobuf.js: Code injection through bytes field defaults in generated toObject c); CVE-2026-44289 (protobuf.js: Denial of service through unbounded protobuf recursion) +9 more

Critical
Category
Supply Chain
Confidence
96% confidence
Finding

protobufjs 7.5.4 is also flagged with multiple critical advisories, including denial-of-service and code-injection-related problems. Because the skill interfaces with decentralized storage and RPC/protobuf ecosystems, maliciously crafted protocol data could plausibly reach this library and threaten agent availability or potentially worse depending on feature usage.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
97% confidence
Finding

The code forwards the entire parent environment to a Node subprocess along with the wallet mnemonic, meaning any secrets present in the agent's environment become available to the external runtime and its dependencies. In this skill context, that is especially dangerous because the same file also auto-installs Node packages, creating a realistic path for dependency or helper compromise to harvest API keys, tokens, and wallet secrets.

Content

Scanner excerpt · jackal-memory/client.py (reported line 394)May include surrounding context.

python
file=sys.stderr)
        sys.exit(1)
    address = _mnemonic_to_jackal_address(mnemonic)
    env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "upload", key],

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
97% confidence
Finding

This second subprocess path has the same secret-exposure issue: all inherited environment variables plus the mnemonic are made available to the Node child process. Given the external JS helper and runtime dependency installation, this materially increases the blast radius of any compromise and can leak unrelated credentials from the hosting agent environment.

Content

Scanner excerpt · jackal-memory/client.py (reported line 432)May include surrounding context.

python
safe_key = re.sub(r'[^a-zA-Z0-9._-]', '_', key)
    cid = f"Home/jackal-memory/{safe_key}"

    env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "download", cid],

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

This code automatically loads secrets from a local .env file adjacent to the skill and populates process.env with them, including the wallet mnemonic used for decentralized storage operations. In an agent-skill context, this expands the trust boundary and makes it easier for the skill to consume sensitive credentials from disk without an explicit caller opt-in, which can lead to wallet compromise or unauthorized storage actions if the skill is invoked in an untrusted environment.

Content

Scanner excerpt · jackal-memory/jackal-client.js (reported line 48)May include surrounding context.

js
// Downloads bypass fetch entirely via nodeHttpGet (require('https')), which is
// the proven fix for SSL renegotiation issues on Windows.

// ── Load .env ─────────────────────────────────────────────────────────────────
const fs   = require('fs');
const path = require('path');
const envPath = path.join(__dirname, '..', '.env');

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The loop reads and parses every line of ../.env and imports values into runtime state, which is effectively credential ingestion from a file under the repository tree. In this skill, the loaded JACKAL_MNEMONIC grants control over the user's wallet-backed storage, so any unintended access path, repository leakage, or misuse of the skill can directly expose or abuse high-value credentials.

Content

Scanner excerpt · jackal-memory/jackal-client.js (reported line 51)May include surrounding context.

js
// ── Load .env ─────────────────────────────────────────────────────────────────
const fs   = require('fs');
const path = require('path');
const envPath = path.join(__dirname, '..', '.env');
if (fs.existsSync(envPath)) {
    for (const line of fs.readFileSync(envPath, 'utf8').split('\n')) {
        const m = line.match(/^\s*([\w]+)\s*=\s*(.*)\s*$/);

Known Vulnerable Dependency: axios==0.21.4 — 16 advisory(ies): CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF); CVE-2026-25639 (Axios is Vulnerable to Denial of Service via __proto__ Key in mergeConfig) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

This lockfile pins a transitive axios 0.21.4 dependency under @cosmjs/launchpad, and that version family is widely associated with multiple security advisories including SSRF/proxy handling and prototype-pollution-related issues. In an agent skill that connects to decentralized storage and remote services, vulnerable HTTP client behavior can increase exposure to request smuggling, header leakage, or server-side request abuse if attacker-controlled URLs or redirects are ever involved.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==7.5.10 — 1 advisory(ies): CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
95% confidence
Finding

The bundled ws 7.5.10 under @cosmjs/socket is an outdated WebSocket implementation with a cited memory exhaustion DoS risk. Because this skill relies on networked blockchain/storage communication, a malicious peer or endpoint could potentially exploit WebSocket parsing/resource handling weaknesses to degrade availability.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The top-level dependency tree includes axios 1.13.6 via @cosmjs/tendermint-rpc, and the finding indicates multiple unresolved advisories affecting that version. Since this skill performs remote RPC/storage operations, flaws in HTTP request processing, redirects, or proxy handling can directly affect confidentiality and integrity of outbound agent communications.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
90% confidence
Finding

form-data 4.0.5 is flagged for CRLF injection via unescaped multipart field names/filenames, which can enable request manipulation when untrusted values are included in multipart submissions. While this may not be the primary path of this skill, it is a real issue in an HTTP-capable dependency stack and becomes dangerous if user-controlled metadata is ever submitted upstream.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
97% confidence
Finding

The direct ws 8.19.0 dependency is flagged for memory disclosure and memory exhaustion DoS vulnerabilities. Since this skill explicitly depends on ws and likely uses persistent network connections for decentralized storage or chain communication, exploitation could expose process memory or make the service unavailable.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
99% confidence
Finding

The package explicitly depends on ws 8.19.0, which is flagged with advisories for uninitialized memory disclosure and memory exhaustion DoS. In a client-side signing/storage integration, websocket communication may be reachable from untrusted peers or services, so a vulnerable parser/handler could leak process memory or allow resource exhaustion of the agent runtime.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill requires broad capabilities—environment access, file read/write, network, and shell execution—but does not declare an explicit tool scope or allowed-tools policy. That makes the effective privilege boundary unclear and increases the chance an agent can invoke this memory skill with more authority than users expect, including reading local secrets, writing persistent files, and making outbound requests.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

text
   The mnemonic controls their on-chain storage. Losing it means losing sovereign access to stored files.

**Important:** Never ask the user to paste their API key, encryption key, or wallet mnemonic into chat. Always direct them to set it as an environment variable on their machine.

## Base URL

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

The skill explicitly instructs the agent to restore memory on startup and save memory at session end or on significant state changes, creating persistent cross-session storage of potentially sensitive user data. Even though content is described as client-side encrypted, persistent retention changes the security posture by increasing the consequences of accidental collection, over-retention, or saving regulated/personal data without granular consent.

Content

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

md
## Behaviour guidelines

- Load your identity/memory blob on startup before doing any work
- Write locally during the session as normal
- Call save at session end or on significant state changes
- Use descriptive keys: `identity`, `session-2026-02-26`, `project-jackal`
- Never log or expose `JACKAL_MEMORY_API_KEY` in output

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

A memory-storage client unexpectedly installs and executes external Node/npm tooling during operation, which exceeds the apparent scope of simple local encryption and remote storage. For agent skills, hidden runtime dependency bootstrapping is dangerous because it introduces supply-chain and arbitrary-code-execution exposure not obvious from the skill's stated purpose.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

Automatically running 'npm install' at runtime causes execution of third-party package install scripts and downloads code from the registry during normal skill use. In an agent context, this expands the trust boundary significantly and can lead to arbitrary code execution if dependencies or registry responses are compromised.

Content

Scanner excerpt · jackal-memory/client.py (reported line 376)May include surrounding context.

python
if not _NODE_MODULES.exists():
        print("[jackal-memory] Installing Jackal dependencies (first run — takes ~30s)...",
              file=sys.stderr)
        r = subprocess.run(
            ["npm", "install", "--prefix", str(_SKILL_DIR)],
            capture_output=True, text=True,
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · jackal-memory/client.py (reported line 396)May include surrounding context.

python
address = _mnemonic_to_jackal_address(mnemonic)
    env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "upload", key],
        input=data_b64, text=True,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,

Tainted flow: 'key' from os.environ.get (line 181, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · jackal-memory/client.py (reported line 396)May include surrounding context.

python
address = _mnemonic_to_jackal_address(mnemonic)
    env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "upload", key],
        input=data_b64, text=True,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · jackal-memory/client.py (reported line 434)May include surrounding context.

python
env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "download", cid],
        text=True,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,

Tainted flow: 'cid' from os.environ.get (line 517, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · jackal-memory/client.py (reported line 434)May include surrounding context.

python
env = {**os.environ, "JACKAL_MNEMONIC": mnemonic, "JACKAL_ADDRESS": address}

    r = subprocess.run(
        ["node", str(_JACKAL_CLIENT), "download", cid],
        text=True,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The wallet generation command prints the full mnemonic to stdout by default, which can expose the secret in terminal logs, agent transcripts, shell history capture, remote session recording, or orchestration logs. Because the mnemonic controls the wallet and storage ownership, disclosure enables full compromise of the user's Jackal account and data access.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

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

md
- **Data leaving your machine:** encrypted payloads + key metadata + your Jackal public address for provisioning
- **Data not leaving your machine:** plaintext memory content, encryption key, wallet mnemonic/private key
- **No runtime wordlist download:** BIP39 English wordlist is vendored locally in this skill package
- **Secret file permissions:** locally generated key/mnemonic files are written with `0600` permissions

- **Homepage:** https://obsideo.io
- **Source code:** https://github.com/Regan-Milne/jackal-memory

Known Vulnerable Dependency: @protobufjs/utf8==1.1.0 — 1 advisory(ies): CVE-2026-44288 (protobufjs has overlong UTF-8 decoding)

Low
Category
Supply Chain
Confidence
84% confidence
Finding

@protobufjs/utf8 1.1.0 is flagged for overlong UTF-8 decoding, which can matter when parsing untrusted serialized data. In this package-lock context it is only a low-severity transitive issue, but the skill does interact with remote data formats, so malformed input handling is still relevant.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: elliptic==6.6.1 — 1 advisory(ies): CVE-2025-14505 (Elliptic Uses a Cryptographic Primitive with a Risky Implementation)

Low
Category
Supply Chain
Confidence
80% confidence
Finding

elliptic 6.6.1 is flagged for use of a risky cryptographic implementation, and this concern is reinforced by deprecation notices elsewhere in the lockfile for cosmjs crypto packages. In a storage/memory skill that may handle keys or signatures, cryptographic weakness is security-relevant even if exploitability depends heavily on application usage patterns.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
jackal-memory/jackal-client.js:55