bacen / pix-api

API Pix: a API do Arranjo de Pagamentos Instantâneos Brasileiro, Pix, criado pelo Banco Central do Brasil.
https://bacen.github.io/pix-api
2.36k stars 267 forks source link

[Segurança] Webhook para URL de terceiros #239

Closed joelemanoel closed 3 years ago

joelemanoel commented 3 years ago

Recentemente @aldemaroc e eu fizemos a implementação da API PIX em nosso sistema de faturamento através da GerenciaNet e observamos que é possível definir a URL de webhook para uma URL de terceiros que já tenham mTLS configurado para o mesmo PSP, o que nos permite efetivamente enviar webhooks para sistemas que não são nossos através da API.

Dessa forma, caso a implementação da API feita pelo cliente não seja segura (ex. não consulta o EndToEndId para validar o webhook e confirmar o pagamento) é possível enviar webhooks para confirmação de pagamentos para qualquer empresa cuja URL de retorno seja conhecida e esteja utilizando o mesmo PSP.

POC (Prova de Conceito):

Uma solução simples seria incluir a chave PIX para onde o pagamento foi enviado no conteúdo do webhook. Já que para o webhook ser feito é necessário mTLS temos certeza que ele é verdadeiro, e dessa forma seria possível validar o pagamento imediatamente sem a necessidade de consultar o EndToEndId (gerando também menos carga na API do PSP).

[UPDATE] Para ficar um pouco mais fácil de entender:

Toda a questão envolvida nesse issue não tem haver com o que é retornado no Webhook (apesar disso, seria interessante vir a chave no objeto do Webhook) e sim em relação a Autenticação e Autorização que o mTLS se propõe.

Se tratando de mTLS entendemos como uma autenticação bidirecional a qual cada um dos lados possam se validar, isto realmente acontece no molde que está hoje, porém como informado acima QUALQUER que seja conta/chave pode setar um Webhook para qualquer URL que esteja com o mTLS do PSP em questão, isso tornando a confiabilidade do Webhook nula, já que você receberá notificações sobre PIXs não recebidos por você, este por si não é o problema, porque o EC poderá validar via /pix o E2EID que foi recebido, todavia, os ECs que não implementarem e acharem que o mTLS está bloqueando esse tipo de situação terão problemas de segurança.

aldemaroc commented 3 years ago

Como já está bem detalhado no issue, qualquer cliente de um determinado PSP pode enviar webhooks para outros clientes do mesmo PSP, já que o PSP não valida o certificado da URL.

Ele até pode estar validando ser um certificado válido assinado por CA reconhecida. Mas o PSP precisa de um elemento de comparação na conta para saber que o certificado é associado a essa conta. E isso não pode ser feito na API, é parâmetro para o dashboard. Exemplo: para conta X, só aceitar certificados do domínio exemplo.com.br.

Não seria mais prudente honrar o Mutual do mTLS e exigir o mesmo certificado utilizado para consumir a API também no webhook? Esse é o objetivo do mTLS, afinal.

Não vejo qualquer motivo para o PSP aceitar certificados emitidos por qualquer CA sendo que ele emite seus próprios certificados.

aldemaroc commented 3 years ago

Se o teste acima falhar, significa que a GN valida. Se continuar funcionando, aí sim significaria, de fato, que ela não valida.

Creio que você não leu o issue, é isso que estamos relatando desde o início. Atualmente é possível definir a URL de webhook de outra pessoa/empresa em uma chave sua, pois o PSP não valida o certificado da URL.

Sinta-se a vontade para realizar seus próprios testes e você irá confirmar.

renatofrota commented 3 years ago

Como já está bem detalhado no issue, qualquer cliente de um determinado PSP pode enviar webhooks para outros clientes do mesmo PSP, já que o PSP não valida o certificado da URL.

Ele até pode estar validando ser um certificado válido assinado por CA reconhecida. Mas o PSP precisa de um elemento de comparação na conta para saber que o certificado é associado a essa conta. E isso não pode ser feito na API, é parâmetro para o dashboard. Exemplo: para conta X, só aceitar certificados do domínio exemplo.com.br.

Não seria mais prudente honrar o Mutual do mTLS e exigir o mesmo certificado utilizado para consumir a API também no webhook? Esse é o objetivo do mTLS, afinal.

Não vejo qualquer motivo para o PSP aceitar certificados emitidos por qualquer CA sendo que ele emite seus próprios certificados.

mTLS é o canal fechado para a comunicação onde os 2 lados precisam ser validados. Isso ocorre:

É fechado mTLS (ou deveria ser) nos 2 momentos distintos. Não precisa ser o mesmo certificado em cada um deles.

rubenskuhl commented 3 years ago

Não seria mais prudente honrar o Mutual do mTLS e exigir o mesmo certificado utilizado para consumir a API também no webhook? Esse é o objetivo do mTLS, afinal.

O m do mTLS se aplica numa conexão. Não especifica que certificados vão ser usados numa conexão no outro sentido.

Não vejo qualquer motivo para o PSP aceitar certificados emitidos por qualquer CA sendo que ele emite seus próprios certificados.

O PSP pode escolher aceitar apenas a CA dele, apenas algumas CAs de mercado, todas as CAs nas trust stores do CA/B Forum... mas qualquer que seja a CA ou CAs aceitas, o processo precisa garantir autenticação e autorização, o que este issue indicou que não está acontecendo.

renatofrota commented 3 years ago

Se o teste acima falhar, significa que a GN valida. Se continuar funcionando, aí sim significaria, de fato, que ela não valida.

Creio que você não leu o issue, é isso que estamos relatando desde o início. Atualmente é possível definir a URL de webhook de outra pessoa/empresa em uma chave sua, pois o PSP não valida o certificado da URL.

Sinta-se a vontade para realizar seus próprios testes e você irá confirmar.

Na verdade o que foi reportado pelo @joelemanoel na abertura do issue é que um webhook enviado para uma transação feita para a sua Chave Pix pode ser enviado pelo PSP para um URL de outro cliente do mesmo PSP, devido o certificado utilizado para fechar o mTLS ser o mesmo para os 2 clientes (e que, exatamente por isso, a URL pode ser registrada para a sua chave mesmo estando no servidor de outro EC).

Em nenhum local no post original o @joelemanoel citou que "o PSP não valida o certificado da URL". Isso quem está dizendo é você.

aldemaroc commented 3 years ago

O m do mTLS se aplica numa conexão. Não especifica que certificados vão ser usados numa conexão no outro sentido.

Você está correto, o problema é de Autorização, não de Autenticação.

flaviolenz commented 3 years ago

Essa criatividade de vcs so vai nos dar mais trabalho. Imagina o PSP usar certificados de client diferente pra cada integrador...

BTW, o BC determina que o certificado pode ser de uma CA amplamente utilizada. Defina o Secret que vc quiser na sua URL... Em teoria o seu concorrente nao vai saber qual eh.

Mas, de qq maneira, o elemento Pix poderia ter um campo "chave".

{ "horario":"2020-12-08T11:40:14.000Z", "valor":"0.15", "txid":"e433v1524u155f31mDvx01", "endToEndId":"E090893562020120811399d35af925d2", "Chave":"xxxxxxxxxxx" }

Em ter, 8 de dez de 2020 22:52, Aldemaro Campos notifications@github.com escreveu:

O m do mTLS se aplica numa conexão. Não especifica que certificados vão ser usados numa conexão no outro sentido.

Você está correto, o problema é de Autorização, não de Autenticação.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bacen/pix-api/issues/239#issuecomment-741430453, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACQ3S7IA2VRKE722H3Y35DDST3J5FANCNFSM4USRYSUA .

renatofrota commented 3 years ago

Essa criatividade de vcs so vai nos dar mais trabalho. Imagina o PSP usar certificados de client diferente pra cada integrador... BTW, o BC determina que o certificado pode ser de uma CA amplamente utilizada. Defina o Secret que vc quiser na sua URL... Em teoria o seu concorrente nao vai saber qual eh. Mas, de qq maneira, o elemento Pix poderia ter um campo "chave". { "horario":"2020-12-08T11:40:14.000Z", "valor":"0.15", "txid":"e433v1524u155f31mDvx01", "endToEndId":"E090893562020120811399d35af925d2", "Chave":"xxxxxxxxxxx" } Em ter, 8 de dez de 2020 22:52, Aldemaro Campos notifications@github.com escreveu: O m do mTLS se aplica numa conexão. Não especifica que certificados vão ser usados numa conexão no outro sentido. Você está correto, o problema é de Autorização, não de Autenticação. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#239 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACQ3S7IA2VRKE722H3Y35DDST3J5FANCNFSM4USRYSUA .

Ponto 1: define-se um "secret" variável a cada implantação do sistema e pronto, o concorrente não vai saber a URL. Concordo.

Ponto 2: o corpo da notificação poderia conter a chave. Condordo - mas não é estritamente necessário, basta definir na própria URL do webhook a chave em questão (eliminando a necessidade da consulta do e2eid inclusive).

Ponto 3: discutir isso pode acabar levando a uma complicação maior de setup (certificados de webhook diferentes por cliente em vez de 1 padrão por PSP, por exemplo). Concordo.

