Back to skill

Security audit

R Package Development — From Zero to CRAN & Bioconductor

Security checks for vulnerabilities and agentic risk

Overview

This R package development skill is coherent and mostly advisory, with a few risky examples users should review before applying.

Before installing, treat this as practical R package guidance rather than a fully hardened operations manual. Be especially careful with the Git author-fix snippet: do not run history rewrites or force pushes unless you have backups, a clean and current branch, collaborator agreement, and understand the repository impact. For CI, consider pinning GitHub Actions and dependency snapshots if reproducibility or supply-chain control matters.

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

T08 · Insecure Dependencies

Warning
Location
references/github-actions.md:27
Finding

Mutable and Dynamically Resolved CI Dependencies

Content
View full analysis

Vulnerability Details

File Location: references/github-actions.md, lines 27–39 and 60–67
Vulnerability Type: Supply-chain exposure through mutable GitHub Action references and unpinned R packages
Risk Level: Medium

Vulnerable Code

yaml
env:
  GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
  _R_CHECK_FORCE_SUGGESTS_: false

steps:
  - uses: actions/checkout@v4
  - uses: r-lib/actions/setup-r@v2
    with:
      r-version: ${{ matrix.config.r }}
      use-public-rspm: true
  - uses: r-lib/actions/setup-pandoc@v2
  - uses: r-lib/actions/setup-r-dependencies@v2
    with:
      extra-packages: any::rcmdcheck
      needs: check
yaml
- name: Install dependencies
  run: |
    install.packages(c("remotes", "rcmdcheck"))
    desc <- readLines("DESCRIPTION")
    desc <- desc[!grepl("^\\s+cmdstanr", desc)]
    writeLines(desc, "DESCRIPTION")
    remotes::install_deps(dependencies = TRUE)
  shell: Rscript {0}

Technical Analysis

The workflow references GitHub Actions using mutable major-version tags such as @v2 and @v4, rather than immutable, reviewed commit SHAs. A major-version tag can be moved by its publisher, so the code executed by a future workflow run may differ from the code originally reviewed.

The alternative installation procedure dynamically installs current versions of remotes, rcmdcheck, and all dependencies resolved from DESCRIPTION. No lockfile, package hashes, exact versions, or repository snapshot is specified. This permits dependency code to change independently of the audited project.

These patterns do not demonstrate that any named dependency is currently malicious. They create a supply-chain trust boundary in which later upstream compromise, account takeover, or malicious dependency publication could introduce unreviewed executable code.

Attack Path

  1. An attacker compromises an upstream action publisher, package maintainer ...[truncated 1350 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every GitHub Action to a reviewed full commit SHA, retaining the release version only as a comment:
    yaml
    - uses: actions/checkout@<full-reviewed-commit-sha> # v4.x
    
  2. Add explicit least-privilege workflow permissions, such as:
    yaml
    permissions:
      contents: read
    
    Grant additional scopes only to jobs that demonstrably require them.
  3. Avoid globally exposing GITHUB_TOKEN as GITHUB_PAT. Provide credentials only to the specific step that requires them.
  4. Introduce dependency locking with a reviewed renv.lock or an equivalent reproducible mechanism.
  5. Use trusted, fixed repository snapshots and enable package integrity verification where supported.
  6. Separate dependency installation and tests involving untrusted pull-request content from jobs holding write-capable credentials.
  7. Use automated dependency-update tooling to propose reviewed SHA and lockfile updates rather than silently resolving current upstream versions.

T09 · Insecure Skill Coding Practices

Note
Location
references/bioconductor.md:127
Finding

Unsafe Git History Rewrite and Unconditional Force Push

Content
View full analysis

Vulnerability Details

File Location: references/bioconductor.md, lines 127–135
Vulnerability Type: Destructive repository operation without backup, confirmation, or lease validation
Risk Level: Low

Vulnerable Code

bash
git filter-branch -f --env-filter '
export GIT_AUTHOR_NAME="RealName"
export GIT_AUTHOR_EMAIL="real@email.com"
export GIT_COMMITTER_NAME="RealName"
export GIT_COMMITTER_EMAIL="real@email.com"
' HEAD
git push --force origin main

Technical Analysis

git filter-branch -f rewrites commit objects in the selected history. The subsequent git push --force origin main unconditionally replaces the remote branch with the rewritten local branch, without verifying whether the remote changed after the user's last fetch.

The guidance does not require a clean working tree, a verified backup branch or tag, a fresh remote fetch, review of the rewritten commit graph, collaborator coordination, or an explicit confirmation immediately before the destructive operation. It also uses --force instead of the safer --force-with-lease.

Rewriting author metadata is a legitimate repository-maintenance task, but the documented procedure can destroy concurrent remote history or make recovery difficult when followed mechanically by an agent or inexperienced user.

Attack Path

  1. A user or agent follows the documented author-correction procedure.
  2. git filter-branch replaces commit identities throughout the selected history.
  3. Another contributor has pushed commits to origin/main, or the local branch is otherwise stale.
  4. The unconditional git push --force replaces the current remote branch regardless of that divergence.
  5. The collaborator's commits disappear from the advertised branch, while commit references, signatures, open reviews, and downstream clones become inconsistent with the rewritten history.
  6. If no backup or reflog remains available, restoration may be diffic ...[truncated 631 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require explicit user confirmation before rewriting history or pushing it.
  2. Verify that the working tree is clean and fetch the current remote state:
    bash
    git status --short
    git fetch origin
    
  3. Create and verify a backup before rewriting:
    bash
    git branch backup/pre-author-rewrite
    git tag pre-author-rewrite
    
  4. Coordinate the maintenance window with collaborators and temporarily prevent ordinary pushes.
  5. Prefer the maintained git filter-repo tool where appropriate, after reviewing and pinning its installation source.
  6. Inspect the rewritten log and compare branch contents before publishing the result.
  7. Replace unconditional force pushing with lease validation:
    bash
    git push --force-with-lease origin main
    
  8. Keep the backup until all collaborators and automation have successfully migrated to the rewritten history.
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/bioconductor.md (reported line 134)May include surrounding context.

export GIT_COMMITTER_NAME="RealName" export GIT_COMMITTER_EMAIL="real@email.com" ' HEAD git push --force origin main

text

Static analysis

No suspicious patterns detected.