Back to skill

Security audit

Soccer Cli

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward soccer stats CLI with disclosed API use, though users should protect the API key file and note that the Go build is not reproducibly pinned.

Before installing, treat the API-Football key as a secret, store the config file with restrictive permissions, and review or pin the Go dependencies because this package does not include module checksum metadata. The skill does not show hidden behavior or malicious activity in the inspected artifacts.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:36
Finding

API Key Stored Without Enforced Restrictive File Permissions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:36-44 (also documented in README.md:26-34)
Vulnerability Type: Plaintext secret stored with potentially insecure permissions
Risk Level: Medium

Vulnerable Code Snippet:

bash
mkdir -p ~/.config/soccer-cli
touch ~/.config/soccer-cli/config.yaml
yaml
apikey: YOUR_API_KEY_HERE

Technical Analysis

The documented configuration procedure stores the API-Football key in a plaintext file but does not enforce owner-only permissions on either the configuration directory or file. The resulting permissions depend on the user's current umask and any preexisting directory permissions. For example, a common umask of 022 can create the file with mode 0644, allowing other local users to read it when the home directory is traversable.

The application subsequently reads this credential and transmits it in the x-apisports-key HTTPS request header. No hardcoded credential or transmission to an undeclared host was identified, but disclosure of the configuration file would expose the user's API credential.

Attack Path

  1. A user follows the documented commands to create ~/.config/soccer-cli/config.yaml.
  2. The file is created under a permissive umask or inside an inadequately protected home/configuration directory.
  3. Another local account enumerates readable files under the victim's configuration directory.
  4. The attacker reads the plaintext apikey value.
  5. The attacker submits API-Football requests using the stolen key.

Exploitation requires local access and filesystem permission to traverse the relevant parent directories.

Impact Assessment

An attacker may obtain the API-Football key and make requests under the victim's account. This can consume API quota, interfere with availability, and potentially cause account-level or billing consequences depending on the associated subscription. The issue does not grant operating- ...[truncated 80 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the documented creation procedure with commands that enforce owner-only access:
    bash
    install -d -m 700 "$HOME/.config/soccer-cli"
    install -m 600 /dev/null "$HOME/.config/soccer-cli/config.yaml"
    
  • Update both SKILL.md and README.md so their instructions are consistent.
  • At runtime, inspect the configuration file's permission bits and reject or prominently warn about files readable or writable by group or other users.
  • Ensure the application does not print the API key in errors, diagnostics, or debug logs.
  • Document key rotation as the response to suspected configuration-file disclosure.

T08 · Insecure Dependencies

Warning
Location
install.sh:11
Finding

Unpinned Third-Party Go Dependencies and Missing Integrity Metadata

Content
View full analysis

Vulnerability Details

File Location: install.sh:11-12, with third-party imports in cmd/root.go:6-7, cmd/game.go:9-10, cmd/scores.go:10-11, and cmd/squad.go:9-10
Vulnerability Type: Non-reproducible dependency resolution without committed checksums
Risk Level: Medium

Vulnerable Code Snippet:

bash
# Build the Go binary. This creates a 'soccer-cli' executable in the current directory.
go build -o soccer-cli main.go

Representative third-party imports include:

go
import (
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)
go
import (
    "github.com/olekukonko/tablewriter"
    "github.com/spf13/cobra"
)

The audited project contains no go.mod or go.sum file.

Technical Analysis

The installer builds code that imports Cobra, Viper, and Tablewriter, but the project does not commit module version constraints or checksum metadata. Consequently, the source tree does not define a reproducible, integrity-verifiable dependency graph.

In a clean modern Go environment, the build may fail because no module definition is present. In an environment relying on external workspace configuration, GOPATH behavior, or preexisting module state, dependency selection can depend on uncontrolled local or remote state. This increases supply-chain exposure and prevents reviewers from verifying precisely which dependency versions are incorporated into the installed binary.

No evidence was found that any named dependency is currently malicious. The risk arises from missing version and integrity controls rather than a confirmed compromised package.

Attack Path

  1. A user invokes install.sh.
  2. The Go toolchain attempts to resolve project and third-party imports using environment-dependent module, workspace, cache, or GOPATH state.
  3. An attacker compromises a dependency source, proxy, local module cache, workspace replacement, or another applicable dependency ...[truncated 996 chars]
Remediation
View remediation