Mas depois de toda a discussão que culminou na convergência de opiniões nesses 3 pontos, a pergunta que fica (não direcionada a você, Flavio) é: qual o sentido de exigir mTLS se o certificado utilizado pelo PSP é público, amplamente conhecido e padrão para todos os clientes do mesmo PSP?

As características de segurança teoricamente oferecidas pelo mTLS no webhook foram pelo ralo e o nível de segurança passou a ser o mesmo que teríamos se o mTLS simplesmente não fosse exigido - tanto é que precisamos da cautela elencada no "Ponto 1" acima para garantir a segurança do request (o que não seria necessário se a proteção extra oferecida pelo mTLS fosse aproveitada de forma eficaz, com certificados diferentes para cada cliente).

rubenskuhl commented 3 years ago

Certificados diferentes para cada cliente é só um dos jeitos do PSP sanar esse problema. O outro é bater o que vem no certificado com uma informação pré-autorizada que serve para autorizar ou não aquele certificado a receber a informação.

renatofrota commented 3 years ago

A implantação do webhook poderia ser simplificada enormemente com a substituição da exigência do mTLS pela exigência de uma variável "secret" na URL de notificação. Ou talvez até pela imposição do valor da variável "secret" pelo próprio PSP ao registrar o webhook, pra garantir a unicidade da variável (distinção entre os clientes).

renatofrota commented 3 years ago

Certificados diferentes para cada cliente é só um dos jeitos do PSP sanar esse problema. O outro é bater o que vem no certificado com uma informação pré-autorizada que serve para autorizar ou não aquele certificado a receber a informação.

Não entendi. :cry:

Pode desenhar pra mim?

rubenskuhl commented 3 years ago

Certificados diferentes para cada cliente é só um dos jeitos do PSP sanar esse problema. O outro é bater o que vem no certificado com uma informação pré-autorizada que serve para autorizar ou não aquele certificado a receber a informação.

Não entendi. 😢

Pode desenhar pra mim?

Você é da empresa ACME. No seu cadastro no PSP, você diz assim: meu certificado de webhook é de algum host no domínio acme.com.br, e o PSP verifica que você é titular desse domínio.

Você registra no Webhook que quer receber avisos de Pix da chave X; o PSP vai lá e verifica qual o certificado apresentado. Se for webhook.acme.com.br, ok; mas se for webhook.pirata.com.br, não aceita a solicitação.

rubenskuhl commented 3 years ago

Como verificar o titular de um domínio: 1) O domínio é .br: https://rdap.registro.br/domain/exemplo.com.br ver o campo publicids[0], type pode ser cpf/cnpj, campo identifier 2) O domínio não é .br: 2.1 envie e-mail para root@example.com, webmaster@example.com com um desafio e peça para o cliente passar um secret 2.2 peça configuração de um record DNS no domínio com um conteúdo específico 2.3 peça para colocar um arquivo no site com conteúdo específico

flaviolenz commented 3 years ago

Implementar o mTLS me custou menos tempo do que o que levei chorando pra fazer... Apanhei bem mais pra implementar o client pra múltiplas empresas, ainda na epoca da NFe. Pra mim... ta OK... resolvido... superado...

Pra atender a norma. PONTO.

Acreditar no payload que recebo no webhook eh outra questão. Nao acredito mesmo, e podem argumentar o que quiserem que nao me convence que eh seguro. Pra mim eh um wakeup call e vantajoso pra nao ficar fazendo pulling. PONTO

Alem disso, meu servidor pode dar pau bem na hora, ficar inacessivel... etc. Do mesmo jeito o PSP pode se perder em algum momento tb. Um pulling diario/horario/sob-demanda ao GET /pix(es) eh mais do que saudavel e barato.

renatofrota commented 3 years ago

Você é da empresa ACME. No seu cadastro no PSP, você diz assim: meu certificado de webhook é de algum host no domínio acme.com.br, e o PSP verifica que você é titular desse domínio.

Se tiver que fazer verificação de propriedade/titularidade do domínio, lascou. Quebra as pernas de vários ERPs e provedores de soluções que vão intermediar os webhooks ou até gerir as cobranças em uma plataforma PaaS / SaaS.

Você registra no Webhook que quer receber avisos de Pix da chave X; o PSP vai lá e verifica qual o certificado apresentado. Se for webhook.acme.com.br, ok; mas se for webhook.pirata.com.br, não aceita a solicitação.

Em um request HTTPS comum enviado pra URL do webhook - a menos que com parâmetros que "desliguem" a verificação de validade do certificado intencionalmente - já é realizada uma validação do certificado apresentado pelo host que recebe o request. Nem precisa de mTLS nesse caso, é o padrão.

flaviolenz commented 3 years ago

