Skip to content

tinyopsec/gitward

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Capsule Render

gitward logo

Typing SVG

   


gitward is a command-line git repository scanner built for OSINT, forensics, and supply-chain audits. Point it at any local repo and it pulls out everything buried in the history: secrets, author identities, IP addresses, suspicious hooks, dangling commits, timezone shifts, and more. Then it scores the repo's overall risk.

It runs entirely through git subprocesses. No libraries, no runtime dependencies, no network calls. Just a single binary and a copy of git.


Table of Contents


Why gitward

Git history is permanent and honest. Developers rotate secrets in the working tree but forget the commit from three months ago that introduced them. Authors use personal emails on work machines. Internal hostnames leak through CI configs. Hooks get added without anyone reviewing them.

gitward looks at the whole picture: every commit across every ref, the reflog, stashes, notes, submodules, unreachable blobs, and hook scripts. Then it surfaces what actually matters.

It's useful for:

  • Red teams auditing a target's leaked or public repositories
  • Blue teams running post-incident forensics on internal repos
  • Security engineers adding a pre-push or CI gate to catch secrets before they leave
  • Developers who want to know what they've actually committed over the lifetime of a project

What It Finds

gitward collects 15 clue types:

Type Description
email Author, committer, config, and Signed-off-by emails across all commits
username Extracted from emails, .git/config, GPG keys, and Signed-off-by trailers
author Unique author and committer names from the full log
commit Every reachable commit hash with subject and timestamp
refname Branches, remotes, tags, reflog entries, and notes
tag Annotated and lightweight tags
stash All stash entries
url Remote URLs, config URLs, and URLs found in diff content
domain Domains extracted from URLs, plus internal .corp/.local/.internal hostnames
ip IPv4 and IPv6 addresses found anywhere in the diff history
filepath Tracked files, with alerts on sensitive filenames like .env, id_rsa, .npmrc
secret Credential patterns matched against 30+ regex rules (see below)
suspicious Dangerous shell patterns, force-push indicators, dangling commits, hook risk, odd-hour commits, timezone shifts, high-churn deletions, Docker directives, VS Code autorun config
relation Submodule paths and GPG-signed commit metadata
timestamp Commit timestamps, used for behavioral analysis

Beyond collection, gitward also inspects:

  • Git hooks in .git/hooks, .githooks, and .husky: each one is scored for network calls, base64 -d, pipe-to-shell patterns, and other signs of malicious intent
  • CI configs: flags .github/workflows, .gitlab-ci.yml, .travis.yml, and Jenkinsfile
  • Dangling blobs: runs git fsck and scans unreachable objects for credential patterns that a normal git log would never show
  • VS Code workspace config: catches runOn: folderOpen and allowAutomaticTasks settings that execute code the moment a repo is opened
  • Timezone shifts: flags when a named author commits from multiple timezones across the history
  • Odd-hour commits: flags commits made between midnight and 6 AM local time

Risk Scoring

Every scan produces a numeric risk score:

Score Meaning
0–29 Low risk
30–99 Worth reviewing
100+ High risk, take action

Scores are additive. Highlights:

  • Secret in a reachable commit: +20
  • Secret in an unreachable blob (deleted, thought to be gone): +80
  • Force-push indicator in reflog: +30
  • Dangling commit: +10
  • Hook with score ≥ 50 (pipe-to-shell, base64 -d, network calls): +100
  • Hook with score ≥ 30: +30
  • High-churn deletion commit: +15
  • File deleted then re-added: +20
  • Odd-hour commits accumulate per commit
  • Three or more timezone shifts for the same author: +10

Installation

Requirements: a C99 compiler, make, and git in $PATH.

git clone https://github.com/tinyopsec/gitward
cd gitward
make
sudo make clean install

Or build without installing:

make
./gitward help

To build with explicit flags:

cc -std=c99 -Wall -Wextra -pedantic -O2 -o gitward main.c scan.c clue.c

No external libraries needed. The binary links only against the C standard library.


Usage

gitward <command> [args]

All commands accept either the full name or a single-letter alias.

gitward scan    [path]              scan a local git repository (default: .)
gitward inspect [path]              scan and print full report
gitward search  <path> <query>      search clues by keyword
gitward save    <path> [outfile]    save results to file
gitward version                     print version
gitward help                        print help

aliases:  s=scan  i=inspect  f=search  o=save

Quick examples:

# Scan the current directory
gitward scan

# Scan a specific repo
gitward scan /path/to/repo

# Search for a domain or string
gitward search /path/to/repo corp.internal

# Save results as plain text
gitward save /path/to/repo results.txt

# Save results as JSON (detected by .json extension)
gitward save /path/to/repo results.json

Commands

scan / s

Scans the repository at path (defaults to .) and prints the full inspection report to stdout. Runs all collectors: commits, authors, refs, tags, stashes, reflog, notes, files, remotes, git config, URLs, IPs, internal domains, submodules, GPG signatures, hooks, VS Code config, CI configs, Docker directives, dangling commits and blobs, timezone anomalies, odd-hour commits, churn analysis, signed-off-by trailers, and force-push indicators.

inspect / i

Same as scan. Both commands scan the repo and print the report; inspect exists for cases where you want the intent to read explicitly in a script.

search / f

Scans the repository and then filters all collected clues against query (case-insensitive substring match against value, author, path, and extra fields). Useful for pivoting: find every clue touching a specific email, hostname, or commit hash.

gitward search . alice@example.com
gitward search /repos/target sk_live_

save / o

Scans the repository and writes results to outfile (defaults to gitward.out). If outfile ends in .json, results are written in JSON format with full field metadata. Otherwise gitward uses a flat key=value text format, suitable for grep pipelines.

The JSON output includes: gitward_version, repo, scanned (UTC timestamp), risk_score, clue_count, and a clues array with type, value, commit, author, path, extra, and utc per entry.


Output Format

The terminal report uses color when stdout is a TTY (green for clean, yellow for warnings, red for secrets and high risk). Sections:

── REPOSITORY ─────────────────────────────────────────────
  path:          /path/to/repo
  scanned:       2025-04-12T14:23:01Z
  git-size:      42M
  pack-size:     38M
  commits:       1847
  authors:       12
  refs:          34
  ...
  secrets:       2
  suspicious:    7
  risk-score:    145

── SECRETS ─────────────────────────────────────────────────
  [CRIT] AKIA...  commit=a3f9c1  path=config/deploy.sh  utc=2024-11-03T02:14:00Z

── SUSPICIOUS ──────────────────────────────────────────────
  [WARN] hook:.git/hooks/post-checkout score=75
  [WARN] force-push-indicator:refs/heads/main reset: moving...

Secret Patterns

gitward matches 30+ patterns across current working files and unreachable history:

  • AWS access keys (AKIA…, ASIA…)
  • GitHub tokens (ghp_, ghs_, github_pat_, classic fine-grained)
  • GitLab tokens (glpat-)
  • Slack tokens (xox[baprs]-)
  • Private keys (RSA, EC, DSA, OpenSSH, PGP)
  • Google API keys (AIza…) and OAuth tokens (ya29.)
  • JWTs (eyJ…)
  • MongoDB connection strings
  • Stripe live keys (sk_live_, rk_live_)
  • SendGrid API keys (SG.)
  • Twilio credentials (AC…, SK…)
  • Square tokens (sq0atp-, sq0csp-)
  • Generic 64-character hex strings
  • Password/secret/token/API key assignment patterns (single- and double-quoted)
  • Database password environment variables
  • NPM tokens
  • Docker and Heroku environment variable assignments
  • AWS metadata endpoint (169.254.169.254)

Suspicious Patterns

Beyond credential patterns, gitward flags shell and behavioral indicators:

  • curl … | sh, wget … | sh
  • base64 -d or base64 --decode
  • eval $(base64 …)
  • Access to /etc/passwd, /etc/shadow, /etc/cron
  • chmod 777 / chmod 666
  • rm -rf /
  • .onion addresses
  • VS Code runOn: folderOpen / allowAutomaticTasks

Hook scripts get scored separately with a finer-grained model that looks at curl, wget, base64, /dev/tcp, nc, netcat, bash -i, python -c, perl -e, ruby -e, ncat, socat, exec, pipe-to-shell, and comment density.


Contributing

Bug reports and patches are welcome. Keep changes to plain C99, POSIX-compatible, and dependency-free. Run make before submitting; the build should produce zero warnings with -Wall -Wextra -pedantic.

About

GitWard Local Git Repo Forensic & OSINT Tool

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors