Exposure of Version-Control Repository to an Unauthorized Control Sphere

Description

Exposure of Version-Control Repository to an Unauthorized Control Sphere is a vulnerability where a product stores a CVS, Git, SVN, or other version control repository in a directory, archive, or other resource that is accessible to unauthorized actors. Version control repositories contain metadata and details within subdirectories (like .git, .svn, .hg) that could be exploited if exposed on web servers or in distributed archives. This exposure can reveal usernames, commit messages, filenames, path structures, IP addresses, and detailed diff data exposing source code snippets never intended for public access.

Risk

Exposed version control repositories provide attackers with comprehensive reconnaissance information. The complete source code history can be reconstructed from .git directories, revealing security vulnerabilities, hardcoded credentials, API keys, and sensitive business logic. Commit messages may contain security-relevant information like "fixed SQL injection" pointing attackers to vulnerabilities. Author information can be used for social engineering. Internal file paths reveal server structure. Previous versions may contain secrets that were "deleted" but remain in history. Attackers commonly scan for .git/HEAD, .svn/entries, or similar files as part of reconnaissance.

Solution

Remove all version control directories and metadata from production deployments and public-facing servers. Configure web servers to deny access to hidden directories starting with a dot. Use deployment tools that exclude VCS metadata. Implement pre-deployment checks to detect VCS artifacts. Configure .gitignore and similar files to prevent sensitive files from being tracked. Use git archive or equivalent commands that export source without VCS metadata. Block requests to VCS paths at the web server or CDN level. Regularly audit public-facing systems for exposed repositories.

Common Consequences

ImpactDetails
ConfidentialityScope: Confidentiality

Read Application Data - Attackers can access source code, configuration files, and sensitive data from the version control history.
ConfidentialityScope: Confidentiality

Read Files or Directories - Version control metadata exposes filenames, directory structure, usernames, and other sensitive information about the application and its developers.

Example Code

Vulnerable Configuration

# Vulnerable: Apache configuration allowing access to VCS directories
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    # No restrictions on hidden directories
    # .git, .svn, .hg are all accessible

    # Attacker can access:
    # http://example.com/.git/HEAD
    # http://example.com/.git/config
    # http://example.com/.git/objects/
    # http://example.com/.svn/entries
</VirtualHost>
# Vulnerable: Nginx without VCS directory protection
server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # No location blocks blocking hidden directories
    # .git directory fully exposed
}
# Vulnerable: Deployment that includes VCS metadata
#!/bin/bash

# Vulnerable: Copying entire project including .git
cp -r /home/developer/project/* /var/www/html/

# Vulnerable: rsync without exclusions
rsync -avz /home/developer/project/ /var/www/html/

# Vulnerable: tar without exclusions
tar czf release.tar.gz /home/developer/project/
scp release.tar.gz server:/var/www/

# On server, extracted with .git intact
tar xzf release.tar.gz
# Vulnerable: Docker image with VCS directory
FROM nginx:alpine

# Vulnerable: Copies entire directory including .git
COPY . /usr/share/nginx/html/

# .git directory is now in the image and served by nginx
# Vulnerable: CI/CD pipeline without cleanup
# GitHub Actions example
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      # Vulnerable: Deploys checkout including .git
      - name: Deploy to server
        run: |
          rsync -avz ./ user@server:/var/www/html/

Attacker Reconnaissance

# Attacker discovers exposed .git directory
curl -I https://target.com/.git/HEAD
# HTTP/1.1 200 OK

# Download Git objects
wget -r --no-parent https://target.com/.git/

# Reconstruct repository
cd target.com
git checkout -- .

# View commit history with secrets
git log --all --full-history
git log -p  # Show diffs

# Search for secrets in history
git log -p | grep -i "password\|secret\|key\|token"

# Find deleted sensitive files
git log --all --full-history -- "**/config.php"
git show <commit>:config.php
# Automated .git exposure scanner
import requests

def check_git_exposure(url):
    endpoints = [
        '/.git/HEAD',
        '/.git/config',
        '/.git/index',
        '/.git/logs/HEAD',
        '/.svn/entries',
        '/.svn/wc.db',
        '/.hg/requires',
        '/CVS/Root',
    ]

    for endpoint in endpoints:
        try:
            resp = requests.get(url + endpoint, timeout=5)
            if resp.status_code == 200:
                print(f"[VULNERABLE] {url}{endpoint}")
                return True
        except:
            pass
    return False

Fixed Configuration

# Fixed: Apache blocking VCS directories
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    # Fixed: Block all hidden directories
    <DirectoryMatch "^\.|\/\.">
        Require all denied
    </DirectoryMatch>

    # Fixed: Explicitly block VCS directories
    <DirectoryMatch "(\.git|\.svn|\.hg|CVS)">
        Require all denied
    </DirectoryMatch>

    # Fixed: Block VCS files
    <FilesMatch "(\.gitignore|\.gitmodules|\.svn|\.hg)$">
        Require all denied
    </FilesMatch>