Como verificar o titular de um domínio:

  1. O domínio é .br: https://rdap.registro.br/domain/exemplo.com.br ver o campo publicids[0], type pode ser cpf/cnpj, campo identifier
  2. O domínio não é .br: 2.1 envie e-mail para root@example.com, webmaster@example.com com um desafio e peça para o cliente passar um secret 2.2 peça configuração de um record DNS no domínio com um conteúdo específico 2.3 peça para colocar um arquivo no site com conteúdo específico

Jeezzzz... O emissor do certificado ja fez isso!

rubenskuhl commented 3 years ago

Implementar o mTLS me custou menos tempo do que o que levei chorando pra fazer... Apanhei bem mais pra implementar o client pra múltiplas empresas, ainda na epoca da NFe. Pra mim... ta OK... resolvido... superado...

Pra atender a norma. PONTO.

Acreditar no payload que recebo no webhook eh outra questão. Nao acredito mesmo, e podem argumentar o que quiserem que nao me convence que eh seguro. Pra mim eh um wakeup call e vantajoso pra nao ficar fazendo pulling. PONTO

A questão é só o que atende à especificação mínima e mitiga o risco apontado. O que cada EC quiser fazer além disso, vai fazer independente do que alguém disser...

Alem disso, meu servidor pode dar pau bem na hora, ficar inacessivel... etc. Do mesmo jeito o PSP pode se perder em algum momento tb. Um pulling diario/horario/sob-demanda ao GET /pix(es) eh mais do que saudavel e barato.

Essa questão de indisponibilidade já foi discutida em outro issue, e a conclusão do BACEN foi não especificar isso. Mas o que pareceu o consenso daquele issue foi ter um exponential back-off (tempo vai aumentando a cada retentiva) com limite máximo (ex: 2 horas).

rubenskuhl commented 3 years ago

Como verificar o titular de um domínio:

  1. O domínio é .br: https://rdap.registro.br/domain/exemplo.com.br ver o campo publicids[0], type pode ser cpf/cnpj, campo identifier
  2. O domínio não é .br: 2.1 envie e-mail para root@example.com, webmaster@example.com com um desafio e peça para o cliente passar um secret 2.2 peça configuração de um record DNS no domínio com um conteúdo específico 2.3 peça para colocar um arquivo no site com conteúdo específico

Jeezzzz... O emissor do certificado ja fez isso!

Mas se o PSP não fizer, é só preceder o cadastro do webhook por cadastrar como domínio o da empresa vítima.

rubenskuhl commented 3 years ago

Você é da empresa ACME. No seu cadastro no PSP, você diz assim: meu certificado de webhook é de algum host no domínio acme.com.br, e o PSP verifica que você é titular desse domínio.

Se tiver que fazer verificação de propriedade/titularidade do domínio, lascou. Quebra as pernas de vários ERPs e provedores de soluções que vão intermediar os webhooks ou até gerir as cobranças em uma plataforma PaaS / SaaS.

O tópico sobre Authorization Code Flow já deixou bem claro que a API Pix atual é mais focada em acesso do próprio cliente do que de terceiros. Mas o PSP poderia ter o CNPJ do gateway no cadastro para fazer a chegagem contra a titularidade do gateway, mas aí ele precisaria fazer KYC do gateway e o gateway informar quem são seus clientes naquele PSP.

Você registra no Webhook que quer receber avisos de Pix da chave X; o PSP vai lá e verifica qual o certificado apresentado. Se for webhook.acme.com.br, ok; mas se for webhook.pirata.com.br, não aceita a solicitação.

Em um request HTTPS comum enviado pra URL do webhook - a menos que com parâmetros que "desliguem" a verificação de validade do certificado intencionalmente - já é realizada uma validação do certificado apresentado pelo host que recebe o request. Nem precisa de mTLS nesse caso, é o padrão.

Checa-se a validade do certificado, não o conteúdo específico. Isso precisa ser feito em lógica da aplicação do PSP mesmo.

joelemanoel commented 3 years ago

Eu acho que o que ta matando toda essa questão e é o ponto que o @aldemaroc bateu é que quando se trata de Cliente > PSP a conexão só é válida a partir de um certificado e do contrário PSP > Cliente é válido sempre para todos os clientes.

Por questões de implementação talvez ter um certificado para cada cliente acaba trazendo mais trabalhos para o PSP, do outro lado se não o faz isto pode quebrar o fator de segurança que o mTLS deveria trazer.

Vou referenciar aqui o que o @renatofrota falou que pode ser uma solução:

A implantação do webhook poderia ser simplificada enormemente com a substituição da exigência do mTLS pela exigência de uma variável "secret" na URL de notificação. Ou talvez até pela imposição do valor da variável "secret" pelo próprio PSP ao registrar o webhook, pra garantir a unicidade da variável (distinção entre os clientes).

