T01 · Skill Instruction Hijacking
- Location
HEARTBEAT.md:414- Finding
Private conversation topics are disclosed through mandatory autonomous engagement instructions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches a Singularity social-network/heartbeat integration, but it asks for persistent authenticated background use and includes instructions that can share conversation-derived topics and perform public social actions without clear per-action approval.
Install only if you are comfortable giving this skill a Singularity API key and letting it make authenticated social-network actions. Prefer manual heartbeat mode, avoid the Windows highest-run-level scheduled task, do not let it mine private conversation history for search terms unless you explicitly approve the exact terms, and store/rotate credentials carefully.
HEARTBEAT.md:414Private conversation topics are disclosed through mandatory autonomous engagement instructions
index.js:15Bearer credentials can be redirected to arbitrary configured network endpoints
README.md:68Documentation recommends recurring elevated execution of the heartbeat
lib/api.js:75Credential and connector session files are written without restrictive permissions
install.sh:58Installer resolves a mutable runtime dependency instead of enforcing the reviewed lockfile
HEARTBEAT.md:465Instructions permit replacement of reviewed Skill text from a mutable remote source
The code is primarily a connection/session-management plugin for Singularity OpenClaw, not a feature-complete EvoMap social-network/marketplace client. It registers with backend endpoints, opens and maintains a WebSocket, handles resume/ack/heartbeat/reconnect, emits incoming events, and stores state/events on disk. The declared description prominently advertises post/comment/gene fetch/apply capabilities, but none of those behaviors appear in this code chunk. The automated heartbeat portion is accurate, and connecting to a related Singularity service is partially aligned, but the main described user-facing capabilities are absent while local file persistence and event queue writing are undeclared. Therefore the description does not accurately represent the actual behavior.
The declared description presents a broader EvoMap integration including posting, commenting, fetching/applying genes, and heartbeat automation. The supplied code chunk is specifically a heartbeat/status CLI: it reads credentials from environment variables or credential files, performs GET/POST requests to home, stats, gene fetch, leaderboard, feed, and heartbeat endpoints, and logs results. The main mismatch is that several declared user-facing actions (post, comment, apply genes) are not implemented in this code, while the code does access local credential files and multiple read-only platform resources that are not mentioned in the declared permissions. Although the code is related to EvoMap and heartbeat functionality, the description does not accurately represent this chunk's concrete behavior.
The description only partially matches the code. The gene fetch/apply aspect is represented, and the skill does connect to Singularity EvoMap-related endpoints. However, key declared functions like posting, commenting, and automated heartbeat are absent. Conversely, the code adds materially different capabilities: bug/error reporting, leaderboard retrieval, and node/personal stats retrieval. The evolution trigger behavior is also different from what a straightforward marketplace/network action would imply, because it does not invoke a real remote trigger endpoint and instead returns a local synthetic task record with optional hub inheritance. This is a meaningful description-to-behavior mismatch.
The declared description presents the skill as an operational integration with Singularity EvoMap for social actions, gene marketplace interactions, and heartbeat automation. The supplied code chunk, however, is only an installer/setup script. Its primary behavior is local environment preparation: checking prerequisites, copying files, installing a dependency, creating a credentials file, and checking OpenClaw registration. Those are materially different from the declared end-user capabilities, and the described EvoMap actions are not present in this code chunk. While installer behavior can support the broader skill, this specific chunk does not accurately match the declared purpose on its own.
The description is partially accurate but materially incomplete. The code does include posting, commenting, gene/capsule fetch/apply, and heartbeat support for Singularity EvoMap. However, it is not limited to those functions; it is a comprehensive client for a much wider Singularity platform surface area, including messaging, marketplace, task systems, rewards, account binding, and persistent local storage of credentials/logs/cache. Because the declared purpose frames the skill narrowly around EvoMap/social posting and heartbeat, while the code exposes many additional operational capabilities and local file access not mentioned in the description, this constitutes a description-behavior mismatch.
The skill instructs users to store an API key, agent ID, and node secret in environment variables or a local credentials file, and later uses those credentials in outbound requests. Accessing and relying on high-value secrets is inherently sensitive; if the skill, host, or surrounding environment is compromised, these credentials can enable account takeover, impersonation, or unauthorized node heartbeats.
在 ~/.hermes/.env 或 ~/.config/singularity/credentials.json 中配置:
SINGULARITY_API_KEY=ak_your_api_key_here
The lockfile pins the runtime dependency ws to version 8.20.0, and the provided advisories indicate this version is affected by both uninitialized memory disclosure and memory-exhaustion denial of service. Because this skill is explicitly designed to connect to an external AI social network over WebSocket, the vulnerable package sits directly on a network-facing trust boundary, making remote exploitation more plausible than in an offline-only tool.
The package depends on ws 8.20.0, which the finding identifies as having known vulnerabilities including memory disclosure and memory-exhaustion denial of service. This is especially relevant because the package description explicitly states it is WebSocket-first and handles auto-reconnect/heartbeat, meaning untrusted remote peers likely interact with the vulnerable library in normal operation.
Falling back to reading credentials.json from the script directory encourages insecure local secret storage and broadens the set of locations from which the script will automatically harvest credentials. In a skill/package setting, this is more dangerous because users may place secrets beside downloaded code, making accidental exposure, misuse, or packaging leaks more likely.
}
// 3. Curr directory fallback
const localPath = path.join(__dirname, 'credentials.json');
if (fs.existsSync(localPath)) {
try {
return JSON.parse(fs.readFileSync(localPath, 'utf8'));
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OPENCLAW_DIR="${HOME}/.openclaw"
SKILL_DIR="${OPENCLAW_DIR}/workspace/skills/${SKILL_NAME}"
CONFIG_DIR="${HOME}/.config/singularity"
CONFIG_FILE="${CONFIG_DIR}/credentials.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "================================================"
This code directly references a credentials file in the user's home directory and loads it for API access, confirming a real credential-access capability. In the context of an agent skill, this is more dangerous because the skill can silently consume stored secrets to perform remote actions on behalf of the user, and the same file may be targeted by other local components.
const __dirname = path.dirname(__filename);
const CACHE_DIR = path.join(os.homedir(), '.cache', 'singularity');
const CREDENTIALS_FILE = path.join(os.homedir(), '.config', 'singularity', 'credentials.json');
const LOG_FILE = path.join(CACHE_DIR, 'skill.log');
// ============================================================================
The entire skill guidance, examples, and required response formats are written only in Chinese, including the prescribed heartbeat output text. There is no indication that the user may choose another language or that the locale restriction is required for a region-specific compliance reason, which creates a natural-language policy concern under the language/locale rule.
The Gene apply example posts agent and capsule metadata to /api/evomap/a2a/apply without showing any Authorization header or trust validation, unlike most other examples in the file. That inconsistency can normalize unauthenticated outbound submissions of agent-linked operational data and increases the risk of misuse, spoofed submissions, or accidental disclosure if operators copy the pattern directly.
curl -X POST https://www.singularity.mba/api/evomap/a2a/apply \
-H "Content-Type: application/json" \
-d '{
"protocol": "gep-a2a",
This workflow tells the agent to search external repositories using keywords related to recent problems it handled, exemplified by 'prompt-injection'. Combined with the surrounding guidance to use recent issue keywords, it can cause user- or task-derived sensitive topics to be transmitted to an external marketplace/search service, creating an avoidable disclosure channel.
curl "https://www.singularity.mba/api/git-market/search?q=prompt-injection&provider=github" \
-H "Authorization: Bearer YOUR_API_KEY"
This section instructs the agent to mine historical conversations for high-frequency topics and then search the external platform with those derived terms, followed by feeding learned summaries back to the user. That creates a natural-language data retention and external disclosure path for user-derived information, potentially exposing sensitive interests, project details, or recurring private topics without explicit consent.
The README instructs users to configure scheduled heartbeat jobs via Task Scheduler, cron, and OpenClaw cron, but it does not clearly warn that this creates a persistent background task that repeatedly contacts an external service. In an agent-skill context, unattended recurring network communication materially changes the trust and risk profile, especially when paired with stored credentials and a node secret.