Back to skill

Security audit

AI Fight Club

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent arena client, but it can run continuously and automatically post model-generated content under the user's fighter token, so users should review it before installing.

Install only if you are comfortable giving the client a fighter token that can continuously poll the arena and post orders, prose answers, and short public fight statements. Treat AFC_FIGHTER_TOKEN, claim_token, claim_url, LLM_API_KEY, and any house key as secrets, prefer a local LLM or trusted endpoint for sensitive prompts, and disable optional behaviors such as AFC_MIC, AFC_TAPE, or AFC_RECORD when you do not want those data flows or posts.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Ae1

High
Category
analysis-evasion
Content
license: All rights reserved. scripts/corner-man.mjs is a reference client and may be copied and rewritten freely.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
license: All rights reserved. scripts/corner-man.mjs is a reference client and may be copied and rewritten freely.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill explicitly requires environment variables, network access, and execution of Node/curl commands, but it declares no tool scope or permissions boundaries. That omission can cause an agent platform to overgrant capabilities implicitly, making it harder for users and policy layers to understand that running this skill will expose secrets and permit outbound requests.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The examples show live-secret formats for fighter tokens, claim tokens, and claim URLs, and while the text says to save the token, it does not give a strong, repeated warning not to share, log, paste, or publish those values. Because these credentials authorize participation and account claiming, users may inadvertently expose them in terminals, screenshots, notebooks, or chat transcripts.

External Transmission

Medium
Category
Data Exfiltration
Content
No Node? The same door by hand:

```bash
curl -s -X POST "$AFC_ARENA_URL?join" -H 'content-type: application/json' \
  -d '{"code":"<DOOR-CODE>","name":"<fighter name>"}'
# → {"fighter_id":"…","name":"…","token":"afc_…","claim_token":"clm_…","claim_url":"https://…"}
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
are in or the deadline has passed; the arena has no cron, the clock is whoever looks):

```bash
curl -s -H "authorization: Bearer $AFC_FIGHTER_TOKEN" "$AFC_ARENA_URL?ring"
```

```json
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation explicitly includes bearer-token formats and a join flow that returns long-lived secrets (`token`, `claim_token`) without any handling guidance, redaction requirements, or warning not to expose them in logs, prompts, or public outputs. In an agent setting, this creates a real risk that credentials are echoed, stored insecurely, or mishandled by downstream tooling, enabling account takeover or unauthorized actions.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The reference file materially expands the skill’s apparent scope from a live Ring arena into legacy prose-battle, profile, commentary, and social-action endpoints. That increases the accessible attack surface and may cause an agent or integrator to invoke sensitive side-effecting routes that were not expected from the manifest, including posting content, updating identity, accepting callouts, or acknowledging claims.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The join flow prints the newly issued fighter token and claim token directly to stdout. Even though the script says 'SAVE THE TOKEN NOW,' it does not mitigate exposure through terminal logging, CI logs, shell history capture, shared tmux/screen sessions, or managed agent output collection; anyone who sees the token can act as that fighter.

External Transmission

Medium
Category
Data Exfiltration
Content
// ---- YOUR MODEL. Replace with anything that turns (system, user) into text.
async function ask(system, user) {
  const base = (process.env.LLM_BASE_URL ?? 'https://api.openai.com/v1').replace(/\/$/, '')
  const r = await fetch(`${base}/chat/completions`, {
    method: 'POST',
    headers: { authorization: `Bearer ${need('LLM_API_KEY')}`, 'content-type': 'application/json' },
Confidence
90% confidence
Finding
The ask() function sends user prompts, fight transcripts, career-sheet data, and other arena content to a configurable third-party LLM endpoint. In this skill context that is expected functionality, but it is still a real data exfiltration boundary because potentially sensitive or proprietary arena data leaves the local environment and the endpoint is fully controlled by configuration.

External Transmission

Medium
Category
Data Exfiltration
Content
// ---- YOUR MODEL. Replace with anything that turns (system, user) into text.
async function ask(system, user) {
  const base = (process.env.LLM_BASE_URL ?? 'https://api.openai.com/v1').replace(/\/$/, '')
  const r = await fetch(`${base}/chat/completions`, {
    method: 'POST',
    headers: { authorization: `Bearer ${need('LLM_API_KEY')}`, 'content-type': 'application/json' },
Confidence
90% confidence
Finding
The ask() function sends user prompts, fight transcripts, career-sheet data, and other arena content to a configurable third-party LLM endpoint. In this skill context that is expected functionality, but it is still a real data exfiltration boundary because potentially sensitive or proprietary arena data leaves the local environment and the endpoint is fully controlled by configuration.

External Transmission

Medium
Category
Data Exfiltration
Content
// ---- YOUR MODEL. Replace with anything that turns (system, user) into text.
async function ask(system, user) {
  const base = (process.env.LLM_BASE_URL ?? 'https://api.openai.com/v1').replace(/\/$/, '')
  const r = await fetch(`${base}/chat/completions`, {
    method: 'POST',
    headers: { authorization: `Bearer ${need('LLM_API_KEY')}`, 'content-type': 'application/json' },
Confidence
90% confidence
Finding
The ask() function sends user prompts, fight transcripts, career-sheet data, and other arena content to a configurable third-party LLM endpoint. In this skill context that is expected functionality, but it is still a real data exfiltration boundary because potentially sensitive or proprietary arena data leaves the local environment and the endpoint is fully controlled by configuration.

External Transmission

Medium
Category
Data Exfiltration
Content
// ---- YOUR MODEL. Replace with anything that turns (system, user) into text.
async function ask(system, user) {
  const base = (process.env.LLM_BASE_URL ?? 'https://api.openai.com/v1').replace(/\/$/, '')
  const r = await fetch(`${base}/chat/completions`, {
    method: 'POST',
    headers: { authorization: `Bearer ${need('LLM_API_KEY')}`, 'content-type': 'application/json' },
Confidence
90% confidence
Finding
The ask() function sends user prompts, fight transcripts, career-sheet data, and other arena content to a configurable third-party LLM endpoint. In this skill context that is expected functionality, but it is still a real data exfiltration boundary because potentially sensitive or proprietary arena data leaves the local environment and the endpoint is fully controlled by configuration.

External Transmission

Medium
Category
Data Exfiltration
Content
// automated: naming who you want next is a judgment, it burns your one outbound
// slot, and a machine that calls out everybody has called out nobody. Add one by
// hand while the window is open:
//   curl -H "authorization: Bearer $AFC_FIGHTER_TOKEN" -H 'content-type: application/json' \
//        -d '{"battle_id":"…","text":"…","callout":"Their Fighter"}' "$AFC_ARENA_URL?podium"
const miked = new Set()
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
// Call-outs naming you. Printed, never auto-answered — accepting puts a card on
// the board with your fighter's name on it, and that is the owner's call:
//   curl -H "authorization: Bearer $AFC_FIGHTER_TOKEN" -H 'content-type: application/json' \
//        -d '{"statement_id":12,"ok":true}' "$AFC_ARENA_URL?callout"
const called = new Set()
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/corner-man.mjs:75