Remediation Suggestions

  • Add and commit a canonical go.mod that pins reviewed direct dependency versions.
  • Generate and commit go.sum so downloaded module content is checked against expected hashes.
  • Ensure the module path matches the imports used by the project.
  • Build the complete module in read-only dependency mode:
    bash
    go build -mod=readonly -o soccer-cli .
    
  • Run go mod verify in the installation or release process.
  • Review dependency updates and use automated vulnerability scanning such as govulncheck.
  • Produce signed or checksummed release artifacts if prebuilt binaries are distributed.
  • Avoid unreviewed replace directives and document any required Go workspace configuration.

T09 · Insecure Skill Coding Practices

Note
Location
cmd/squad.go:48
Finding

Unchecked API Statistics Slice Can Crash the Squad Command

Content
View full analysis

Vulnerability Details

File Location: cmd/squad.go:48-50 and cmd/squad.go:65-67
Vulnerability Type: Unchecked slice indexing of externally supplied API data
Risk Level: Low

Vulnerable Code Snippet:

go
for _, playerDetail := range homeTeam.Players {
    stats := playerDetail.Statistics[0] // Assuming one set of stats per player per game
    if stats.Games.Minutes > 0 {
go
for _, playerDetail := range awayTeam.Players {
    stats := playerDetail.Statistics[0]
    if stats.Games.Minutes > 0 {

Technical Analysis

The Statistics field is populated from the remote API response and is represented as a slice. The command directly accesses element zero without verifying that the slice contains an element. A syntactically valid response containing a player with an empty or omitted statistics array therefore causes a Go index-out-of-range panic.

Although the HTTP client restricts requests to a fixed HTTPS API host, malformed upstream data, an upstream service defect, or a compromised API response can trigger the failure. The issue is limited to process availability because no memory corruption primitive results from Go's bounds checking.

Attack Path

  1. The user runs soccer-cli squad with a fixture ID.
  2. The API returns at least two team entries, satisfying the existing team-count check.
  3. At least one player entry contains an empty or omitted statistics array.
  4. The loop evaluates playerDetail.Statistics[0].
  5. Go raises an index-out-of-range panic and terminates the CLI process.

An attacker would need influence over the API response or upstream data. Ordinary incomplete data may also trigger the same condition without malicious action.

Impact Assessment

The affected command terminates before completing output, resulting in a local denial of service for that invocation. Repeated malformed responses can make the squad functionality unavailable. The issue ...[truncated 104 chars]

Remediation
View remediation

Remediation Suggestions

  • Validate the slice before accessing its first element:
    go
    for _, playerDetail := range homeTeam.Players {
        if len(playerDetail.Statistics) == 0 {
            continue
        }
    
        stats := playerDetail.Statistics[0]
        if stats.Games.Minutes > 0 {
            // Append the validated statistics.
        }
    }
    
  • Apply the same validation to both home and away player loops.
  • Consider displaying an explicit “statistics unavailable” value instead of silently skipping incomplete entries.
  • Add unit tests covering omitted, null, and empty statistics arrays.
  • Validate the decoded API response before passing it to presentation logic.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 26)May include surrounding context.

md
3.  **Configure API Key:**
    The CLI needs a free API key from [API-Football](https://www.api-football.com/).

    Create a configuration file at `~/.config/soccer-cli/config.yaml`:
    ```bash
    mkdir -p ~/.config/soccer-cli
    touch ~/.config/soccer-cli/config.yaml

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
3.  **Configure API Key:**
    The CLI needs a free API key from [API-Football](https://www.api-football.com/).

    Create a configuration file at `~/.config/soccer-cli/config.yaml`:
    ```bash
    mkdir -p ~/.config/soccer-cli
    touch ~/.config/soccer-cli/config.yaml

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · cmd/root.go (reported line 49)May include surrounding context.

go
if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println("Config file not found. Please create one at ~/.config/soccer-cli/config.yaml")
			fmt.Println("Example:\napikey: YOUR_API_KEY_HERE")
			os.Exit(1)
		} else {

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file tells users to create a config file containing a live API key, but it does not include any warning about protecting that file, avoiding commits, or treating the key as sensitive. For markdown files, omissions around behaviors affecting privacy or credentials handling can warrant a missing-warning finding.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code performs outbound network requests and includes a credential in the request header via x-apisports-key. There is no user-facing log, comment, docstring, or confirmation indicating that requests send authentication data to an external service.

Content

No source excerpt is available for this finding.