Cópias crackeadas no GitHub: o que o dev JavaScript faz
Um desenvolvedor foi ao Hacker News contar que pediu ao GitHub para remover cópias crackeadas do software dele, esperou mais de um mês e os repositórios continuam lá, públicos, com instrução de instalação e tudo. O post é o Tell HN: GitHub refuses to remove cracked copies of my software after a month, e a thread virou um desabafo coletivo de quem vende software. Se você tem um produto em JavaScript com versão paga, o caso interessa diretamente: cópias crackeadas do seu código podem estar hospedadas na maior plataforma de código do mundo, e tirar elas de lá dá mais trabalho do que parece.
Vou separar a coisa em duas partes. Primeiro, o que dá para fazer quando o crack já está no ar. Depois, o que muda no seu código para o crack dar menos prejuízo.
O que aconteceu, em resumo
O roteiro é conhecido. Você lança um app pago. Alguém remove a checagem de licença, sobe o resultado num repositório público e escreve um README caprichado. Às vezes o README é melhor que o seu. O crack chegou antes do seu changelog.
Aí você faz o que todo mundo manda fazer: abre um pedido de remoção por DMCA. E espera. Segundo o autor, a espera passou de um mês sem os repositórios caírem.
Na thread apareceram as duas leituras de sempre. Um lado acha que o GitHub está sendo omisso com quem é dono do código. O outro lembra que a plataforma recebe um volume enorme de pedidos, muitos abusivos, e que derrubar repositório sem conferir também é problema. As duas coisas podem ser verdade ao mesmo tempo.
Como funciona o DMCA no GitHub (e por que demora)
O GitHub tem um processo formal e público. Os pedidos aceitos são publicados no repositório github/dmca, com os dados pessoais removidos. Isso já diz muita coisa: é um processo jurídico, não um botão de denúncia.
Alguns detalhes que travam muita gente:
- Cada URL conta. O pedido precisa listar os repositórios que estão infringindo. "O usuário X tem várias cópias" não basta.
- Forks não caem sozinhos. Se você não diz explicitamente que todos os forks também infringem, e não explica por quê, a remoção pode pegar só o repositório original. Num projeto crackeado, os forks se multiplicam rápido.
- Pedido incompleto volta. Faltou a declaração de boa-fé, a assinatura ou a descrição clara da obra original? O pedido fica parado esperando você corrigir, e muitas vezes ninguém te avisa com a urgência que você gostaria.
- Existe contranotificação. O dono do repositório pode contestar. Nesse caso, o conteúdo pode voltar depois de alguns dias úteis, a menos que você entre na Justiça.
Ou seja: o processo é lento por desenho. Ele parte do princípio de que quem denuncia pode estar mentindo. É frustrante quando você está certo, mas é o mesmo mecanismo que impede um concorrente de derrubar o seu repositório com uma denúncia falsa.
O DMCA protege seu direito, não seu prazo.
O que fazer quando a cópia crackeada já está no ar
Se você está nessa situação agora, o caminho prático é este:
- Liste tudo. Repositório original, forks, releases com binário, gists. Cole as URLs uma por uma.
- Cite os forks de forma explícita. Diga que o projeto inteiro é cópia não autorizada e que todos os forks herdam a infração.
- Prove a autoria. Link do seu site, do seu repositório privado, data do primeiro release, hash de um arquivo que aparece igual na cópia.
- Acompanhe pelo suporte. Se passou uma ou duas semanas sem resposta, abra um ticket citando o pedido original. Silêncio costuma significar "pedido incompleto", não "pedido negado".
- Ataque a descoberta também. O usuário quase nunca acha o crack navegando no GitHub. Ele acha pelo buscador. Pedir a remoção dos resultados de busca costuma reduzir mais o estrago do que derrubar um repositório que vai reaparecer com outro nome amanhã.
Esse último ponto é o que pouca gente faz. Derrubar a cópia é enxugar gelo. Tirar ela da primeira página do Google é fechar a torneira.
Por que a checagem de licença em JavaScript cai tão fácil
Agora a parte que dói. Se o seu produto é JavaScript rodando no cliente, seja um app Electron, uma extensão de navegador ou um CLI em Node ou Bun, quem tem o arquivo tem o código. Minificar não esconde nada. Ofuscar só atrasa.
A checagem mais comum que eu vejo por aí é algo assim:
const license = localStorage.getItem('license')
if (license === 'PRO') {
unlockProFeatures()
}
Quebrar isso leva menos tempo do que ler este parágrafo. Basta abrir o DevTools e setar a chave. Ou trocar o if por true no bundle.
Um passo acima é validar a licença com assinatura digital. Você assina a licença no seu servidor com uma chave privada e o app só confere com a chave pública. Com Web Crypto dá para fazer isso sem dependência nenhuma, em navegador moderno, Node e Bun:
const PUBLIC_KEY_B64 = 'MCowBQYDK2VwAyEA...' // sua chave pública Ed25519
const fromB64 = (s: string) => Uint8Array.from(atob(s), (c) => c.charCodeAt(0))
export async function isValidLicense(payload: string, signatureB64: string) {
const key = await crypto.subtle.importKey(
'spki',
fromB64(PUBLIC_KEY_B64),
{ name: 'Ed25519' },
false,
['verify'],
)
return crypto.subtle.verify(
'Ed25519',
key,
fromB64(signatureB64),
new TextEncoder().encode(payload),
)
}
Isso resolve um problema real: ninguém consegue gerar chaves de licença falsas, porque não tem a sua chave privada. Acaba a era do keygen.
Mas seja honesto com você mesmo. Quem crackeia não precisa gerar licença. Ele apaga a chamada para isValidLicense e pronto. A assinatura protege contra falsificação, não contra edição do código.
Onde a proteção funciona de verdade
A pergunta certa não é "como impedir o crack". É "o que o crack não consegue entregar".
Tudo que roda na máquina do usuário pode ser copiado. O que roda no seu servidor não pode. Então mova o valor para lá:
- Sincronização e backup entre dispositivos.
- Recursos que dependem de API sua, como processamento pesado, IA, integrações ou exportações.
- Atualizações automáticas. A versão crackeada fica parada no tempo, e cada release seu aumenta a distância.
- Suporte e conta. Quem paga tem um lugar para reclamar. Quem crackeou tem um README.
Na prática, o código do cliente pede um token curto ao servidor, e o servidor só emite se a licença estiver ativa:
const res = await fetch('https://api.seuapp.com/session', {
headers: { Authorization: `License ${licenseKey}` },
})
if (!res.ok) return showFreeTier()
const { token } = await res.json() // expira em minutos, usado nas chamadas pagas
O crack ainda pode liberar a interface. Mas a interface sem o backend é uma casca bonita. E isso muda a conversa: em vez de proteger o código, você protege o serviço.
Vale a pena brigar com o GitHub?
Vale mandar o pedido, e mandar bem feito. É o seu direito e é barato. Mas eu não apostaria o modelo de negócio nisso. Mesmo com o GitHub agindo em uma semana, o mesmo arquivo aparece em outro host, num Discord, num torrent.
Minha opinião, e aqui sei que tem gente que discorda: no software em JavaScript que roda no cliente, a guerra contra o crack está perdida desde o primeiro npm run build. Quem baixa crack, na maioria, nunca ia pagar. Quem ia pagar quer atualização, suporte e a sensação de que o app não vai roubar a senha dele. Um binário crackeado de repositório aleatório é, inclusive, um ótimo jeito de instalar malware. Isso vale lembrar na sua página de preço, com educação.
Então a divisão de esforço que eu sugiro é simples. Uma hora para escrever um DMCA completo, com URLs e forks. Uma tarde para trocar a checagem ingênua por licença assinada. E o resto do tempo construindo coisa que só funciona com o seu servidor do outro lado.
O caso do Hacker News é um lembrete chato, mas útil: plataforma nenhuma vai proteger seu produto por você. A arquitetura protege. Se quiser ver como eu penso esse equilíbrio entre cliente e servidor nos apps que construo, dá uma olhada nos meus projetos.
Resumo para o LinkedIn
Pedi pro GitHub tirar do ar cópias crackeadas do meu software. Um mês depois, elas continuam lá. Esse foi o desabafo de um dev no Hacker News, e ele mostra uma verdade chata: o DMCA protege o seu direito, não o seu prazo. Se o seu produto é JavaScript rodando no cliente, quem tem o arquivo tem o código. Minificar não esconde nada e ofuscar só atrasa. Licença assinada com Ed25519 acaba com o keygen, mas não impede ninguém de apagar o `if`. A proteção que funciona de verdade está na arquitetura: sync, API, IA e updates rodando no seu servidor. O crack libera a interface, mas sem o backend ela vira só uma casca bonita. Escrevi no blog o passo a passo de um DMCA que funciona e de como mover o valor do produto para o servidor. Se você vende software, vale a leitura. #JavaScript #DesenvolvimentoDeSoftware #GitHub #SaaS #SegurançaDaInformação