Autor: OFJAAAH Data: 2024-10-30
Sintoma: Os botões dentro do popup da extensão não respondiam aos cliques:
- ❌ 📋 Copiar Nome - não funcionava
- ❌ 💻 Comando Create - não funcionava
- ❌ 🔗 Ver Registry - não funcionava
Causa Raiz: Content Security Policy (CSP) do Chrome bloqueava event handlers inline (onclick="function()").
1. Removidos Event Handlers Inline
// ANTES (QUEBRADO):
<button onclick="copyPackageName('${packageName}')">📋 Copiar Nome</button>
// DEPOIS (CORRIGIDO):
<button class="btn-action btn-copy-name">📋 Copiar Nome</button>2. Adicionados Data Attributes
<div class="finding-card"
data-package="${escapeHtml(finding.package)}"
data-type="${finding.type}"
data-registry="${escapeHtml(finding.registryUrl || '')}">3. Implementada Event Delegation
function setupFindingActionListeners() {
const container = document.getElementById('findingsList');
container.addEventListener('click', (e) => {
const button = e.target.closest('.btn-action');
if (!button) return;
const card = button.closest('.finding-card');
if (!card) return;
const packageName = card.dataset.package;
const packageType = card.dataset.type;
const registryUrl = card.dataset.registry;
if (button.classList.contains('btn-copy-name')) {
copyPackageName(packageName);
} else if (button.classList.contains('btn-copy-command')) {
copyCreateCommand(packageName, packageType);
} else if (button.classList.contains('btn-open-registry')) {
openRegistry(registryUrl);
}
});
}4. Funções Movidas para Escopo Local
// ANTES:
window.copyPackageName = function(packageName) { ... }
// DEPOIS:
function copyPackageName(packageName) { ... }5. Adicionado Error Handling
navigator.clipboard.writeText(packageName).then(() => {
showNotification('Nome copiado!', 'success');
}).catch(err => {
console.error('Failed to copy:', err);
showNotification('Erro ao copiar', 'error');
});popup.js- Implementação de event delegation (linhas 158-182)manifest.json- Version bump para 1.1.1
# Substitua apenas o popup.js
cp popup.js /caminho/da/extensao/# Extraia o novo ZIP
unzip dependency-confusion-hunter-v1.1.1.zip -d ~/hunter-v1.1.1/
# Chrome → chrome://extensions/
# Remove versão antiga e carrega novaSe você já tem os arquivos atualizados:
- Abra
chrome://extensions/ - Encontre "Dependency Confusion Hunter"
- Clique no botão 🔄 Recarregar
- Teste os botões!
Após atualizar, teste todos os botões:
Achados Atuais:
- ✓ 📋 Copiar Nome - deve copiar o nome do pacote
- ✓ 💻 Comando Create - deve copiar comando npm/pip
- ✓ 🔗 Ver Registry - deve abrir URL do registry
Histórico:
- ✓ 🗑️ Limpar Histórico - deve funcionar
- ✓ 📊 Exportar - deve baixar CSV
Chrome Extensions têm CSP rigoroso que bloqueia:
- ❌
onclick="function()"- inline event handlers - ❌
eval()e similar - ❌ Inline scripts sem hash
Solução Correta:
- ✅ Event listeners via
addEventListener() - ✅ Event delegation para conteúdo dinâmico
- ✅ Uso de
.closest()para bubbling
Vantagens:
- Funciona com conteúdo dinâmico
- Um único listener para múltiplos elementos
- Melhor performance
- Compatível com CSP
Como funciona:
Click no botão
↓
Event bubbles para container
↓
Container identifica botão clicado
↓
Lê data attributes do card pai
↓
Executa ação apropriada| Aspecto | v1.1.0 | v1.1.1 |
|---|---|---|
| Botões funcionam | ❌ | ✅ |
| CSP compliant | ❌ | ✅ |
| Event delegation | ❌ | ✅ |
| Error handling | Parcial | ✅ Completo |
| Histórico | ✅ | ✅ |
| Validação | ✅ | ✅ |
Antes (v1.1.0):
- Extensão instalada
- Detecções funcionam
- ❌ Usuário não consegue usar os botões
- Experiência quebrada
Depois (v1.1.1):
- Extensão instalada
- Detecções funcionam
- ✅ Todos os botões funcionam perfeitamente
- Experiência completa
- Conteúdo gerado dinamicamente
- Listas com múltiplos elementos
- Cards/items repetidos
- Botões dentro de loops
// 1. Renderizar HTML sem onclick
container.innerHTML = items.map(item => `
<div data-id="${item.id}">
<button class="btn-action">Click</button>
</div>
`).join('');
// 2. Adicionar listener no container
container.addEventListener('click', (e) => {
const btn = e.target.closest('.btn-action');
if (!btn) return;
const id = btn.closest('[data-id]').dataset.id;
handleAction(id);
});Esta mudança também melhora a segurança:
- Elimina eval() implícito dos inline handlers
- Reduz superfície de ataque XSS
- Conformidade total com CSP
- Código mais auditável
Nenhuma! API e funcionalidade permanecem iguais.
Mudanças apenas internas de implementação.
Se os botões ainda não funcionarem após atualização:
-
Limpar cache do Chrome:
chrome://settings/clearBrowserData ☑ Cached images and files
-
Recarregar extensão:
chrome://extensions/ 🔄 Reload button
-
Console de erros:
F12 no popup → Console Verificar erros
-
Reinstalar:
Remover completamente Reiniciar Chrome Instalar novamente
Extensão apenas (21KB):
dependency-confusion-hunter-v1.1.1.zip
SHA256: 6ed7e033a3b2ac1565dfda52a9a3cefd67c31c95ca1dfc96666387f4a90640eaPacote completo com test lab (67KB):
dependency-confusion-hunter-FULL-v1.1.1.zip
SHA256: e33eb50740e6ab7a0c37626c05e751b784382e1cfbbbcf5a4249d23efb4ef60eDesenvolvido com ❤️ por OFJAAAH
v1.1.1 - Agora com botões que realmente funcionam! 🎯