</VirtualHost>
# Fixed: Nginx blocking VCS directories
server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # Fixed: Block all hidden files and directories
    location ~ /\. {
        deny all;
        return 404;
    }

    # Fixed: Explicitly block VCS directories
    location ~ /\.(git|svn|hg|bzr|cvs)/ {
        deny all;
        return 404;
    }

    # Fixed: Block specific VCS files
    location ~ /\.(gitignore|gitmodules|gitattributes)$ {
        deny all;
        return 404;
    }
}
# Fixed: Deployment scripts excluding VCS metadata
#!/bin/bash

# Fixed: Use git archive to export without .git
git archive --format=tar HEAD | tar -x -C /var/www/html/

# Fixed: rsync with exclusions
rsync -avz \
    --exclude='.git' \
    --exclude='.svn' \
    --exclude='.hg' \
    --exclude='.gitignore' \
    --exclude='CVS' \
    /home/developer/project/ /var/www/html/

# Fixed: tar with exclusions
tar czf release.tar.gz \
    --exclude='.git' \
    --exclude='.svn' \
    --exclude='.hg' \
    /home/developer/project/

# Fixed: Find and remove any VCS directories after deployment
find /var/www/html -type d -name ".git" -exec rm -rf {} + 2>/dev/null
find /var/www/html -type d -name ".svn" -exec rm -rf {} + 2>/dev/null
find /var/www/html -type d -name ".hg" -exec rm -rf {} + 2>/dev/null

# Fixed: Verification
if [ -d "/var/www/html/.git" ]; then
    echo "ERROR: .git directory found in deployment!"
    exit 1
fi
# Fixed: Docker image without VCS directories
FROM nginx:alpine

# Fixed: Use .dockerignore to exclude VCS
# .dockerignore contents:
# .git
# .svn
# .hg
# .gitignore
# .gitmodules

# Or explicitly copy only needed files
COPY --chown=nginx:nginx src/ /usr/share/nginx/html/
COPY --chown=nginx:nginx public/ /usr/share/nginx/html/

# Fixed: Remove any VCS artifacts that might slip through
RUN find /usr/share/nginx/html -name ".git*" -type d -exec rm -rf {} + 2>/dev/null || true && \
    find /usr/share/nginx/html -name ".svn" -type d -exec rm -rf {} + 2>/dev/null || true
# Fixed: CI/CD pipeline with proper cleanup
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      # Fixed: Remove VCS artifacts before deployment
      - name: Clean VCS artifacts
        run: |
          rm -rf .git .gitignore .gitmodules
          find . -name ".git*" -type d -exec rm -rf {} + 2>/dev/null || true

      # Fixed: Or use git archive
      - name: Create clean archive
        run: |
          git archive --format=tar --output=release.tar HEAD
          mkdir deploy
          tar -xf release.tar -C deploy/

      - name: Deploy to server
        run: |
          rsync -avz --delete deploy/ user@server:/var/www/html/

      # Fixed: Verify deployment
      - name: Verify no VCS exposed
        run: |
          if curl -s -o /dev/null -w "%{http_code}" https://example.com/.git/HEAD | grep -q "200"; then
            echo "ERROR: .git directory is exposed!"
            exit 1
          fi
# Fixed: Pre-deployment check script
import os
import sys

def check_vcs_artifacts(deploy_dir):
    """Check for VCS artifacts before deployment."""
    vcs_patterns = ['.git', '.svn', '.hg', 'CVS', '.bzr']
    found = []

    for root, dirs, files in os.walk(deploy_dir):
        for pattern in vcs_patterns:
            if pattern in dirs:
                found.append(os.path.join(root, pattern))
            for f in files:
                if f.startswith('.git'):
                    found.append(os.path.join(root, f))

    if found:
        print("ERROR: VCS artifacts found in deployment directory:")
        for path in found:
            print(f"  - {path}")
        return False
    return True

if __name__ == '__main__':
    deploy_dir = sys.argv[1] if len(sys.argv) > 1 else '/var/www/html'
    if not check_vcs_artifacts(deploy_dir):
        sys.exit(1)
    print("OK: No VCS artifacts found")

CVE Examples

No specific CVEs are listed in the MITRE database for this CWE. However, exposed Git repositories have been involved in numerous security incidents:

  • Exposed .git directories have led to source code leaks at major companies
  • Credentials found in Git history have enabled account takeovers
  • This is a common finding in bug bounty programs

References

  1. MITRE Corporation. "CWE-527: Exposure of Version-Control Repository to an Unauthorized Control Sphere." https://cwe.mitre.org/data/definitions/527.html
  2. OWASP. "Source Code Disclosure."
  3. GitTools. "Tools for exploiting exposed .git directories."