2024-08-26 11:16:40 -05:00
import os
2024-08-26 13:27:14 -05:00
import argparse
2024-08-26 15:52:50 -05:00
import logging
2024-08-27 13:56:30 -05:00
import json
2024-08-26 15:52:50 -05:00
from github import Github , Auth , GithubException
# Configure logging
logging . basicConfig ( level = logging . INFO , format = ' %(asctime)s - %(levelname)s - %(message)s ' )
2024-08-26 11:16:40 -05:00
2025-02-22 19:19:28 +00:00
# authentication
2024-08-26 11:16:40 -05:00
def auth ( ) :
access_token = os . getenv ( " GITHUB_ACCESS_TOKEN " )
2024-08-26 15:46:39 -05:00
if not access_token :
raise ValueError ( " GITHUB_ACCESS_TOKEN environment variable not set " )
2024-08-26 11:16:40 -05:00
auth = Auth . Token ( access_token )
g = Github ( auth = auth )
return g
2025-01-21 10:10:12 -06:00
"""
This class is used to search GitHub repositories to gather information about repos and users .
- search_repo : Search for repositories based on the query .
- search_users : Search for users based on the query .
- search_in_repo_name : Search for repositories based on the query in the repository name .
- search_by_repo_name : Search for repositories based on the query in the repository name .
- get_repo_open_issues : Get the open issues of a repository .
- get_repo_stars : Get the number of stars of a repository .
- get_repo_open_pull_requests : Get the open pull requests of a repository .
- get_repo_contents : Get the contents of a repository .
- get_result : Get the search result .
- query : The search query .
- result : The search result .
- g : The GitHub object .
Example usage :
# Searching for a CVE-ID in repositories:
searcher = GithubSearcher ( " CVE-2021-1234 " ) # Initialize the searcher with the query
searcher . search_repo ( ) # Search for repositories based on the query. This would search github for repositories with the query "CVE-2021-1234"
result = searcher . get_result ( ) # Get the search result
# Searching for a specific repo by name:
searcher = GithubSearcher ( " php/php-src " ) # Initialize the searcher with the query
searcher . search_by_repo_name ( ) # Search for repositories based on the query in the repository name. This would search github for the repository "php/php-src"
result = searcher . get_result ( ) # Get the search result
# Getting open issues of a repository:
repo = result [ 0 ] # Get the first repository from the search result
open_issues = searcher . get_repo_open_issues ( repo ) # Get the open issues of the repository
for issue in open_issues :
print ( issue . title ) # Print the title of the issue
# Getting the number of stars of a repository:
repo = result [ 0 ] # Get the first repository from the search result
stars = searcher . get_repo_stars ( repo ) # Get the number of stars of the repository
"""
2024-08-26 11:16:40 -05:00
class GithubSearcher ( ) :
def __init__ ( self , query ) :
self . g = auth ( )
self . query = query
self . result = None
def search_repo ( self ) :
2024-08-26 15:52:50 -05:00
try :
self . result = self . g . search_repositories ( self . query )
except GithubException as e :
logging . error ( f " Error searching repositories: { e } " )
self . result = None
2024-08-26 13:27:14 -05:00
2024-08-26 11:16:40 -05:00
def search_users ( self ) :
2024-08-26 15:52:50 -05:00
try :
self . result = self . g . search_users ( self . query )
except GithubException as e :
logging . error ( f " Error searching users: { e } " )
self . result = None
2024-08-26 11:16:40 -05:00
2024-08-27 13:56:30 -05:00
def search_in_repo_name ( self ) :
2024-08-26 15:52:50 -05:00
try :
self . result = self . g . search_repositories ( ' in:name ' + self . query )
except GithubException as e :
logging . error ( f " Error searching in name: { e } " )
self . result = None
2024-08-26 13:27:14 -05:00
2025-01-21 10:10:12 -06:00
def search_by_repo_name ( self ) :
try :
self . result = self . g . search_repositories ( f ' repo: { self . query } ' )
except GithubException as e :
logging . error ( f " Error searching by repo name: { e } " )
self . result = None
2024-08-26 15:46:39 -05:00
def get_repo_open_issues ( self , repo ) :
2024-08-26 15:52:50 -05:00
try :
2024-08-27 10:35:22 -05:00
return repo . get_issues ( state = ' open ' )
2024-08-26 15:52:50 -05:00
except GithubException as e :
logging . error ( f " Error getting open issues: { e } " )
return None
2024-08-26 15:46:39 -05:00
2025-01-21 10:10:12 -06:00
def get_repo_stars ( self , repo ) :
try :
return repo . stargazers_count
except GithubException as e :
logging . error ( f " Error getting stars: { e } " )
return None
2024-08-27 10:35:22 -05:00
def get_repo_open_pull_requests ( self , repo ) :
try :
return repo . get_pulls ( state = ' open ' )
except GithubException as e :
logging . error ( f " Error getting open pull requests: { e } " )
return None
2024-08-26 15:46:39 -05:00
def get_repo_contents ( self , repo ) :
2024-08-26 15:52:50 -05:00
try :
2024-08-27 13:56:30 -05:00
return repo . get_contents ( " " )
2024-08-26 15:52:50 -05:00
except GithubException as e :
logging . error ( f " Error getting repository contents: { e } " )
return None
2024-08-26 15:46:39 -05:00
2024-08-26 11:16:40 -05:00
def get_result ( self ) :
return self . result
def main ( ) :
2024-08-26 15:52:50 -05:00
parser = argparse . ArgumentParser ( description = " Search GitHub repositories and users for PoC exploits and CVEs. " )
parser . add_argument ( " --query " , type = str , required = True , help = " The search query. " )
2025-01-21 10:10:12 -06:00
parser . add_argument ( " --search_type " , type = str , required = True , choices = [ " repo " , " users " , " in-repo-name " , " by-repo-name " ] , help = " The type of search to perform: ' repo ' , ' users ' , ' in-repo-name ' , or ' by-repo-name ' . " )
2024-08-27 10:35:22 -05:00
parser . add_argument ( " --get_file_contents " , action = " store_true " , help = " Get the contents of repo results. " )
parser . add_argument ( " --get_open_issues " , action = " store_true " , help = " Get the open issues of repo results. " )
parser . add_argument ( " --get_open_pull_requests " , action = " store_true " , help = " Get the open pull requests of repo results. " )
2024-08-27 13:56:30 -05:00
parser . add_argument ( " --json " , action = " store_true " , help = " Output results in JSON format. " )
2024-08-27 10:35:22 -05:00
2024-08-26 13:27:14 -05:00
args = parser . parse_args ( )
searcher = GithubSearcher ( args . query )
if args . search_type == " repo " :
searcher . search_repo ( )
elif args . search_type == " users " :
searcher . search_users ( )
2024-08-27 13:56:30 -05:00
elif args . search_type == " in-repo-name " :
searcher . search_in_repo_name ( )
2025-01-21 10:10:12 -06:00
elif args . search_type == " by-repo-name " :
searcher . search_by_repo_name ( )
2024-08-26 13:27:14 -05:00
2024-08-26 11:16:40 -05:00
result = searcher . get_result ( )
2024-08-26 15:46:39 -05:00
if result is None :
print ( " No results found. " )
return
2024-08-27 13:56:30 -05:00
output = [ ]
2024-08-26 13:27:14 -05:00
for item in result :
if args . search_type == " users " :
2024-08-26 13:56:26 -05:00
user_repos = item . get_repos ( )
2024-08-27 13:56:30 -05:00
2024-08-26 13:56:26 -05:00
for repo in user_repos :
2024-08-27 13:56:30 -05:00
repo_info = { " repo_url " : repo . html_url , " repo_name " : repo . name , " repo_description " : repo . description }
output . append ( repo_info )
2024-08-26 13:27:14 -05:00
else :
2024-08-27 13:56:30 -05:00
repo_info = { " repo_url " : item . html_url , " repo_name " : item . name , " repo_description " : item . description }
2024-08-26 11:16:40 -05:00
2024-08-26 15:46:39 -05:00
if args . get_open_issues :
2024-08-27 13:56:30 -05:00
open_issues = searcher . get_repo_open_issues ( item )
if open_issues :
repo_info [ " open_issues " ] = [ { " title " : issue . title , " url " : issue . html_url } for issue in open_issues ]
2025-01-21 10:10:12 -06:00
repo_info [ ' total_open_issues ' ] = item . open_issues_count
2024-08-27 10:35:22 -05:00
if args . get_open_pull_requests :
2024-08-27 13:56:30 -05:00
open_prs = searcher . get_repo_open_pull_requests ( item )
if open_prs :
repo_info [ " open_pull_requests " ] = [ { " title " : pr . title , " url " : pr . html_url } for pr in open_prs ]
2025-01-21 10:10:12 -06:00
repo_info [ " total_open_pull_requests " ] = item . open_pulls_count
2024-08-26 15:46:39 -05:00
if args . get_file_contents :
2024-08-27 13:56:30 -05:00
contents = searcher . get_repo_contents ( item )
if contents :
2024-08-28 18:18:53 -05:00
repo_info [ " contents " ] = [
{
" name " : content_file . name ,
" sha " : content_file . sha ,
" size " : content_file . size ,
" encoding " : content_file . encoding ,
" html_url " : content_file . html_url
} for content_file in contents
]
2024-08-27 13:56:30 -05:00
output . append ( repo_info )
if args . json :
print ( json . dumps ( output , indent = 4 ) )
else :
for item in output :
print ( item )
2024-08-26 15:46:39 -05:00
2024-08-26 11:16:40 -05:00
if __name__ == " __main__ " :
2025-02-22 19:19:28 +00:00
main ( )