Back to Intelligence

Defending Against GitHub API Recon: Ghost Accounts Campaign Detection & Mitigation

SA
Security Arsenal Team
July 12, 2026
6 min read

Security Arsenal is tracking a significant rise in mass reconnaissance campaigns targeting software supply chains. Recent intelligence highlights that threat actors are leveraging "ghost accounts"—newly created, low-activity GitHub profiles—to systematically map organizational structures on the platform.

These campaigns are not merely opportunistic; they represent the initial phase of targeted attacks. By enumerating organization members and repository inventories, attackers build a precise intelligence picture of your development environment. This data facilitates follow-on attacks, including sophisticated social engineering against developers, the identification of vulnerable or abandoned repositories for fork-based poisoning, and the discovery of hardcoded secrets in public code. Defenders must assume their organization is currently being scanned and implement immediate detection and containment measures.

Technical Analysis

Target: GitHub Organizations and Enterprise accounts.

Mechanism: Attackers automate the creation or utilization of dormant "ghost" accounts to query the GitHub REST API. The focus is on enumeration endpoints that reveal organizational topology.

  • GET /orgs/{org}/members: Used to list all members of an organization, providing a list of human targets for social engineering.
  • GET /orgs/{org}/repos: Used to list repositories, potentially identifying internal tools, naming conventions, and inadvertently publicized private assets.

Abuse Pattern: While GitHub API rate limits exist, attackers distribute requests across a large botnet of ghost accounts to evade thresholds. The traffic often appears as legitimate API usage from disparate IP addresses and unique user agents, making simple IP blocking ineffective. The critical indicator is the intent—aggressive enumeration of structure rather than standard code interaction (cloning, pushing).

Impact:

  • Asset Discovery: Exposure of private project names and internal team structures.
  • Supply Chain Risk: Identification of high-value repositories for dependency confusion attacks or malicious pull requests.
  • Privacy Violation: Uncovering of membership lists which may be sensitive.

CVE Status: N/A (This is an abuse of platform mechanics and API logic, not a software vulnerability).

Detection & Response

Detecting this campaign requires identifying behavioral anomalies in API logs. Defenders should focus on high-frequency enumeration of members and repositories from accounts with little to no commit history or activity.

SIGMA Rules

YAML
---
title: GitHub API Mass Reconnaissance - Member Enumeration
id: 8a4b2c1d-5e6f-4a7b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects potential mass reconnaissance via GitHub API targeting organization members. High volume of GET requests to /orgs/*/members from a single source.
references:
 - https://docs.github.com/en/rest/orgs/members
author: Security Arsenal
date: 2026/04/06
tags:
 - attack.discovery
 - attack.t1593
logsource:
 category: web
detection:
 selection:\   cs-method: 'GET'
   cs-host|contains: 'api.github.com'
   cs-uri|contains: '/members'
 condition: selection | count() by src_ip > 20
falsepositives:
 - Legitimate auditing scripts
 - High-activity onboarding tools
level: high
---
title: GitHub API Mass Reconnaissance - Repository Enumeration
id: 9b5c3d2e-6f7a-5b8c-9d0e-1f2a3b4c5d6e
status: experimental
description: Detects potential mass reconnaissance via GitHub API targeting repositories within an organization.
references:
 - https://docs.github.com/en/rest/repos/repos
author: Security Arsenal
date: 2026/04/06
tags:
 - attack.discovery
 - attack.t1593
logsource:
 category: web
detection:
 selection:
   cs-method: 'GET'
   cs-host|contains: 'api.github.com'
   cs-uri|contains: '/repos'
 condition: selection | count() by src_ip > 20
falsepositives:
 - Legitimate repository management tools
level: medium

KQL (Microsoft Sentinel / Defender)

KQL — Microsoft Sentinel / Defender
// Hunt for GitHub API enumeration targeting members or repos
CommonSecurityLog
| where DestinationPort == 443
| where RequestURL contains \"api.github.com\"
| where RequestMethod == \"GET\"
| extend UriPath = extract(@\"\/api\\.github\\.com\/[^\\?]+\", 0, RequestURL)
| where UriPath contains \"/members\" or UriPath contains \"/repos\"
| summarize Count = count(), UniqueUris = dcount(UriPath) by SourceIP, UserAgent, bin(TimeGenerated, 10m)
| where Count > 50 or UniqueUris > 10
| order by Count desc
| project TimeGenerated, SourceIP, UserAgent, Count, UniqueUris

Velociraptor VQL

VQL — Velociraptor
-- Hunt for processes communicating with api.github.com
-- Useful for identifying compromised internal hosts participating in recon or using stolen tokens
SELECT Pid, Name, CommandLine, Exe, Username
FROM pslist()
WHERE Name IN ('git.exe', 'python.exe', 'node.exe', 'curl.exe', 'powershell.exe')
  AND Pid IN (
      SELECT Pid
      FROM netstat()
      WHERE RemoteAddress =~ 'api.github.com'
         OR RemoteAddress =~ 'github.com'
  )

Remediation Script (PowerShell)

This script audits your GitHub organization for suspicious access patterns and helps identify "ghost" users (users with 0 followers, 0 public repos, and recent creation dates) who have access to your resources. Requires the GitHub CLI (gh) to be installed and authenticated.

PowerShell
# GitHub Organization Ghost Account Auditor
# Requires: gh cli (https://cli.github.com/)

param(
    [Parameter(Mandatory=$true)]
    [string]$OrgName
)

Write-Host \"[+] Auditing Organization: $OrgName\" -ForegroundColor Cyan

# Check if gh is installed and authenticated
$null = gh auth status 2>&1
if ($LASTEXITCODE -ne 0) {
    Write-Host \"[-] Error: GitHub CLI not found or not authenticated. Run 'gh auth login' first.\" -ForegroundColor Red
    exit 1
}

# Fetch all members
Write-Host \"[*] Fetching member list...\" -ForegroundColor Yellow
$members = gh api --paginate \"orgs/$OrgName/members\" | ConvertFrom-Json

Write-Host \"[+] Found $($members.Count) members. Analyzing profiles...\" -ForegroundColor Green

$suspiciousUsers = @()

foreach ($member in $members) {
    $userDetail = gh api \"users/$($member.login)\" | ConvertFrom-Json
    
    # Heuristics for Ghost Accounts
    $isGhost = $false
    $reasons = @()

    if ($userDetail.public_repos -eq 0 -and $userDetail.followers -eq 0) {
        $isGhost = $true
        $reasons += \"0 Public Repos and 0 Followers\"
    }
    
    $accountAge = (Get-Date) - [datetime]$userDetail.created_at
    if ($accountAge.Days -lt 30) {
        $isGhost = $true
        $reasons += \"Account created < 30 days ago\"
    }

    if ($isGhost) {
        $suspiciousUsers += [PSCustomObject]@{
            Username = $userDetail.login
            Type = $userDetail.type
            Created = $userDetail.created_at
            PublicRepos = $userDetail.public_repos
            Followers = $userDetail.followers
            Reasons = ($reasons -join ', ')
        }
    }
}

if ($suspiciousUsers.Count -gt 0) {
    Write-Host \"[!] ALERT: Found $($suspiciousUsers.Count) potentially suspicious ghost accounts:\" -ForegroundColor Red
    $suspiciousUsers | Format-Table -AutoSize
} else {
    Write-Host \"[+] No obvious ghost account patterns detected based on heuristics.\" -ForegroundColor Green
}

# Check Organization Audit Log for recent failed auths or heavy API usage (Requires Admin Access)
Write-Host \"[*] Checking recent Audit Log entries for high-frequency API access...\" -ForegroundColor Yellow
$auditEvents = gh api \"orgs/$OrgName/audit-log?phrase=action:api&per_page=50\" 2>$null
if ($auditEvents) {
    Write-Host \"[+] Review recent API audit logs manually in GitHub UI for clustered IPs.\" -ForegroundColor Cyan
} else {
    Write-Host \"[-] Could not retrieve audit logs (Requires Org Admin privileges).\" -ForegroundColor DarkYellow
}

Remediation

To mitigate the risk of ghost account reconnaissance and secure your GitHub environment:

  1. Restrict Organization Visibility: Review your organization's settings. Ensure that the "Members" list visibility is set to "Members only" rather than "Public" where possible to obscure team structure.
  2. Enable IP Allow Lists: In GitHub Enterprise or Organizations, configure IP Allow Lists to restrict access to your organization's assets to known corporate IP ranges. This renders ghost accounts operating from external IPs ineffective.
  3. Enforce SSO and 2FA: Require all organization members to authenticate via your IdP (SAML SSO) and enable Two-Factor Authentication (2FA). This blocks standalone ghost accounts from joining or accessing resources easily.
  4. Review Third-Party Access: Audit your "Outside Collaborators" and OAuth Apps. Revoke access for any application or user that does not have a verified business justification.
  5. Harden Repository Visibility: Audit repositories to ensure sensitive code is not accidentally set to "Public". Implement a policy where private repositories cannot be made public without a pull request or manual review.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

sigma-rulekql-detectionthreat-huntingdetection-engineeringsiem-detectiongithub-apireconnaissancecloud-securitysupply-chain

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.