Encontra links externos quebrados que podem ser sequestrados.
Contexto
O Broken Link Hijacking ocorre quando um site possui links para domínios externos que não existem mais ou que expiraram. Um Pentester utiliza esta ferramenta para:
- Identificar Links de Redes Sociais: Se um site aponta para um Twitter ou canal de YouTube que foi deletado, o atacante pode criar uma conta com o mesmo nome e herdar a confiança dos usuários.
- Prevenir Sequestro de Domínios: Se o site linka para um script (
.js) em um domínio que expirou, o atacante pode comprar esse domínio e servir código malicioso diretamente no site alvo. - Limpeza de SEO: Do ponto de vista defensivo, ajuda a manter a integridade e a autoridade do site.
Possibilidades de Implementação
- Web Crawling: O script percorre o HTML do site alvo buscando todas as tags
<a>,<img>,<script>e<link>. - Validação de Status: Para cada link externo encontrado, o script faz uma requisição para verificar se o domínio ainda responde (Status 200) ou se retorna erro de DNS/Conexão (Status 404 ou erro de resolução).
- Filtro de Domínios Externos: O script ignora links internos (do próprio site) para focar apenas em ativos de terceiros que podem ser "comprados" ou "recriados".
Código
Este módulo utiliza BeautifulSoup para extrair os links e requests para validar o status de cada um deles.
Requisitos: pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse
def get_external_links(url):
"""
Extrai todos os links externos de uma página.
"""
links = set()
domain = urlparse(url).netloc
try:
response = requests.get(url, timeout=5)
soup = BeautifulSoup(response.text, 'html.parser')
for a_tag in soup.find_all("a", href=True):
href = a_tag['href']
parsed_href = urlparse(href)
# Verifica se o link é absoluto e se o domínio é diferente do alvo
if parsed_href.scheme and parsed_href.netloc != domain:
links.add(href)
except Exception as e:
print(f"[!] Erro ao acessar a página principal: {e}")
return links
def check_link_status(link):
"""
Verifica se o link externo está quebrado ou acessível.
"""
try:
# allow_redirects=True para seguir encurtadores de URL
response = requests.head(link, timeout=5, allow_redirects=True)
# Se o status for 404 ou o domínio não existir, o link está quebrado
if response.status_code >= 400:
print(f"[!] LINK QUEBRADO ENCONTRADO: {link} (Status: {response.status_code})")
return True
except requests.exceptions.RequestException:
# Erros de conexão ou DNS indicam que o domínio pode estar disponível para compra
print(f"[!] DOMÍNIO NÃO RESOLVIDO/INEXISTENTE: {link}")
return True
return False
def main():
print("=" * 60)
print("Módulo: Broken Link Checker | Projeto: 30 Lessons in Python")
print("=" * 60)
target_url = "https://example.com" # Substitua pelo site alvo
print(f"[*] Analisando links externos em: {target_url}\n")
external_links = get_external_links(target_url)
print(f"[*] Foram encontrados {len(external_links)} links externos. Iniciando validação...\n")
broken_count = 0
for link in external_links:
if check_link_status(link):
broken_count += 1
print("\n" + "=" * 60)
print(f"[*] Scan finalizado. Total de links perigosos: {broken_count}")
if __name__ == "__main__":
main()
Observações
- Falsos Positivos: Alguns sites bloqueiam requisições do tipo
HEAD(usadas para economizar banda). Se falhar, o script deve tentar umGETcompleto. - Recursividade: Para um projeto profissional, o script poderia navegar por todas as páginas do site (crawling) em vez de analisar apenas a página inicial.
- Riscos de Segurança: Encontrar um link para um arquivo
.jsquebrado é uma descoberta de Severidade Alta, pois permite o controle total do navegador do usuário (XSS via arquivo externo).