Skip to main content

GitHub repository safety scanner

Project description

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

From PyPI (Recommended)

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

Links


Made with โค๏ธ for safer open source

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

repo_tester-2.0.1.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

repo_tester-2.0.1-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file repo_tester-2.0.1.tar.gz.

File metadata

  • Download URL: repo_tester-2.0.1.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for repo_tester-2.0.1.tar.gz
Algorithm Hash digest
SHA256 d12bfd45353ef949bd45c24cb6b879068839ae1ba01fcf504ff16eaa8ecbace6
MD5 8ca393c1cada0870adb197bc515601e2
BLAKE2b-256 1d0a493367111d9786413f4d7ed4fda85e36d8ca12a2ba1befa3a5aef200d463

See more details on using hashes here.

Provenance

The following attestation bundles were made for repo_tester-2.0.1.tar.gz:

Publisher: publish.yml on Dennis-J-Carroll/repo-tester

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file repo_tester-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: repo_tester-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 26.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for repo_tester-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 716291e50388189e14d138cf88bb81a4302d68db2ae0661dce534d43219c8db9
MD5 aa5903d437db79796b2f719c999fa038
BLAKE2b-256 14e27f81307ae806e413d02cf824b64b8af2cd1dec6c45032085e41ab6c99349

See more details on using hashes here.

Provenance

The following attestation bundles were made for repo_tester-2.0.1-py3-none-any.whl:

Publisher: publish.yml on Dennis-J-Carroll/repo-tester

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page