Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
lago-stripe-invoice-idor — Reproduz um IDOR CWE-639 no Lago v1.53.0, onde o webhook one-time do Stripe carrega faturas sem escopo de organização, permitindo bypass de pagamento entre organizações. Inclui um laboratório de loopback. | Kitploit
Ferramentas/GitHubGitHub/abraxas/lago-stripe-invoice-idor
Autenticação e AutorizaçãoAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoSegurança de APILabs e Prática

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
GitHubabraxas/lago-stripe-invoice-idor

lago-stripe-invoice-idor

Reproduz um IDOR CWE-639 no Lago v1.53.0, onde o webhook one-time do Stripe carrega faturas sem escopo de organização, permitindo bypass de pagamento entre organizações. Inclui um laboratório de loopback.

Ver Repositório
9há 16 diasAinda não revisado

Abraxas Labs - lago-stripe-invoice-idor

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  lago-stripe-invoice-idor

lago-stripe-invoice-idor

Lago v1.53.0 - GetLago

POST /webhooks/stripe/:organization_id verifica Stripe-Signature com o segredo de webhook daquela organização da URL. Em seguida, o branch one-time em StripeService#update_payment_status carrega a fatura com Invoice.find_by(id:) e sem organization_id. handle_missing_payment é escopado. Faturas Adyen já passam organization_id:. Cashfree e Flutterwave copiam o find_by(id:) sem escopo do Stripe. Este lab é o Stripe.

Outro tenant no mesmo banco de dados, com Stripe conectado, pode marcar sua fatura como paga. O dashboard Stripe deles não tem cobrança correspondente. O seu pode ter.

IDsem CVE ainda
CWECWE-639, CWE-345
CVSSAlto: 7.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N
ProdutoLago / lago-api
Afetadoaté v1.53.0 webhook one-time do Stripe; banco de dados compartilhado
Authorganização atacante com Stripe conectado; UUID da fatura da vítima
LicençaGNU Affero GPL v3.0
Labapenas 127.0.0.1

O que um atacante pode fazer

Assinar um payment_intent.succeeded como sua organização, colocar payment_type=one-time e o lago_invoice_id da sua fatura. O caminho escopado nunca é executado. A linha da vítima se torna payment_status=succeeded. Recarga de carteira / assinatura com pagamento obrigatório é desbloqueada.

Não é não autenticado. Não é um shell. Self-host de organização única não é este bug: esse segredo de assinatura já é dono dos pagáveis daquela organização. Você precisa de um UUID de fatura da vítima (URL do portal, e-mail, PDF, API vazada) e de uma linha stripe_customer da vítima. Evento fictício. Sem Stripe ao vivo.

Mesma árvore do acceptInvite ATO. Bug diferente.

Como eu encontrei

Eu li update_payment_status, depois o find_by(id:) do create_payment one-time, depois o organization_id: do handle_missing_payment. O comentário no caminho escopado teme o mesmo segredo Stripe usado entre organizações. O branch one-time esqueceu de temer.

O primeiro cliente que olhar para isso vai fazer POST de um payment_intent.succeeded sem payment_type. handle_missing_payment busca a fatura e organization_id. Organização atacante, fatura da vítima. nil. Pendente. Esse é o controle. O lab afirma isso.

Caminhos errados já registrados: assinar com o segredo de webhook da vítima (aí você já é dono dos pagáveis daquele comerciante); self-host de organização única; UUID de fatura da organização atacante (pagamento intra-organização); sem stripe_customer na vítima (exceção, não succeeded); tratar o HTTP 200 do webhook como o oráculo (o job é assíncrono - faça polling em GET /api/v1/invoices/:id); um reverse shell. Teatro.

Então: duas chamadas registerUser plantam Victim Corp e Attacker Corp. A chave REST da vítima cria um add-on, um customer e uma fatura não paga com skip_psp para que eu não precisasse de um PSP ao vivo para criar a linha. seed_stripe.rb planta provedores Stripe e um stripe_customer na vítima. webhook_secret fictício. sk_test_lab_* fictício. Evento de controle assinado, sem payment_type: ainda pendente. Evento assinado com payment_type=one-time: succeeded, paid=1000.

Lab

cd lab
./run.sh

Alvo apenas http://127.0.0.1:13001. O Invite ATO usou 13000. Este não compartilha volume com aquele lab.

IOC payment_status_before=pending
IOC control webhook (no payment_type) payment_status_after_control=pending
IOC attack webhook payment_type=one-time
IOC poll payment_status=succeeded paid=1000
SUCCESS Lago Stripe one-time webhook unscoped invoice

A correção

Invoice.find_by(id:, organization_id:) no caminho one-time, do jeito que handle_missing_payment e as faturas Adyen já fazem. O mesmo para Cashfree/Flutterwave.

Referências

  • github.com/getlago/lago tag v1.53.0 · lago-api
  • webhooks_controller.rb · stripe_service.rb · adyen_service.rb · cashfree_service.rb · flutterwave_service.rb
  • Mesmo produto: lago-invite-ato
  • CWE-639 · CWE-345

Licença

GNU Affero GPL v3.0. Veja LICENSE. Apenas lab em loopback. Sem garantia.

Baixar ferramenta