T09 · Insecure Skill Coding Practices
- Location
lib/config.mjs:102- Finding
Credential-bearing settings are written without restrictive file permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its stated game-autoplay purpose, but it can spend live account game balance, installs mutable dependency code, and handles Telegram secrets too loosely.
Review this carefully before installing. Use staging first, set conservative balance limits, avoid storing Telegram bot tokens in the settings file, and treat Telegram logging as sharing gameplay/status data with Telegram and any chat members. Installation should ideally pin snake-rodeo-agents to a reviewed commit or release.
lib/config.mjs:102Credential-bearing settings are written without restrictive file permissions
snake.mjs:172Configuration command discloses the Telegram bot token in plaintext
package.json:14Core runtime dependency is fetched from an unpinned GitHub branch
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
achedToken = null;
/**
* Send a message to Telegram
* Token resolution: TELEGRAM_BOT_TOKEN env var → settings.telegramBotToken → null
*/
export async function sendTelegram(text, chatId = null) {
const settings = loadSettings();
chatId = chatId || settings.telegramChatId;
if (!chatId) return false;
if (!settings.logToTelegram) return false;
if (!cachedToken) {
cachedToken = process.env.TELEGRAM_BOT_TOKEN || settings.telegramBotToken || null;
}
if (!cachedToken) {
return false;
}
try {
const res = await fetch(`https://api.telegram.org/bot${cachedToken}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text,
parse_mode: 'HTML',
}),
});
return res.ok;
} catch {
return false;
}
}
export function formatStatus(state, settings) {
const lines = [
`🐍 Snake Daemon Status`,
`├─ Strategy: ${settings.strateg
The skill automates voting on a live server using the user's authenticated account and in-game balance, but the description does not clearly warn that running it can autonomously spend funds. In this context, omission of that warning is dangerous because users may enable a persistent daemon without understanding that it will place bids continuously and consume balance on their behalf.
Telegram logging sends game events to an external service and potentially to a group chat, but the documentation does not warn users about the privacy implications. In a daemon that may log gameplay activity, account-linked events, and operational status, this omission can lead to unintended disclosure of behavioral or account-related information to third parties.
This code loads an authentication token and sends it in the Authorization header for backend requests, which is a safety-relevant network operation involving credentials. While the file has internal comments describing behavior, it lacks any user-facing prompt, log, or warning that authenticated requests will be made with locally sourced credentials.
The header comment says config is loaded from CLI arguments, environment variables, config file, and defaults in that precedence order. In this file, settings are only loaded from the JSON config file and defaults, with CLI options merged separately and only a single backend URL override read from the environment; there is no general environment-variable config loading path.
saveSettings writes arbitrary non-default settings, including fields such as telegramBotToken, into ~/.config/snake-rodeo/settings.json without any permission hardening, secret segregation, or warning. In a daemon that authenticates to external services and supports messaging integrations, persisting secrets in a general config file increases the chance of credential exposure through local reads, backups, logs, or accidental sharing.
The manifest describes an autoplay daemon for connecting to the game server, authenticating, and voting with AI strategies. This file invokes a shell command (sleep) via execSync, which is an OS-level capability not clearly justified by that stated game-playing purpose and exceeds what would normally be needed for server interaction or strategy execution.
The manifest scopes the skill to playing Snake Rodeo, simulations, and custom strategies, but this code launches system tail processes and executes shell commands to inspect logs. OS utility execution is not an obvious requirement of gameplay automation and represents an additional capability outside the described purpose.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
try {
const res = await fetch(`https://api.telegram.org/bot${cachedToken}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
The function sends the provided message text and chat ID to the Telegram API via an HTTP POST request, which transmits potentially sensitive runtime or user-related information off-system. While the file comments describe Telegram logging technically, there is no user-facing warning, confirmation, or disclosure in the code around this external data transmission.
When a user runs snake telegram <chat_id>, the CLI immediately transmits a test message to Telegram, an external third-party service, without an explicit warning that data is being sent off-host. Although the payload here is only a fixed test string, the behavior can surprise users and establishes an outbound channel to a configured chat, which is a privacy/transparency issue rather than a direct code-execution flaw.
The documentation says to run snake auth login to set up auth, but the only documented commands in this skill use node snake.mjs ... and no auth subcommand appears in the command list. This creates an intent/documentation contradiction about how authentication is actually performed.
Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration