Skip to main content

repo-tester logo

repo-tester

PyPI version Python 3.11+ License: MIT CI

GitHub repository safety scanner - Detect malicious patterns, supply chain risks, and repository health issues

Overview

repo-tester is a comprehensive security scanner for GitHub repositories that identifies malicious code patterns, supply chain vulnerabilities, and repository health issues. Built for security engineers, DevOps teams, and developers, it provides fast parallel scanning with actionable findings.

Perfect for vetting third-party repositories, auditing dependencies, and integrating security checks into CI/CD pipelines.

Features

  • Malicious Pattern Detection - Identifies obfuscated code, suspicious imports, base64 encoding, credential theft patterns, and hidden backdoors
  • Supply Chain Risk Analysis - Detects vulnerable dependencies, security advisories, and compromised packages using OSV database
  • Repository Health Metrics - Evaluates code quality, maintenance status, commit activity, and security best practices
  • Parallel Scanning - All three scanners run concurrently for performance
  • JSON & Terminal Output - Flexible reporting formats for integration and human review
  • 🔐 Security-First - Designed with a defense-in-depth approach across multiple threat vectors

Quick Start

Installation

pip install repo-tester

Basic Usage

# Scan a repository
repo-tester https://github.com/owner/repo

# Output as JSON
repo-tester https://github.com/owner/repo --format json

# Silent mode (exit code only, no output if clean)
repo-tester https://github.com/owner/repo --quiet

Installation

pip install repo-tester

From Source (Development)

git clone https://github.com/Dennis-J-Carroll/repo-tester.git
cd repo-tester
pip install -e .
pip install pytest pytest-mock

Usage Examples

Basic Repository Scan

$ repo-tester https://github.com/owner/repo

REPO SCAN: owner/repo
═════════════════════════════════════════════
[HIGH] in setup.py:42
  Suspicious base64 execution detected
  Found base64 decode followed by exec() call

[MEDIUM] in requirements.txt
  Deprecated dependency
  Package uses outdated version with known vulnerabilities

═════════════════════════════════════════════
1 CRITICAL  0 HIGH  1 MEDIUM  2 LOW  0 INFO

JSON Output for Integration

$ repo-tester https://github.com/owner/repo --format json
{
  "url": "https://github.com/owner/repo",
  "scanned_at": "2024-04-01T15:30:45.123456+00:00",
  "exit_code": 1,
  "summary": {
    "CRITICAL": 0,
    "HIGH": 1,
    "MEDIUM": 1,
    "LOW": 2,
    "INFO": 0
  },
  "findings": [
    {
      "severity": "HIGH",
      "title": "Suspicious base64 execution detected",
      "detail": "Found base64 decode followed by exec() call",
      "file_path": "setup.py",
      "line_number": 42,
      "scanner": "MaliciousPatternScanner"
    },
    {
      "severity": "MEDIUM",
      "title": "Deprecated dependency",
      "detail": "Package uses outdated version with known vulnerabilities",
      "file_path": "requirements.txt",
      "line_number": null,
      "scanner": "SupplyChainScanner"
    }
  ]
}

Quiet Mode (CI/CD Friendly)

# Returns exit code 0 if clean, 1 if issues found
# No output unless there are findings
$ repo-tester https://github.com/owner/repo --quiet
$ echo $?
0

CI/CD Integration

GitHub Actions

name: Security Scan

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      - run: pip install repo-tester
      - run: repo-tester https://github.com/${{ github.repository }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Processing JSON Results

# Extract critical findings only
repo-tester https://github.com/owner/repo --format json | \
  jq '.findings[] | select(.severity == "CRITICAL")'

# Get count of high-severity issues
repo-tester https://github.com/owner/repo --format json | \
  jq '.summary.HIGH'

# Create markdown report
repo-tester https://github.com/owner/repo --format json | \
  jq -r '.findings[] | "- [\(.severity)] \(.title): \(.detail)"'

How It Works

Three-Scanner Architecture

The tool runs three independent scanners in parallel, each focusing on different security aspects:

1. Malicious Pattern Scanner (Priority 1)

Searches for common code patterns used in malware and attacks:

  • Base64 execution sequences (base64.b64decode() + exec())
  • Command injection patterns
  • Shell obfuscation techniques
  • Pickle deserialization vulnerabilities
  • Credential theft patterns

Patterns are defined in patterns/malicious_patterns.json for easy updates without code changes.

2. Supply Chain Scanner (Priority 2)

Analyzes dependencies for security risks:

  • Uses OSV (Open Source Vulnerabilities) database
  • Checks for known CVEs in specific versions
  • Identifies deprecated or unmaintained packages
  • Detects high-risk dependencies
  • Validates version pinning practices

3. Repository Health Scanner (Priority 3)

Evaluates overall repository health:

  • Commit frequency and activity patterns
  • License presence and compliance
  • README completeness
  • Security policy files
  • Branch protection rules
  • Issue response times

All three scanners run concurrently via ThreadPoolExecutor for optimal performance.

Development

Running Tests

# Run all tests
pytest -v

# Run a single test file
pytest tests/test_scanner_malicious.py -v

# Run a specific test
pytest tests/test_scanner_malicious.py::test_detects_base64_exec -v

Development Setup

git clone https://github.com/Dennis-J-Carroll/repo-tester.git
cd repo-tester
pip install -e .
pip install pytest pytest-mock

Adding Custom Patterns

Edit src/repo_tester/patterns/malicious_patterns.json:

{
  "pattern_name": {
    "regex": "your_pattern_here",
    "severity": "HIGH",
    "title": "Pattern Title",
    "detail": "What this pattern indicates"
  }
}

Add corresponding test in tests/test_scanner_malicious.py:

def test_detects_your_pattern(self):
    code = "code containing pattern"
    findings = self.scanner.scan(self.repo)
    assert any("pattern_name" in f.title for f in findings)

Project Structure

repo-tester/
├── src/repo_tester/
│   ├── cli.py                 # Command-line interface
│   ├── context.py             # Repository cloning and context
│   ├── report.py              # Finding report generation
│   ├── patterns/
│   │   └── malicious_patterns.json  # Malicious code patterns
│   └── scanners/
│       ├── base.py            # Scanner interface
│       ├── malicious.py       # Malicious pattern scanner
│       ├── supply_chain.py    # Dependency vulnerability scanner
│       └── health.py          # Repository health scanner
├── tests/                     # Test suite
├── pyproject.toml             # Project configuration
└── README.md                  # This file

Security

About This Tool

repo-tester is a detection and analysis tool, not a prevention tool. It helps identify potential security issues in repositories but should be used as part of a comprehensive security strategy.

Safety Considerations

  • Shallow clones only - Repository code is cloned to a temporary directory and immediately cleaned up
  • No package installation - Dependencies are analyzed but not executed
  • Read-only scanning - No modifications to the scanned repository
  • Network isolation - Only makes API calls for vulnerability database lookups

Responsible Disclosure

If you discover a vulnerability in repo-tester itself, please email denniscarrollj@gmail.com instead of using the issue tracker.

What This Tool Is NOT

  • Not a substitute for professional security audits
  • Not a guarantee of safety
  • Not a replacement for code review
  • Not a source code obfuscation tool

Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for your changes
  4. Commit your changes (git commit -m 'feat: add amazing feature')
  5. Push to your branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Development Guidelines

  • Write tests for all new features
  • Maintain or improve code coverage
  • Follow PEP 8 style guidelines
  • Update documentation for new features
  • Ensure all tests pass before submitting PR

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Dennis J. Carroll


Made with ❤️ for safer open source

Metadata

Release files for repo-tester 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for repo-tester 2.0.1
File Size Uploaded
repo_tester-2.0.1.tar.gz 1.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for repo-tester 2.0.1
File Interpreter ABI Platform
repo_tester-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / repo_tester-2.0.1.tar.gz

Download URL repo_tester-2.0.1.tar.gz
Size 1.8 MB
Tags Source
SHA-256 checksum
How to use checksums
d12bfd45353ef949bd45c24cb6b879068839ae1ba01fcf504ff16eaa8ecbace6
BLAKE2b-256 checksum
How to use checksums
1d0a493367111d9786413f4d7ed4fda85e36d8ca12a2ba1befa3a5aef200d463
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.

Transparency log

Release files / repo_tester-2.0.1-py3-none-any.whl

Download URL repo_tester-2.0.1-py3-none-any.whl
Size 26.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
716291e50388189e14d138cf88bb81a4302d68db2ae0661dce534d43219c8db9
BLAKE2b-256 checksum
How to use checksums
14e27f81307ae806e413d02cf824b64b8af2cd1dec6c45032085e41ab6c99349
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page