Para não fugirmos mais sobre o problema central, @renatofrota e @rubenskuhl poderia abaixo fornecerem todas as soluções que vocês possuem em mente? (Sei que já citaram anteriormente, mas ficou um pouco bagunçado com a tal discussão).

rubenskuhl commented 3 years ago

Para não fugirmos mais sobre o problema central, @renatofrota e @rubenskuhl poderia abaixo fornecerem todas as soluções que vocês possuem em mente? (Sei que já citaram anteriormente, mas ficou um pouco bagunçado com a tal discussão).

Está estruturado em um dos comentários aqui no tópico, https://github.com/bacen/pix-api/issues/239#issuecomment-741343147

joelemanoel commented 3 years ago

Dessas soluções eu descartaria:

PSP checar se a URL já foi usada em outra ativação de webhook

Por quê? O fraudador pode setar variáveis a mais na hora de passar o webhook e isso quebraria a checagem.

Método /chave/xx-xx-xx que o webhook só responderia para chave de que ele queira ser informado

Em relação ao comentário acima, poderia detalhar mais, talvez um cenário? Não consegui compreender bem.

renatofrota commented 3 years ago

Painel de possíveis mitigações já possíveis sem mudança da API:

* Secret no webhook : `https://webhook.exemplo.com.br/api/v1/webhook/YYYYY/XXXXX/BBBBB/pix`

adicionar ?secret=A1b2C3 (ou &secret=A1b2C3 se já existir ? na URL) me parece muito mais simples que esse formato (e nesse caso, seria a minha opção)

* PSP checar se a URL já foi usada em outra ativação de webhook

Além do já citado pelo @joelemanoel, podem acontecer problemas com domínios que expiram, continuam vinculados no PSP, e depois o novo titular fica impossibilitado de usar (e aí teria que existir mais uma msg de erro específica pra essa situação particular, o que acarretaria mudança na API - no retorno, nesse caso, mas ainda assim é uma mudança).

* PSP associar o CN, fingerprint e chain do certificado do webhook a uma conta/aplicação

o certificado utilizado para a URL ou o específico do mTLS? Pq se o EC mudar de fornecedor de SSL vai invalidar e dar dor de cabeça.

* PSP personalizar os certificados por conta/aplicação, e instruir o EC a checar um CN específico mesmo que da CA do PSP

por favor, não dê ideias que compliquem o setup :disappointed:

* Usar o E2EID e confirmar a chave destino em /pix

mitigação já acessível sem mudança por parte dos PSPs, mas exige um request extra, que não seria necessário com o uso do ?secret + um fragmento/var que indique a própria chave (por opção do próprio EC).

Painel de possível acréscimo à API que permitiria já não ativar o webhook indevido:

* Método /chave/xx-xx-xx que o webhook só responderia para chave de que ele queira ser informado

Também não entendi exatamente essa sugestão.

rubenskuhl commented 3 years ago

Dessas soluções eu descartaria:

PSP checar se a URL já foi usada em outra ativação de webhook

Por quê? O fraudador pode setar variáveis a mais na hora de passar o webhook e isso quebraria a checagem.

Hoje pode colocar a direita do /pix no webhook ? Qual a opção ?

Método /chave/xx-xx-xx que o webhook só responderia para chave de que ele queira ser informado

Em relação ao comentário acima, poderia detalhar mais, talvez um cenário? Não consegui compreender bem.

O webhook hoje tem apenas /pix . Além do /pix, ele teria agora também um /chave/xx-xx-xx com a chave que se quer configurar. Aí na hora de ativar o webhook da chave legítima, o PSP vai testar e dar ok. Mas na hora de ativar o webhook da chave mutreta, o EC vai dar erro 404 nessa, e o PSP não vai ativar esse webhook. Só que isso não existe hoje na API, por essa idéia esta na seção de o que poderia ser feito com mudança da API.

renatofrota commented 3 years ago

Hoje pode colocar a direita do /pix no webhook ? Qual a opção ?

Não entendi direito essa pergunta. A URL de webhook é completamente livre. É o EC que determina...

rubenskuhl commented 3 years ago

Painel de possíveis mitigações já possíveis sem mudança da API:

* Secret no webhook : `https://webhook.exemplo.com.br/api/v1/webhook/YYYYY/XXXXX/BBBBB/pix`

adicionar ?secret=A1b2C3 (ou &secret=A1b2C3 se já existir ? na URL) me parece muito mais simples que esse formato (e nesse caso, seria a minha opção)

Mesmo problema acima, até onde eu lembre o /pix não é parte da chamada então não teria como colocar parâmetros depois.

Além do já citado pelo @joelemanoel, podem acontecer problemas com domínios que expiram, continuam vinculados no PSP, e depois o novo titular fica impossibilitado de usar (e aí teria que existir mais uma msg de erro específica pra essa situação particular, o que acarretaria mudança na API - no retorno, nesse caso, mas ainda assim é uma mudança).

Mas aí seria por URL. E o erro já está previsto na 2.2.0, erro 400 com WebhookOperacaoInvalida.

o certificado utilizado para a URL ou o específico do mTLS? Pq se o EC mudar de fornecedor de SSL vai invalidar e dar dor de cabeça.

No caso do webhook, os dois são o mesmo.

por favor, não dê ideias que compliquem o setup 😞

Segurança, segurança...

mitigação já acessível sem mudança por parte dos PSPs, mas exige um request extra, que não seria necessário com o uso do ?secret + um fragmento/var que indique a própria chave (por opção do próprio EC).

Também não é minha preferida, mas ela existe e resolve.

rubenskuhl commented 3 years ago

Hoje pode colocar a direita do /pix no webhook ? Qual a opção ?

Não entendi direito essa pergunta. A URL de webhook é completamente livre. É o EC que determina...

Não é o que diz a API. A chamada é só até webhookUrl, mas o que o PSP precisa chamar nessa URL é o /pix:

Screen Shot 2020-12-09 at 01 52 44
renatofrota commented 3 years ago

A solução definitiva seria o PSP enviar a chave que recebeu o pagamento no corpo do notificação. Não precisaria toda essa preocupação com URLs, não precisa o GET no /pix pra verificar a transação e, talvez, nem precisaríamos de mTLS, que já tá inseguro de qualquer forma segundo a implementação atual (e já reportaram mais bugs a esse respeito lá no Discord).

Com a chave no corpo da notificação, esse issue nem teria sido aberto. :joy_cat:

rubenskuhl commented 3 years ago

A solução definitiva seria o PSP enviar a chave que recebeu o pagamento no corpo do notificação. Não precisaria toda essa preocupação com URLs, não precisa o GET no /pix pra verificar a transação e, talvez, nem precisaríamos de mTLS, que já tá inseguro de qualquer forma segundo a implementação atual (e já reportaram mais bugs a esse respeito lá no Discord).

Com a chave no corpo da notificação, esse issue nem teria sido aberto. 😹

Não é verdade. O webhook de alguém que não deveria saber de uma determinada transação foi informado dela... já há uma falha mesmo que o sistema recebedor não confunda uma conciliação.

flaviolenz commented 3 years ago

Hoje pode colocar a direita do /pix no webhook ? Qual a opção ?

Não entendi direito essa pergunta. A URL de webhook é completamente livre. É o EC que determina...

Não é o que diz a API. A chamada é só até webhookUrl, mas o que o PSP precisa chamar nessa URL é o /pix:

Screen Shot 2020-12-09 at 01 52 44

De onde veio isso?

Screenshot_20201209-020549_Chrome

rubenskuhl commented 3 years ago

Hoje pode colocar a direita do /pix no webhook ? Qual a opção ?

Não entendi direito essa pergunta. A URL de webhook é completamente livre. É o EC que determina...

Não é o que diz a API. A chamada é só até webhookUrl, mas o que o PSP precisa chamar nessa URL é o /pix:

Screen Shot 2020-12-09 at 01 52 44

De onde veio isso?

https://github.com/bacen/pix-api/releases/tag/2.2.0

Screenshot_20201209-020549_Chrome

Mas aí é a chamada de ativação. A chamada passa https://exemplo.com.br/webhook, aí o PSP aciona https://exemplo.com.br/webhook/pix .

renatofrota commented 3 years ago
  1. Não vejo o menor sentido forçar o "/pix" na URL (exigiria regras de "handling" complexas em alguns webservers)

  2. a GN, aparentemente (segundo logs que eu vi em aplicações de terceiros), não está seguindo isso (está chamando a URL registrada como webhook sem o "/pix").

rubenskuhl commented 3 years ago
  1. Não vejo o menor sentido forçar o "/pix" na URL (exigiria regras de "handling" complexas em alguns webservers)

Eu só apontei a documentação. Não reclame com o mensageiro. ;-) Edit: e está assim desde a versão 2.0.0, que foi onde o webhook apareceu. As versão 2.1.x e 2.2.x apenas mantiveram isso.

  1. a GN, aparentemente (segundo logs que eu vi em aplicações de terceiros), não está seguindo isso (está chamando a URL registrada como webhook sem o "/pix").

Então deveria mudar. Já vou avisar a GN.

joelemanoel commented 3 years ago
  1. Não vejo o menor sentido forçar o "/pix" na URL (exigiria regras de "handling" complexas em alguns webservers)

Eu só apontei a documentação. Não reclame com o mensageiro. ;-)

  1. a GN, aparentemente (segundo logs que eu vi em aplicações de terceiros), não está seguindo isso (está chamando a URL registrada como webhook sem o "/pix").

Então deveria mudar.

Pode confirmar se isso foi implementado na 2.2? Não lembro de ter visto isso na 2.1 e nem 2.0 (A GN ainda aparentemente está na 2.0).

renatofrota commented 3 years ago

Se o teste acima falhar, significa que a GN valida. Se continuar funcionando, aí sim significaria, de fato, que ela não valida.

Creio que você não leu o issue, é isso que estamos relatando desde o início. Atualmente é possível definir a URL de webhook de outra pessoa/empresa em uma chave sua, pois o PSP não valida o certificado da URL.

Sinta-se a vontade para realizar seus próprios testes e você irá confirmar.

No fim das contas, @aldemaroc está [parcialmente] certo (realmente, a GN não está usando o mTLS no envio dos callbacks do webhook, somente no "setup" da URL pela API), apesar de não ter sido esse o report do @joelemanoel (que também se surpreendeu com a confirmação).

Parcialmente por que, no setup, ela valida (onde não precisaria). Só não valida no envio dos callbacks transacionais (que é onde deveria validar, kkk)

rubenskuhl commented 3 years ago
  1. Não vejo o menor sentido forçar o "/pix" na URL (exigiria regras de "handling" complexas em alguns webservers)

Eu só apontei a documentação. Não reclame com o mensageiro. ;-)

  1. a GN, aparentemente (segundo logs que eu vi em aplicações de terceiros), não está seguindo isso (está chamando a URL registrada como webhook sem o "/pix").

Então deveria mudar.

Pode confirmar se isso foi implementado na 2.2? Não lembro de ter visto isso na 2.1 e nem 2.0 (A GN ainda aparentemente está na 2.0).

Veio da 2.0 e não mudou.

joelemanoel commented 3 years ago

Se o teste acima falhar, significa que a GN valida. Se continuar funcionando, aí sim significaria, de fato, que ela não valida.

Creio que você não leu o issue, é isso que estamos relatando desde o início. Atualmente é possível definir a URL de webhook de outra pessoa/empresa em uma chave sua, pois o PSP não valida o certificado da URL. Sinta-se a vontade para realizar seus próprios testes e você irá confirmar.

No fim das contas, @aldemaroc está certo (realmente, a GN não está usando o mTLS no envio dos callbacks do webhook, somente no "setup" da URL pela API), apesar de não ter sido esse o report do @joelemanoel (que também se surpreendeu com a confirmação).

Como relatado anteriormente esse foi um reporte em conjunto com o @aldemaroc dou até os créditos a ele inclusive. Talvez esse não tenha ficado claro no início do issue mas a mensagem que queríamos passar é que realmente não estava se dando autorização da forma correta no mTLS.

renatofrota commented 3 years ago

Eu só apontei a documentação. Não reclame com o mensageiro. ;-)

Não reclamei :+1:

joelemanoel commented 3 years ago
  1. Não vejo o menor sentido forçar o "/pix" na URL (exigiria regras de "handling" complexas em alguns webservers)

Eu só apontei a documentação. Não reclame com o mensageiro. ;-)

  1. a GN, aparentemente (segundo logs que eu vi em aplicações de terceiros), não está seguindo isso (está chamando a URL registrada como webhook sem o "/pix").

Então deveria mudar.

Pode confirmar se isso foi implementado na 2.2? Não lembro de ter visto isso na 2.1 e nem 2.0 (A GN ainda aparentemente está na 2.0).

Veio da 2.0 e não mudou.

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

rubenskuhl commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

joelemanoel commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se o problema sou eu, mas não entendo como isso seria uma solução. https://webhook.meusite111212233.com.br/pix ou https://webhook.meusite111212233.com.br/ Não seria exatamente a mesma coisa?

renatofrota commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se eu sou muito burro ou o quê, mas não consigo entender essa sua proposição do "/chave". Pode dar um exemplo com endereços LITERAIS?

joelemanoel commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se eu sou muito burro ou o quê, mas não consigo entender essa sua proposição do "/chave". Pode dar um exemplo com endereços LITERAIS?

Obrigado, estou na mesma luta kkkk.

rubenskuhl commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se o problema sou eu, mas não entendo como isso seria uma solução. https://webhook.meusite111212233.com.br/pix ou https://webhook.meusite111212233.com.br/ Não seria exatamente a mesma coisa?

  • Levando em consideração como está e não como você apresentou como solução (vejo que é um pouco diferente do que já tem).

Justamente, se o acionamento é diretamente do tratador de Pix, não há extensibilidade. Não dá para por exemplo criar um /splitpix que tratasse de webhook de split payment com parâmetros ligeiramente diferentes. A API fica travada sem possibilidade de inovação.

rubenskuhl commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se eu sou muito burro ou o quê, mas não consigo entender essa sua proposição do "/chave". Pode dar um exemplo com endereços LITERAIS?

Da extensibilidade eu comentei em https://github.com/bacen/pix-api/issues/239#issuecomment-741540643. De como funcionaria especificamente o /chave em https://github.com/bacen/pix-api/issues/239#issuecomment-741523476 .

renatofrota commented 3 years ago

Então realmente a GN está em desacordo. Apesar disso, discordo de como está feito o /pix no Webhook como falado anteriormente pelo @renatofrota só vai atrapalhar e não trazer nenhum tipo de segurança/benefício.

Uma das vantagens de especificar um /alguma-coisa é exatamente a extensibilidade. Por exemplo, eu propus um /chave... se a URL fosse já do método de tratar Pix recebidos, não teria como ser incorporada. Quer se adicione ou não esse /chave, a extensibilidade é necessária e o pensamento da especificação me parece apropriado.

Não sei se o problema sou eu, mas não entendo como isso seria uma solução. https://webhook.meusite111212233.com.br/pix ou https://webhook.meusite111212233.com.br/ Não seria exatamente a mesma coisa?

  • Levando em consideração como está e não como você apresentou como solução (vejo que é um pouco diferente do que já tem).

Justamente, se o acionamento é diretamente do tratador de Pix, não há extensibilidade. Não dá para por exemplo criar um /splitpix que tratasse de webhook de split payment com parâmetros ligeiramente diferente. A API fica travada sem possibilidade de inovação.

Mas determinar o que é pra fazer com uma notificação com base na URL que foi chamada é algo totalmente descabido. O conteúdo da notificação é que é relevante. O setup do servidor tem que ser feito só uma vez e cobrir todos os cenários por meio de uma URL única. O tratamento do que vai ser feito com a notificação ficam em outros locais (no PSP ou no código que vai receber o callback).

renatofrota commented 3 years ago

De como funcionaria especificamente o /chave em #239 (comment) .

Eu li. Mas não entendi.

Se você pudesse citar tudo isso com endereços literais (usando api.example.com para o PSP e webhook.example.net para o EC, por exemplo, além de todas as demais substituições plausíveis como "/chave" - que eu não sei se é literal ou uma $var - e "/xx-xx-xx" - idem).... compreende onde eu quero chegar?

rubenskuhl commented 3 years ago

Mas determinar o que é pra fazer com uma notificação com base na URL que foi chamada é algo totalmente descabido. O conteúdo da notificação é que é relevante. O setup do servidor tem que ser feito só uma vez e cobrir todos os cenários por meio de uma URL única. O tratamento do que vai ser feito com a notificação ficam em outros locais (no PSP ou no código que vai receber o callback).

O conteúdo da notificação pode ser diferente dependendo do evento notificado ou da função sendo solicitada. A URL base é o que foi adotado também na API da parte direta do Pix; há uma base, a partir dai um /versão/método.

joelemanoel commented 3 years ago

Mas determinar o que é pra fazer com uma notificação com base na URL que foi chamada é algo totalmente descabido. O conteúdo da notificação é que é relevante. O setup do servidor tem que ser feito só uma vez e cobrir todos os cenários por meio de uma URL única. O tratamento do que vai ser feito com a notificação ficam em outros locais (no PSP ou no código que vai receber o callback).

Compartilho do mesmo pensamento! E destaco a parte "O conteúdo da notificação é que é relevante.", você deve deixar que o EC escolha o que quer fazer com cada método e como citado no #241 o mais importante é sempre o conteúdo.

renatofrota commented 3 years ago

Mas determinar o que é pra fazer com uma notificação com base na URL que foi chamada é algo totalmente descabido. O conteúdo da notificação é que é relevante. O setup do servidor tem que ser feito só uma vez e cobrir todos os cenários por meio de uma URL única. O tratamento do que vai ser feito com a notificação ficam em outros locais (no PSP ou no código que vai receber o callback).

O conteúdo da notificação pode ser diferente dependendo do evento notificado ou da função sendo solicitada. A URL base é o que foi adotado também na API da parte direta do Pix; há uma base, a partir dai um /versão/método.

Mas aí é o EC consumindo a API do PSP. O PSP não "consome" o sistema do EC. Só notifica eventos. Pro PSP tanto faz a versão do meu sistema e o que eu vou fazer com a informação entrante.