When a client asked why their repo was being scanned by unknown IPs, I traced the traffic back to a simple GitHub profile scrape. The public page lists followers, starred repos, contribution graphs, and even the default branch names. All that data is free reconnaissance for an attacker looking to map your tech stack, find old vulnerable dependencies, or guess credential patterns.

The fix isn’t to go private, that defeats the purpose of open source, but to prune what you expose and to harden the surrounding workflow.

Stop leaking internal project names

Many teams use the same repo naming convention they use internally (e.g., proj-frontend-prod). Those names end up in the URL and in the contribution graph.

  • Rename the public repo to a generic name that doesn’t expose the environment (frontend).
  • Use a separate private org for internal prototypes.

Clean up the contribution graph

The graph shows daily commit counts, which can hint at release cycles or sprint cadence.

# Disable the contribution graph for a specific repository
git config --local core.sparseCheckout true
  • core.sparseCheckout prevents GitHub from counting commits that are only in a private branch.
  • Alternatively, push a dummy commit with a generic message to break the pattern.

Remove or hide starred repositories

Stars are a quick way for a recruiter to see what you like, but they also reveal the libraries you depend on.

  • Unstar anything that isn’t part of your public portfolio.
  • Use the "private stars" feature (available in the UI) to keep the list hidden.

Limit the information in your README

Readmes often contain badges that pull build status, coverage, or deployment URLs. Those URLs can be probed for open endpoints.

[![Build Status](https://example.com/badge.svg)](https://example.com)
  • Remove badges that point to internal CI servers.
  • Replace them with static images if you still want to show the badge.

Harden the API token exposure risk

If you ever commit a token, GitHub will automatically redact it in the UI, but the raw commit remains in the history.

  • Run git filter-repo --invert-paths --path token.txt to purge the file.
  • Enable GitHub secret scanning in your repository settings, it alerts you when a secret appears.

Audit your public profile automatically

A small Node script can list everything GitHub shows publicly for a given username. Run it periodically to catch accidental leaks.

// audit-github.js
const fetch = require('node-fetch');
const username = process.argv[2];
(async () => {
  const res = await fetch(`https://api.github.com/users/${username}/repos`);
  const repos = await res.json();
  repos.forEach(r => console.log(r.name, r.private, r.fork));
})();
  • fetch pulls the public repo list.
  • r.private should always be false for a public profile; any true indicates a mis-configured repo.
  • r.fork helps you spot accidental forks of internal code.

Practical warning: don’t forget organization visibility

Even if your personal profile is clean, an organization you belong to may be public and list all members. Attackers can enumerate the org, then scrape each member’s profile.

  • Set the organization visibility to Private if you don’t need a public presence.
  • Use Team visibility settings to restrict who can see member lists.

Why you should care about the attack surface

Attackers start with information gathering. The more you reveal, the easier it is for them to:

  1. Identify the language stack (e.g., a repo full of pom.xml files signals Java).
  2. Spot outdated dependencies that have known CVEs.
  3. Guess credential patterns based on naming conventions.
  4. Target CI pipelines that might still have exposed secrets.

Reducing that surface doesn’t stop a determined adversary, but it raises the effort bar and often eliminates automated scans that rely on cheap data.

Checklist for a lean GitHub profile

  • [ ] Rename public repos to generic names.
  • [ ] Unstar non-essential repositories.
  • [ ] Remove internal CI badges from READMEs.
  • [ ] Enable secret scanning.
  • [ ] Run the audit script monthly.
  • [ ] Review organization visibility settings.

FAQ

How can I see what GitHub shows to the world?

Visit https://github.com/your-username in an incognito window or use the API endpoint https://api.github.com/users/your-username. Anything returned is visible to anyone.

Does disabling the contribution graph hide my commit history?

No, the commits remain in the repository. Disabling the graph only stops GitHub from aggregating them into the visual heatmap, which reduces the cadence clues attackers can infer.

Will making my repos private stop all reconnaissance?

It stops casual scanning of your public repos, but attackers can still look at forks, public forks, and the organization’s member list. Combine privacy with the checklist above for true hardening.

Wrapping up

If you treat your GitHub profile like a resume, you’ll want to showcase the right things and hide the rest. A quick audit, a few naming tweaks, and turning on the built-in security features go a long way toward denying attackers the low-effort data they love. Share this checklist with your team and make the cleanup a regular habit, it’s the cheapest security win you can get from a platform you already use.