AI Security Review
scanned 2h ago · by lpm-firewall-aiThe CLI is an explicitly invoked cryptocurrency-payment tool. User commands can sign messages, contact the RAIL20 API/RPCs, and submit transfers or contract calls; no install-time or passive attack behavior is present.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs login, deposit, send, swap, bridge, recover, balance, assets, or latest.
Impact
Users intentionally authorize blockchain operations; no confirmed unconsented credential exfiltration, persistence, or wallet-draining path is established by the packaged source.
Mechanism
Explicit wallet signing, API/RPC requests, and on-chain transaction submission.
Rationale
The scanner's wallet-transfer signal reflects this package's stated, user-invoked payment functionality. Source inspection found no lifecycle execution or concrete stealth/exfiltration chain, so the risky primitives are package-aligned rather than malicious.
Evidence
package.jsonbin/rail20.jsREADME.md~/.rail20/wallet.json~/.rail20/config.json
Network endpoints4
api.rail20.orgmainnet.base.orgrpc.mainnet.chain.robinhood.comregistry.npmjs.org/@rail20/cli/latest
Decision evidence
public snapshotAI called this Clean at 91.0% confidence as Benign with medium false-positive risk.
Evidence for block
- bin/rail20.js: deposit/swap accept API-prepared transaction data and broadcast only after explicit CLI commands.
- bin/rail20.js: wallet keys are used for user-requested on-chain deposits, sends, swaps, bridges, and recovery.
Evidence against
- package.json has no preinstall, install, or postinstall lifecycle hook.
- bin/rail20.js dispatches behavior only from explicit process.argv commands; import/install does not perform wallet or network actions.
- bin/rail20.js stores an interactively supplied key locally in ~/.rail20 with mode 0600 and does not post the key to its API.
- bin/rail20.js sends encrypted ephemeral burner keys to the registry; decryption occurs locally from a user signature.
- No child-process execution, eval/vm, dynamic payload loading, broad filesystem harvesting, or AI-agent configuration writes were found.
Behavioral surface
CryptoEnvironmentVarsFilesystemNetwork
HighEntropyStringsUrlStrings
Source & flagged code
2 flagged · loading sourcebin/rail20.jsView file
2/**
L3: * rail20 CLI - private payments for onchain agents.
L4: *
...
L21: // === constants ===
L22: const API = process.env.RAIL20_API || 'https://api.rail20.org'
L23: const SIGN_MESSAGE =
...
L26: 'No transaction will be sent.'
L27: const CONFIG_DIR = path.join(os.homedir(), '.rail20')
L28: const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json') // cached RAIL20 sig
...
L37: function color(text, col) {
L38: return process.stdout.isTTY ? `${col}${text}${c.reset}` : text
L39: }
Critical
Wallet Drain
Source uses private key material to transfer cryptocurrency funds.
bin/rail20.jsView on unpkg · L22Trigger-reachable chain: manifest.bin -> bin/rail20.js
L2: /**
L3: * rail20 CLI - private payments for onchain agents.
L4: *
...
L21: // === constants ===
L22: const API = process.env.RAIL20_API || 'https://api.rail20.org'
L23: const SIGN_MESSAGE =
...
L26: 'No transaction will be sent.'
L27: const CONFIG_DIR = path.join(os.homedir(), '.rail20')
L28: const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json') // cached RAIL20 sig
...
L37: function color(text, col) {
L38: return process.stdout.isTTY ? `${col}${text}${c.reset}` : text
L39: }
Critical
Trigger Reachable Dangerous Capability
A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.
bin/rail20.jsView on unpkg · L2Findings
2 Critical3 Medium3 Low
CriticalWallet Drainbin/rail20.js
CriticalTrigger Reachable Dangerous Capabilitybin/rail20.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings