AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 1168972
Accepted
Ami Heines
Ami Heines
Asked: 2024-12-17 15:55:09 +0800 CST2024-12-17 15:55:09 +0800 CST 2024-12-17 15:55:09 +0800 CST

Como rejeitar o cabeçalho do Host se for diferente da URL da solicitação no Apache?

  • 772

Tenho um servidor Apache/2.4.6 (CentOS) com vários subdomínios como ServerAlias ​​no Apache VirtualHost.

algo como:

<VirtualHost *:443>
  ServerName mydomain.com
  ServerAlias a.mydomain.com
  ServerAlias b.mydomain.com

Cada empresa cliente deve acessar através de seu subdomínio e há bancos de dados diferentes para cada empresa cliente, por questões de segurança, há uma separação de dados.

Fui alertado por um especialista em segurança cibernética de que há uma vulnerabilidade em que um usuário de um subdomínio 'a.mydomain.com' pode acessar outro subdomínio 'b.mydomain.com' adicionando um cabeçalho de Host às chamadas do cliente para o servidor web.

No começo, tentei obter as informações em PHP, mas falhei, o PHP não obtém as informações dos cabeçalhos. Então, mudei para procurar uma solução para essa situação no nível do servidor web - Apache.

Quero detectar e rejeitar quando um usuário malicioso tenta enganar o servidor e enviar a solicitação para outro subdomínio usando um Host Header. Neste exemplo, o usuário deve ser atendido por a.mydomain.com e não b.mydomain.com:

curl 'https://a.mydomain.com/users/login' \
  -H 'Host: b.mydomain.com' \
  --data-raw $'{"email":"[email protected]","password":"*****"}'

Uma chamada normal do aplicativo do lado do cliente se parece com isto:

curl 'https://a.mydomain.com/users/login' \
  --data-raw $'{"email":"[email protected]","password":"*****"}'

Eu tentei RequestHeader unset host, mas não funciona como eu esperava.

Minha expectativa era que se o usuário malicioso enviasse um cabeçalho "Host", o servidor deveria ignorá-lo. Isso faria com que ambas as chamadas culr acima fossem efetivamente as mesmas.

Acho que o que acontece é que o Apache está usando a URL na chamada, mas se houver um cabeçalho "Host", ele tem precedência e é isso que é usado e o domínio original da URL é descartado.

Se for esse o caso, então RequestHeader unset hostnão envie nenhum host para meu código PHP, o que faz com que meu código seja interrompido, pois ele precisa saber qual empresa cliente o está chamando.

apache2
  • 2 2 respostas
  • 271 Views

2 respostas

  • Voted
  1. Best Answer
    grawity
    2024-12-17T17:40:03+08:002024-12-17T17:40:03+08:00

    Isso não faz sentido, porque o Hostcabeçalho é como o Apache conhece a URL em primeiro lugar.

    Requisições HTTP regulares não fornecem a URL literal para um servidor web. Se você executar curl com a -vopção, verá que a requisição se parece com , ou seja, apenas o caminho (e a string de consulta) está presente – nãoGET /users/login é como você provavelmente imagina. (Proxies usam o último, requisições normais não.) GET https://a.mydomain.com/users/login

    Então, para onde vai a parte do nome do host da URL quando uma solicitação HTTP é feita? O único lugar para onde vai, no que diz respeito ao HTTP, é o Host:cabeçalho. Portanto, é impossível que o cabeçalho seja "diferente da URL da solicitação", porque é a URL da solicitação.

    Em outras palavras, alterar o cabeçalho do Host não é realmente "enganar o servidor" mais do que apenas alterar a URL; apenas fazer isso https://b.mydomain.com/users/loginteria o mesmo efeito.

    Pode haver algum outro problema sobre o qual o "especialista" estava tentando alertá-lo (por exemplo, talvez ele estivesse falando sobre uma solicitação que tenta enviar dois cabeçalhos de Host, contra os quais acredito que tanto o Apache quanto o PHP já se protegem; ou talvez ele quisesse dizer que o servidor aceitou TLS SNI e HTTP Host incompatíveis, o que também não é um grande problema em si), mas você precisará pedir esclarecimentos a ele.


    Meu palpite é que seu aplicativo não isola sessões PHP (ou tokens de autenticação) por domínio, de modo que se um usuário fizer login e receber um cookie de sessão (ou token de acesso) para o domínio A, mas tentar enviar o mesmo token para o domínio B, o aplicativo o aceitará como autenticação válida para o domínio B. Isso seria um grande problema de segurança, mas nada a ver com falsificar o cabeçalho do Host como tal.

    Agora, o PHP sabe para qual domínio ele foi chamado ( $_SERVER["SERVER_NAME"]e/ou $_SERVER["HTTP_HOST"]— o primeiro vem do Apache, o último é literalmente o Host:cabeçalho; o PHP, na verdade, recebe todos os cabeçalhos por meio HTTP_*de campos), então, se eu acertei, pode ser que esses campos precisem ser armazenados e comparados com a sessão do PHP (ou com o público de qualquer JWT que você esteja emitindo, ou qualquer outra coisa que você use para autenticação).

    Mas, novamente, isso é apenas um palpite, e você deve pedir ao especialista para lhe dar uma explicação mais específica sobre o que eles realmente queriam dizer.

    • 11
  2. Ferrybig
    2024-12-18T00:45:15+08:002024-12-18T00:45:15+08:00

    Você está entendendo mal a vulnerabilidade aqui, tomando como exemplo o post anterior:

    curl 'https://a.mydomain.com/users/login' \
      -H 'Host: b.mydomain.com' \
      --data-raw $'{"email":"[email protected]","password":"*****"}'
    

    Isso autentica no servidor via SNI como a.mydomain.com, mas então envia o cabeçalho do host b.mydomain.com.

    Por padrão, o Apache detecta isso, registra um erro no arquivo de log e retorna um erro 400.

    Nome do host ... fornecido via SNI e nome do host ... fornecido via HTTP são diferentes

    Veja também: https://security.stackexchange.com/questions/134021/what-kind-of-attack-is-prevented-by-apache2s-error-code-ah02032-hostname-prov

    O Apache expõe os resultados do SNI detectado dentro da variávelSSL_TLS_SNI

    Note que você está usando ServerAliasem vez de fazer blocos separados por servidor. Se o SNI informar que ele se conectou a.example.come então enviar um cabeçalho de Host de b.example.com, porque da perspectiva do apache, é o mesmo servidor que permite a solicitação.

    Você quer dividir cada um dos seus servidores para garantir que o apache detecte a incompatibilidade do SNI e do cabeçalho do host. Você pode usar um Includebloco para carregar um arquivo de configuração comum para não ter que se repetir

    • 6

relate perguntas

  • Acessando o servidor web do servidor na rede local com seu endereço IP local

  • Como posso encaminhar solicitações do meu servidor web?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Você pode passar usuário/passar para autenticação básica HTTP em parâmetros de URL?

    • 5 respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Verifique se a porta está aberta ou fechada em um servidor Linux?

    • 7 respostas
  • Marko Smith

    Como automatizar o login SSH com senha?

    • 10 respostas
  • Marko Smith

    Como posso dizer ao Git para Windows onde encontrar minha chave RSA privada?

    • 30 respostas
  • Marko Smith

    Qual é o nome de usuário/senha de superusuário padrão para postgres após uma nova instalação?

    • 5 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    kernel O scp pode copiar diretórios recursivamente? 2011-04-29 20:24:45 +0800 CST
  • Martin Hope
    Robert ssh retorna "Proprietário incorreto ou permissões em ~/.ssh/config" 2011-03-30 10:15:48 +0800 CST
  • Martin Hope
    Eonil Como automatizar o login SSH com senha? 2011-03-02 03:07:12 +0800 CST
  • Martin Hope
    gunwin Como lidar com um servidor comprometido? 2011-01-03 13:31:27 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve