A Parte 1 deixou de explicar como o IBM WebSphere Application Server V6.1 e versões posteriores foram projetados com o princípio de segurança seguro por padrão. Embora não tenha sido alcançado com perfeição, o objetivo era lançar um produto por meio do qual, nas configurações mais comuns e ambientes mais simples, o produto fosse configurado de forma razoavelmente segura por padrão. O artigo anterior terminou após descrever muitas medidas de segurança preventivas e significativas baseadas na infraestrutura que foram incorporadas ao WebSphere Application Server. Este artigo continua com uma descrição de outras medidas preventivas baseadas em aplicativo e depois descreve algumas considerações avançadas e críticas.
Embora as informações deste artigo se baseiem no IBM WebSphere Application Server V7, a maioria dos assuntos tratados aqui se aplica também à V6.1. Se um assunto for exclusivo à determinada versão, ele será identificado. Se você usa uma versão anterior do WebSphere Application Server, consulte o artigo anterior, visto que há diferenças significativas.
Medidas preventivas baseadas em aplicativo
Até este ponto, o foco destes artigos foram as etapas básicas que podem ser executadas para garantir a criação de uma infraestrutura segura de IBM WebSphere Application Server. Obviamente isso é importante, mas concentrar-se apenas na infraestrutura não é suficiente. Agora que a infraestrutura foi fortalecida, é preciso examinar as coisas que os aplicativos precisam fazer para serem seguros. Naturalmente, os aplicativos devem aproveitar a infraestrutura fornecida pelo WebSphere Application Server, mas há várias outras ações que os desenvolvedores de aplicativos devem tomar (ou não) para torná-los tão seguros quanto possível:
- Nunca configure a raiz do documento do servidor da Web para WAR
- Verifique com cuidado se todo alias de servlet está seguro
- Não entregue servlets por nome de classe
- Não coloque informações sensíveis na raiz WAR
- Defina um manipulador de erros padrão
- Avalie a possibilidade de desativar a entrega de arquivos e a navegação de diretório
- Ative a segurança da sessão
- Cuidado com acesso à rede JMX customizado
Para ajudá-lo a ligar essas ações de volta a classes específicas de ataque, cada item usará a chave apresentada na Parte 1 para representar essas vulnerabilidades
1. Nunca configure a raiz do documento do servidor da Web para WAR
Os arquivos WAR contêm código do aplicativo e muitas informações sensíveis. Apenas algumas dessas informações são o conteúdo fornecido pela Web e, assim, não é apropriado configurar a raiz do documento de servidor da Web para a raiz WAR. Se isso for feito, o servidor da Web entregará todo o conteúdo do arquivo WAR sem interpretação, resultando em código, JSPs brutos e mais coisas serem entregues aos seus usuários. (Esta ação é relevante apenas quando o servidor da Web está colocalizado com um servidor de aplicativos.)
2. Verifique com cuidado se todo alias de servlet está seguro
O WebSphere Application Server torna servlets seguros por URL. Cada URL que deve ser tornada segura deve ser especificada no arquivo web.xml que descreve o aplicativo. Se um servlet tem mais de um alias (ou seja, diversos URLs acessam a mesma classe de servlet) ou há muitos servlets, é fácil esquecer acidentalmente de tornar o alias seguro. Cuidado! Visto que o WebSphere Application Server torna seguras as URLs e não as classes subjacentes, se apenas uma URL de servlet não estiver segura, um intruso poderá contornar sua segurança. Para aliviar isso, use curingas para tornar servlets seguros sempre que possível. Se isso não for adequado, verifique novamente e com cuidado seu arquivo web.xml antes da implementação.
Relacionado a isso, certifique-se de que, quando especificar restrições de autorização para servlets, não aliste nenhum método ou, com muito cuidado, aliste (provavelmente em diversas restrições) TODOS os métodos de um servlet (GET, POST, PUT, HEAD, e assim por diante). De acordo com a especificação Java™ EE, se uma restrição de autorização alistar métodos de forma explícita, outros métodos não mencionados NÃO tem restrição de autorização! Isso é especialmente perigoso com métodos como HEAD, cujo padrão é chamar GET para obter os cabeçalhos necessários -- na verdade, chamando o método GET sem verificar suas restrições de autorização. A seção de código do web.xml na Listagem 1 é considerada não segura, enquanto aquela mostrada na Listagem 2 é segura.
Listagem 1. web.xml – não seguro
<security-constraint> <web-resource-collection> <web-resource-name>myservlet</web-resource-name> <url-pattern>/myservlet</url-pattern> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>arole</role-name> </auth-constraint> </security-constraint> |
Listagem 2. web.xml – seguro
<security-constraint> <web-resource-collection> <web-resource-name>myservlet</web-resource-name> <url-pattern>/myservlet</url-pattern> </web-resource-collection> <auth-constraint> <role-name>arole</role-name> </auth-constraint> </security-constraint> |
3. Não entregue servlets por nome de classe
Os servlets podem ser entregues por nome de classe ou por alias de URL normal. Em geral, os aplicativos escolhem o último. Ou seja, os desenvolvedores definem um mapeamento preciso de cada URL para cada classe de servlet no arquivo web.xml, manualmente ou usando uma das várias ferramentas de desenvolvimento do WebSphere Application Server.
Contudo, o WebSphere Application Server também permite entregar servlets por nome de classe. Em vez de definir um mapeamento para cada servlet, uma única URL genérica (como /servlet) entrega todos os servlets. Supõe-se que o componente do caminho após a base é o nome de classe do servlet. Por exemplo, "/servlet/com.ibm.sample.MyServlet" refere-se à classe de servlet "com.ibm.sample.MyServlet."
Entregar servlets por nome de classe é acompanhado pela configuração da propriedade serveServletsByClassnameEnabled para verdadeiro no arquivo ibm-web-ext.xmi ou selecionando a entrega de servlets por nome de classe no editor WAR do IBM Rational® Application Developer. Não ative esse recurso -– o Rational Application Developer o ativa por padrão, de modo que deve ser desativado. Esse recurso torna possível para todos os que conhecem o nome de classe de qualquer servlet chamá-lo diretamente. Mesmo que a URLs do seu servlet esteja segura, um invasor pode ser capaz de contornar a segurança normal baseada em URL. Além disso, dependendo da estrutura do carregador de classe, um invasor pode ser capaz de chamar os servlets fora do seu aplicativo da Web, como em servlets fornecidos pela IBM.
Se não tiver certeza da configuração de vários aplicativos quanto a se ativaram de forma errada a entrega de servlets por nome de classe, configure o servidor de aplicativos para ignorar a configuração (desativando assim a entrega por nome de classe) definindo uma propriedade customizada.
4. Não coloque informações sensíveis na raiz WAR
Os arquivos WAR contém conteúdo que pode ser entregue. O contêiner de Web entregará qualquer arquivo encontrado na raiz do arquivo WAR. Não há problema com isso desde que apenas conteúdo que possa ser entregue seja colocado na raiz. Assim, nunca coloque conteúdo que não deveria ser mostrado aos usuários na raiz do WAR. Por exemplo, não coloque arquivos de propriedades, arquivos de classe ou outras informações importantes ali. Se precisar colocar essas informações no arquivo WAR, coloque-as no diretório WEB-INF, conforme permitido pela especificação de servlet. As informações ali nunca são entregues pelo contêiner de Web.
5. Defina um manipulador de erros padrão
Quando ocorre uma requisição em um aplicativo da Web -- ou mesmo antes do despacho do aplicativo (por exemplo, se o WebSphere Application Server não conseguir localizar um servlet de destino) -- será exibida uma mensagem de erro para o usuário. Por padrão, o WebSphere Application Server exibirá um dump de pilha de exceções bruto com o erro. Isso não só é incrivelmente difícil para o usuário, mas também revela informações sobre o aplicativo (nomes de classes e métodos estão nas informações de pilha). O texto da mensagem de exceção também é exibido, e ele pode conter informações sensíveis.
É melhor assegurar que os usuários nunca vejam uma mensagem de erro bruta definindo uma página de erro padrão que seja exibida sempre que ocorrer uma exceção não manipulada. Essa página pode ser uma mensagem de erro fácil e simples em vez de um rastreio de pilha. A página de erro padrão é definida em ibm-web-ext.xmi usando o atributo defaultErrorPage, ou pode ser configurada no Rational Application Developer usando o editor do descritor de implementação da Web (guia Extensions).
6. Avalie a possibilidade de desativar a entrega de arquivos e a navegação de diretório
Pode-se limitar ainda mais o risco de entregar conteúdo impróprio desativando a entrega de arquivos e a navegação de diretório nos seus aplicativos da Web. Naturalmente, se o WAR contiver conteúdo estático que possa ser entregue, a entrega de arquivos terá de ser ativada.
7. Ative a segurança da sessão
O WebSphere Application Server em geral não impõe autorização de acesso à sessão HTTP. Qualquer um com um identificador de sessão válida poderá acessar qualquer sessão. Embora não seja fácil adivinhar os identificadores de sessão, pode ser possível obtê-los por outros meios.
Para reduzir o risco dessa forma de ataque, avalie a possibilidade de ativar a segurança de sessão. Essa configuração é definida pela navegação até o painel em Application server > <server name> > Web container > Session management . Basta selecionar a opção Security integration , mostrada na Figura 1.
Figura 1. Integração de segurança de sessão
O WebSphere Application Server controlará então que usuário (como determinado pela credencial de LTPA que o usuário apresenta) é dono de uma sessão específica e assegurará que apenas esse usuário possa acessar essa sessão.
Em casos raros, essa configuração pode quebrar aplicativos da Web. Se o aplicativo contiver uma mistura de servlets seguros (com restrições de autorização) e inseguros, os últimos não poderão acessar o objeto de sessão. Depois que o servlet seguro acessar a sessão, ele será marcado como “de propriedade” daquele usuário. Os servlets inseguros executados como anônimos receberão falha de autorização se tentarem acessar essas páginas. A partir do WebSphere Application Server V6.1, o comportamento de autenticação pode ser alterado para garantir que os servlets sem restrição de autorização herdem a identidade do usuário atual se esta já tiver sido estabelecida, cuidando assim desse problema. A Figura 2 mostra como configurar esse recurso.
Figura 2. Preservar a identidade existente
Evitando um ataque
Ativar a segurança de sessão realmente evita um tipo de ataque. Suponhamos que seu Web site estabeleça uma sessão HTTP antes de o usuário autenticar e antes do uso de HTTPS (como se dá na maioria dos sites). Nesse caso, o cookie de sessão (JSESSIONID) fica exposto, tornando fácil para um invasor capturá-lo. Posteriormente, quando o usuário faz a autenticação, naturalmente se deve mudar para SSL e assegurar que o cookie de LTPA flua somente por SSL, como já mencionado. O problema é que o invasor já tem o cookie JSESSIONID. Dependendo de como seu aplicativo foi escrito, ele pode ser capaz de usar esse cookie e um cookie de LTPA diferente (talvez um de sua própria identidade de usuário) para acessar o aplicativo como o primeiro usuário. Esse ataque é muito grave e é muito fácil de implementar se estiver em uso uma rede wireless aberta. Ativando a segurança de sessão, esse ataque é bloqueado porque o servidor de aplicativos bloqueará o acesso a uma sessão que não seja de propriedade do usuário atual.
8. Cuidado com acesso à rede JMX customizado
JMX e MBeans customizados possibilitam oferecer suporte a uma poderosa administração customizada e remota dos seus aplicativos. Cuidado, porém, que os JMX MBeans são acessíveis pela rede. Se decidir implementá-los, faça isso com cuidado e assegure que tenham autorização adequada em suas operações. O WebSphere Application Server fornecerá automaticamente restrições de autorização padrão para MBeans com base em informações no descritor do arquivo JAR MBean. Se isso é apropriado ou não dependerá dos seus aplicativos. Consulte o livro IBM WebSphere: Deployment and Advanced Configuration para obter mais informações.
Medidas de design e implementação
A seguir, vamos voltar a atenção para as ações que os desenvolvedores e designers de aplicativos devem tomar para criar um aplicativo seguro. Estas etapas são vitais e, infelizmente, costumam ser deixadas de lado.
- Use a segurança do WebSphere Application Server para tornar seus aplicativos seguros
- Não dependa da sessão HTTP para identidade do usuário
- Torne segura cada camada do aplicativo
- Valide todas as entradas do usuário
- Escreva aplicativos seguros
- Armazene as informações de forma segura
- Seja sensível a auditoria e rastreio
- Evite o uso de autenticação básica para clientes do navegador
9. Use a segurança do WebSphere Application Server para tornar seus aplicativos seguros
As equipes de aplicativos geralmente reconhecem que seus aplicativos precisam de certa segurança. Em geral, esse é um requisito de negócios. Infelizmente, muitas equipes decidem desenvolver sua própria infraestrutura de segurança. Embora seja possível fazer isso bem, também é muito difícil fazê-lo e, em resultado, a maioria das equipes não consegue. Em vez disso, há a ilusão de segurança forte, quando na verdade a segurança do sistema é bastante fraca. Segurança é, simplesmente, um problema difícil. Há problemas sutis de criptografia, ataques de repetição e diversas outras formas de ataque que são facilmente esquecidas. A mensagem aqui é que a segurança do WebSphere Application Server não deve ser usada. Foi recomendado antes ativar a segurança do aplicativo; aqui, recomendamos realmente usá-la em seus aplicativos.
Talvez a queixa mais comum sobre o modelo de segurança declarativo definido por Java EE é que ele não é suficientemente granular. Por exemplo, pode-se executar autorização apenas no nível do método de um EJB ou servlet (neste contexto, um método de um servlet é um dos métodos de HTTP, como GET, POST, PUT, e assim por diante) não um nível de instância. Assim, por exemplo, todas as contas bancárias têm as mesmas restrições de segurança, mas talvez seja bom que certos usuários tenham permissões especiais em suas contas.
Esse problema é tratado pelas APIs de segurança do Java EE isCallerInRole e getCallerPrincipal. Usando essas APIs, os aplicativos podem desenvolver suas próprias regras de autorização poderosas e flexíveis, mas ainda retiram essas regras das informações conhecidas como exatas: os atributos de segurança do tempo de execução do WebSphere Application Server. Se isso ainda não for suficiente, pode-se criar (ou comprar) uma estrutura de autorização mais elaborada que aproveite as informações de segurança existentes já mantidas pelo servidor de aplicativos (como grupos). Se nem isso for suficiente, a infraestrutura de segurança é altamente customizável. Aproveitar o que existe e funciona (ampliando onde necessário) é a abordagem correta, em vez de descartar o que se tem e tentar criar uma infraestrutura segura do zero.
Exemplo de segurança fraca
Este é um exemplo rápido de um sistema de segurança fraco. Os aplicativos que não usam a segurança do WebSphere Application Server tendem a criar seus próprios tokens de segurança e passá-los dentro do aplicativo. Esses tokens em geral contêm o nome do usuário e alguns atributos de segurança, como suas associações ao grupo. Não é incomum que esses tokens de segurança não tenham informações verificáveis por criptografia. A suposição é que as decisões de segurança podem ser tomadas com base nas informações desses tokens. Isso é falso. Os tokens simplesmente afirmam privilégios de usuário. O problema aqui é que qualquer programa Java pode forjar um desses objetos de segurança e, em seguida, possivelmente infiltrar-se no sistema por uma porta de trás. O melhor exemplo disso é quando o aplicativo cria esses tokens na camada de servlet e então os passa para uma camada EJB. Se a camada EJB não for segura (consulte o próximo item), os invasores podem chamar um EJB diretamente com credenciais falsificadas, tornando a segurança do aplicativo sem sentido. Assim, sem substancial esforço de engenharia, a única fonte segura confiável de informações sobre o usuário é a infraestrutura do WebSphere Application Server.
10. Não dependa da sessão HTTP para identidade do usuário
Muitos aplicativos que implementam sua própria segurança controlam a sessão de autenticação do usuário pelo uso da sessão HTTP. Isso é um perigo. A sessão é controlada por meio de um ID de sessão (ou uma URL ou um cookie). Embora o ID seja gerado aleatoriamente, ainda está sujeito a ataques de repetição porque não tem um tempo limite absoluto específico. Um tempo limite só ocorre após um período de inatividade -- se o cookie de sessão for interceptado, existe um tempo potencialmente ilimitado para utilizá-lo de forma abusiva. Por outro lado, o token LTPA, que é criado quando a segurança do WebSphere Application Server é utilizada pelo aplicativo, é projetado para fornecer um token de autenticação mais forte. Em especial, os tokens LTPA têm tempo de vida limitada, usam criptografia forte e o subsistema de segurança faz uma auditoria do recebimento de tokens LTPA potencialmente falsificados.
Um problema ainda mais perigoso, mas sutis, com o uso da sessão HTTP para a segurança é que o cookie de sessão (JSESSIONID) geralmente é criado antes de o usuário se autenticar -- normalmente quando ele acessa o site. Nesse ponto, o cookie em geral é enviado abertamente por HTTP. Depois que o usuário se autentica, a maioria dos aplicativos mudará para HTTPS em todo o tráfego futuro (protegendo cookies e conteúdo), mas o cookie JSESSIONID já pode ter sido roubado, porque um invasor poderia tê-lo capturado quando ele foi enviado inicialmente por HTTP. Além do ponto óbvio de não usar a sessão HTTP para segurança, o risco de roubo de uma sessão HTTP pode ser reduzido ativando a segurança da sessão e restringindo o cookie LTPA a HTTPS, como já mencionado.
11. Torne segura cada camada do aplicativo
Com muita frequência, os aplicativos da Web são implementados com algum grau de segurança (desenvolvida localmente ou baseada no WebSphere Application Server) na camada do servlet, mas as outras camadas que fazem parte do aplicativo são deixadas sem segurança. Isso é feito sob a falsa premissa de que somente os servlets precisam ser protegidos no aplicativo porque são a porta de entrada dele. Mas, como qualquer policial lhe dirá, também é preciso trancar a porta de trás e as janelas de casa. Há muitas maneiras de isso ocorrer, mas isso é mais comumente visto quando componentes acessíveis remotamente (como EJBs acessíveis por IIOP ou serviços da Web) são usados como parte de uma arquitetura multicamadas quando os clientes Java não fazem parte do aplicativo. Nesse caso, os desenvolvedores geralmente supõem que os componentes remotamente acessíveis não precisam ser protegidos, porque não são "acessíveis ao usuário" em seu design do aplicativo, mas essa suposição é perigosamente errada. Um invasor pode contornar as interfaces de servlet, ir diretamente até a camada de serviços e causar estragos se não tiver sido aplicada segurança nessa camada.
Com frequência, a primeira reação a esse problema é tornar os serviços seguros por um meio trivial, talvez os marcando como acessíveis a todos os usuários autenticados. Mas, dependendo do registro, "todos os usuários autenticados" podem ser todos os funcionários de uma empresa. Alguns levam isso além e restringem o acesso a membros de determinado grupo que significa basicamente "qualquer pessoa que possa acessar este aplicativo". Isso é melhor, mas geralmente não é suficiente, visto que todos que podem acessar o aplicativo não devem necessariamente ser capazes de realizar todas as operações nele. O modo certo de resolver isso é implementar verificações de autorização dos serviços. No caso de EJBs, também se pode pensar em implementar componentes de EJB apenas com interfaces locais, tornando impossível conectar-se a eles remotamente.
12. Valide todas as entradas do usuário
O script entre sites é um ataque bastante insidioso que tira vantagem da flexibilidade e capacidade dos navegadores da Web. A maioria dos navegadores da Web pode interpretar várias linguagens de script, como JavaScript™. O navegador sabe que está vendo algo executável com base em uma sequência especial de caracteres de escape. Aí está a força -- e uma falha perigosa -- do modelo de segurança dos navegadores da Web.
Os invasores podem aproveitar essa brecha enganando o Web site para que exiba um script que ele deseja que o site execute. Isso é feito com bastante facilidade em sites que permitem entradas de usuário arbitrárias. Por exemplo, se um site inclui um formulário para inserir um endereço, um usuário pode, em vez disso, inserir JavaScript. Quando o site exibir o endereço posteriormente, o navegador da Web executará o script. Esse script, visto que é executado dentro do navegador da Web a partir do site, tem acesso a informações seguras, como os cookies do usuário.
Até aqui, isso não parece lá muito perigoso, mas os invasores podem levar isso além e enganar um usuário a ir para um Web site e inserir o script intruso, talvez enviando ao usuário uma URL inocente em um e-mail ou postando-a no blog público. O intruso pode agora executar código arbitrário no navegador do usuário, geralmente com acesso aos cookies, e pode ver todos os eventos de teclado e as páginas exibidas. Isso é tudo de que um intruso precisa para causar danos irreparáveis ao usuário.
Esse problema é na verdade um caso especial de uma classe muito maior de problemas relacionados à validação de entrada do usuário. Sempre que se permite ao usuário digitar texto livre, deve-se garantir que o texto não contenha caracteres especiais que possam causar danos. Por exemplo, se um usuário digitar uma cadeia de caractere usada para procurar um índice, pode ser importante filtrar a cadeia de caractere quanto a curingas incorretos que possam causar pesquisas ilimitadas. No caso da prevenção de script entre sites, é preciso filtrar os caracteres de escape das linguagens de script suportadas pelo navegador. A mensagem aqui é que todas as entradas externas devem ser consideradas suspeitas e ser cuidadosamente validadas. Uma discussão sobre todos os problemas que devem ser tratados está muito além do escopo deste artigo.
13. Escreva aplicativos seguros
Devido a limitações de espaço e à intenção deste artigo, não é possível enumerar aqui todos os problemas de design e codificação do aplicativo que podem afetar a segurança dele. Se houver interesse em desenvolver aplicativos realmente seguros, consulte estes excelentes recursos sobre design, desenvolvimento e teste de aplicativos seguros:
- Livro: Writing Secure Code
- Livro: Software Security: Building Security In
- OWASP, que publicou estes guias:
- Web Application Security Consortium
- Penetration testing frameworks
Além disso, um IBM Redbook publicado recentemente trata do uso do IBM Rational AppScan como elemento-chave do seu ciclo de desenvolvimento para criar aplicativos da Web seguros.
14. Armazene as informações de forma segura
Para criar um sistema seguro, deve-se levar em conta onde as informações são armazenadas ou exibidas. Às vezes, vazamentos de segurança bastante sérios podem ser introduzidos por acidente. Por exemplo, cuidado ao armazenar informação altamente confidencial no objeto de sessão HTTP, visto que ele pode ser serializado para o banco de dados, tornando-o legível a partir dali. Se uma intruso tiver acesso ao seu acessar (ou até acesso em nível de máquina bruto aos volumes do banco de dados), ele pode ser capaz de ver as informações na sessão. Não é preciso dizer que esse tipo de ataque precisa de alto grau de qualificação.
15. Seja sensível a auditoria e rastreio
Qualquer aplicativo não trivial gerará uma quantidade substancial de informações de registro e rastreio para fins comerciais e de depuração. Até aí, tudo bem. Mas se lembre de que as informações nos arquivo têm a tendência de terminar em vários lugares (talvez fora da sua organização). Informações extremamente sensíveis não devem ser rastreadas e deve-se procurar rastreio a auditoria delas, se possível. Por exemplo, vimos clientes que imprimem senhas de usuário, números de carteiras de motorista e até números de segurança social em um arquivo de rastreio. Se esse arquivo for lido pela pessoa errada (talvez um consultor que esteja ajudando), você terá acabado de revelar informações sensíveis.
Só por segurança, limite e revise o que é registrado.
16. Evite o uso de autenticação básica para clientes do navegador
O problema com a autenticação básica é que o navegador da Web armazena em cache o ID do usuário e senha, e os reenvia automaticamente em futuras solicitações quando necessário. Isso significa que é impossível efetuar logoff do usuário que tenha usado autenticação básica. Por exemplo, se o cookie LTPA do usuário vencer, o servidor de aplicativos pede novamente o ID do usuário e a senha. Para ajudar, o navegador os reenvia – tornando o tempo limite inútil. Para piorar, se uma solicitação ocorrer por HTTP (sem criptografia), o navegador enviará prontamente a senha aberta pela rede.
A autenticação básica é uma abordagem sensata quando o cliente não é um navegador. Por exemplo, os serviços da Web ou clientes REST muitas vezes usam autenticação básica de forma segura. Naturalmente, essas solicitações devem fluir por SSL.
Vamos agora para algumas questões avançadas relacionadas com o fortalecimento, incluindo a confiança entre células, isolamento de aplicativos, a propagação de identidade e as limitações de segurança do WebSphere Application Server. Na maioria dos casos, não há aqui nenhuma recomendação específica. Em vez disso, deve-se usar essas informações importantes para ajudar nos esforços de manter e gerenciar uma infraestrutura segura.
Confiança e isolamento de célula
Uma célula de WebSphere Application Server não deve ultrapassar os limites da confiança. Se não for possível confiar totalmente em alguém, não deixe que gerencie sua célula ou uma máquina na célula. Independentemente do uso de segurança administrativa de baixa granularidade, a infraestrutura administrativa do WebSphere Application Server pressupõe um modelo de confiança compartilhado de alta granularidade por toda a célula entre cada processo do WebSphere. Todo servidor de aplicativos contém dentro dele a infraestrutura administrativa, incluindo as APIs internas. No lado positivo, isso torna os servidores de aplicativos altamente independentes e robustos ao eliminar pontos comuns de controle e falha, mas também tem impacto negativo sobre o isolamento. As implicações dessa abordagem incluem:
- Cada servidor de aplicativos em uma célula do WebSphere Application Server tem autoridade administrativa integral sobre toda a célula. Se algum servidor de aplicativos ficar comprometido, todos ficarão.
- Limites de máquina física (computadores separados, LPARs, nós, e assim por diante) praticamente não têm impacto na segurança da célula. A unidade de confiança em uma célula são todos os servidores de aplicativos em todos os nós.
- Os limites de processo têm pouco impacto sobre a segurança da célula. Colocar aplicativos em JVMs de servidor de aplicativos separados ajuda pouco em aumentar seu isolamento da perspectiva de segurança dentro de uma célula.
- As identidades de sistema operacional separadas têm pouco impacto sobre a segurança da célula. Visto que os servidores de aplicativos se comunicam com o restante da célula por meio de vários protocolos que não são gerenciados pelo sistema operacional, as proteções normais do sistema operacional têm pouco efeito.
Isso nos leva a dois tópicos importante: isolamento administrativo e isolamento de aplicativos.
Com o WebSphere Application Server, todos os administradores têm autoridade administrativa (baseada em sua atribuição designada) por padrão na célula inteira. Com o WebSphere Application Server V6.1, um novo recurso conhecido como grupos de autorização foi acrescentado, possibilitando a concessão de autoridades administrativas em um nível de baixa granularidade (servidor, aplicativo, nó, cluster, e assim por diante). No V6.1, os grupos de autorização são suportados apenas por wsadmin. No WebSphere Application Server V7, são suportados também pelo console de administração. Se houver uma célula grande com muitos administradores, tire tempo para analisar estes recursos.
Neste contexto, isolamento de aplicativos se refere basicamente a evitar que ações ilícitas em um aplicativo prejudiquem outro. Esses tipos de ataques são muito difíceis de evitar. A realidade é que produtos de software de infraestrutura, como servidores de aplicativo Java EE, ainda não atingiram o nível de maturidade dos sistemas operacionais multiusuário. Eles não fornecem o tipo de isolamento robusto que um sistema operacional em geral fornece entre diversos usuários.
Isso tudo afeta você?
Em primeiro lugar, os pontos fracos discutidos aqui são apenas internos. Eles podem ser explorados apenas por aplicativos instalados na sua célula. . Na experiência da IBM, a vasta maioria dos usuários do WebSphere Application Server, até mesmo aqueles com infraestrutura compartilhada, não sofrem impacto por esses problemas. Isso se dá porque reconhecem que sua infraestrutura compartilhada está dentro da empresa e executa código aprovado da empresa. Assim, em geral não exigem isolamento de segurança completo dos aplicativos.
Os usuários do WebSphere Application Server afetados pelas questões levantadas aqui em geral têm políticas de segurança extremamente rigorosas, como:
- Políticas formais que exigem que os aplicativos não tenham acesso a outros dados de aplicativo mesmo quando executados em uma infraestrutura compartilhada.
- Com sistemas anteriores ao WebSphere Application Server: o requisito de que cada aplicativo executado em um ID do usuário separado em servidores compartilhados, regras detalhadas sobre permissões de sistema de arquivos, processos dedicados para cada aplicativo e procedimentos estritos de auditoria para impor esses requisitos.
- Diretrizes estritas de segurança corporativa impostas rigorosamente para garantir a conformidade, provavelmente incluindo arquitetura do aplicativo e inspeções de código. Sem inspeções de código, os desenvolvedores podem inserir código que viola a política corporativa.
- Possibilidade de ficar excepcionalmente interessado em ataques remotos que possam comprometer um dos aplicativos e serem usados para comprometer outros aplicativos.
Se isso não parece a sua praia, os problemas desta seção não se aplicam a você. Vá para a próxima seção.
Que ações de mitigação podem ser tomadas?
Que ações de mitigação podem ser tomadas?
- Imponha inspeções rigorosas a todo código do aplicativo. Use também sistemas seguros de gerenciamento de código de origem. Assim, cada mudança de código é rastreada à pessoa que a fez, e as inspeções de código podem ser planejadas e controladas com relação a cada mudança de código. Nessa situação, seria impossível para um único programador inserir código doloso no seu sistema. Em vez disso, diversas pessoas teriam de trabalhar juntas para conseguir isso. Consideramos isso especialmente relevante visto que código de aplicativo doloso pode facilmente causar grande dano em um aplicativo, independentemente do isolamento de aplicativos.
- Se decidir comprar aplicativos comerciais para executar no WebSphere Application Server, assegure-se de comprar produtos apenas de fornecedores confiáveis, teste com cuidado e monitore os aplicativos antes da implementação em produção e monitore-o durante a produção.
- Se for absolutamente necessário, implemente aplicativos em células privadas do WebSphere Application Server. Avalie a possibilidade de usar células diferentes para unidades de negócios diferentes ou outras unidades organizacionais, com base no risco e confiança. Para limitar os custos de hardware, execute de forma segura os nós a partir de diversas células em uma única máquina ou LPAR. Basta executar cada execução com um ID do usuário do sistema operacional diferente, chaves de criptografia diferentes e senhas administrativas diferentes. Isso fornecerá isolamento completo, da perspectiva de segurança.
Se nenhuma dessas abordagens for aceitável, aplique técnicas de fortalecimento de isolamento de aplicativos à infraestrutura. Entenda que essas técnicas exigem muito trabalho. Mais importante ainda, não fornecem garantia e isolamento. Aplicativos na mesma célula -- mesmo com segurança administrativa, segurança do aplicativo e segurança de Java 2 ativadas -- têm o potencial de comprometer outros aplicativos na mesma célula ao acessar recursos deles ou alterar a configuração da célula. Não há maneira de garantir que esse comprometimento seja impossível.
Apesar desses avisos, as seções a seguir documentarão as ações que podem ser tomadas para melhorar significativamente o isolamento de segurança dos aplicativos dentro de uma célula. Possivelmente, você notará logo que tomar essas ações é difícil e caro. Talvez, uma abordagem melhor e menos cara é assegura que seus desenvolvedores de aplicativos forneçam código confiável por meio de práticas rigorosas de contratação, revisão de código e outros controles de gerenciamento. Como antes, essas ações estão alistadas em ordem de prioridade.
- Não especifique aliases gerenciados por componentes em recursos Java EE
- Não defina ID do usuário e senha padrão em um recurso
- Segurança Java 2
- Aproveite a delegação de cadeia segura
- Proteja a senha do TAM WebSEAL TAI
- Cuidado com permissões maiores no código JMX customizado
- Use DynaCache com cuidado
- Use todos os recursos com cuidado
1. Não especifique aliases gerenciados por componentes em recursos Java EE
Qualquer aplicativo Java EE executado dentro da célula tem o potencial de acessar qualquer recurso Java EE. Isso se dá porque os recursos têm nomes JNDI que podem ser procurados por qualquer aplicativo e não há autorização de acesso ao recurso. Assim, se o aplicativo A usa o banco de dados corporativo apenas para defini-lo como fonte de dados, é possível que o aplicativo B na mesma célula possa acessar esse banco de dados.
Quando um aplicativo tenta acessar um recurso chamando getConnection() no factory de recurso (por exemplo, uma fonte de dados um connection factory JMS), o WebSphere Application Server fornece implicitamente informações sobre autenticação para o recurso subjacente se estiver disponível. A decisão de que informações sobre autenticação fornecer depende do modo de autenticação e dos aliases de autenticação de J2C disponíveis. Os detalhes são bem complexos, mas em síntese, qualquer aplicativo pode procurar qualquer recurso no namespace de JNDI. Quando isso é feito, o modo de autenticação de "aplicativo" é usado implicitamente. Isso, por sua vez, significa que o WebSphere Application Server usará um alias de autenticação gerenciado por componente se estiver disponível. Assim, qualquer recurso definido com um alias gerenciado por componente está acessível a qualquer aplicativo na célula. Repare que definir recursos em escopos diferentes não tem impacto nenhum sobre a segurança. Os escopos de recursos são apenas uma conveniência administrativa.
Por outro lado, se apenas um alias gerenciado por contêiner for definido em um recurso (ou não for especificado nenhum alias), um aplicativo mal-intencionado não conseguirá acessar o recurso porque, ao procurá-lo no namespace de JNDI global, é aplicada a autenticação de aplicativo e, com isso, são usados aliases gerenciados por componente. Em resultado disso, não pode ocorrer autenticação implícita porque não há alias gerenciado por componente.
Se for decidido usar essa abordagem, ainda será bom providenciar que os aplicativos adequados tenham acesso a esses recursos. Para isso, esses aplicativos devem especificar referências a recursos locais em seus descritores de implementação para acessar o recurso. Essas referências podem ser então vinculadas no tempo de implementação aos recursos corretos. Se o aplicativo especificar autenticação gerenciada por contêiner na referência, um alias gerenciado por contêiner e definido no próprio recurso será usado implicitamente. Um desenho talvez ajude a esclarecer isso. A Figura 3 mostra o editor de referência do IBM Rational Application Developer onde é especificada a autenticação gerenciada por contêiner em uma referência de conexão JMS.
Figura 3. Referência de recurso de banco de dados usando autenticação gerenciada por contêiner
Há dois problemas com essa abordagem. Primeiro, aliases gerenciados por contêiner foram descontinuados erroneamente no WebSphere Application Server V6.1 (mas não estão mais descontinuados na V7). Segundo, e mais significativo, talvez tenha notado que nem todos os recursos permitem especificar aliases gerenciados por contêiner (por exemplo, factories JMS na V6.1). Nesse caso, a única opção é não fornecer informações sobre autenticação padrão no recurso. Em vez disso, especifique (provavelmente durante o processo de implementação) as informações sobre autenticação para cada referência de recurso no aplicativo (o método de autenticação não importa nesse caso). Isso é um tédio, mas pode ser automatizado usando wsadmin. Pelo menos no caso de MDBs, as informações sobre autenticação podem ser especificadas na especificação de ativação.
Aliases de recuperação de XA não são um problema
Não confunda aliases gerenciados por componente com aliases de recuperação de XA especificados nos recursos. O alias de recuperação de XA é usado apenas durante certos cenários de recuperação que envolvem falhas transacionais. Normalmente não é acessível a aplicativos se a segurança Java 2 estiver ativada e as permissões padrão tiverem sido usadas.
2. Não defina ID do usuário e senha padrão em um recurso
Um corolário do item anterior é que não se deve definir um ID do usuário e senha padrão em um recurso. Se isso for feito, qualquer aplicativo dentro da célula poderá procurar o recurso e, implicitamente, usar o ID do usuário e a senha fornecidos.
Como já mencionado, todos os servidor de aplicativos contêm a infraestrutura administrativa do WebSphere Application Server e, assim, as APIs para executar a maioria das operações administrativas. Um programador de aplicativo que aprenda as APIs pode escrever um aplicativo que chame qualquer dessas APIs e executar essencialmente qualquer operação administrativa. Além disso, o repositório de configuração do sistema de arquivos contém muitas informações sensíveis (como senhas). Qualquer aplicativo pode usar E/S comum de Java para ler esses arquivos.
O WebSphere Application Server inclui suporte a segurança Java 2 conforme fornecida pelo padrão JDK. A IBM aprimorou o suporte a Java 2 para impor as especificações Java EE, bem como para proteger as APIs internas do WebSphere Application Server contra acesso não autorizado. Simplesmente ativando a segurança Java 2, essas regras são impostas automaticamente. Assim, ativando a segurança Java 2, proteção adicional substancial é acrescentada ao tempo de execução para evitar acesso ilegal ao aplicativo. Contudo, sem um processo formal para revisar as permissões concedidas, não há absolutamente nenhum valor em usar a segurança Java 2 – de fato, ativá-la sem uma validação de arquivo de políticas torna a situação pior, porque não há melhoria na segurança, o desenvolvimento de aplicativo é mais difícil e o desempenho sofre um pouco.
Depois que a segurança Java 2 é ativada, os aplicativos são limitados por padrão a um conjunto muito pequeno de permissões "seguras". Se um aplicativo precisa de mais permissões, em geral deve definir essas permissões solicitadas no arquivo was.policy contido dentro do EAR. Quando o aplicativo é executado, o arquivo was.policy é lido, e essas permissões são incluídas no conjunto padrão. Como deve ser óbvio, essa é uma brecha d e segurança em potencial. Para tornar isso viável, será necessário um processo rigoroso e bem-definido para determinar, revisar e depois impor as permissões de Java 2 para cada aplicativo. Se um aplicativo tentar solicitar permissões inaceitáveis (mesmo durante uma correção emergencial) rejeite-o. Deve haver um processo formal que inclua uma revisão de segurança para determinar que permissões estarão autorizadas para o aplicativo. Mesmo com um processo formal, ativar a segurança Java 2 deve ser encarado com cautela. Além do esforço adicional envolvido, muitas vezes um mandato de "ativar segurança Java 2" resulta no uso de arquivos de políticas que fornecem pouca proteção significativa para tornar a implementação possível, o que, além de resultar em esforço adicional, produz um falso senso de segurança.
O processo de revisão e verificação durante a instalação pode ser entediante. Mas há uma abordagem alternativa. Primeiro, para um conjunto grande de ambientes, a maioria dos aplicativos precisará de um conjunto comum de permissões adicionais. Se isso for possível, a equipe de infraestrutura pode colocar as permissões padrão para todos os aplicativos no arquivo app.policy naquele nó. Depois, apenas os aplicativos que precisem de permissões incomuns serão colocados no was.policy e exigirão verificação adicional. Pode-se ir mais além ao proibir o uso de was.policy e exigir que todas as permissões sejam incluídas em app.policy pela equipe de administração. Isso complica a implementação de algumas maneiras (edição de um arquivo comum), mas reduz o risco de um aplicativo obter permissões impróprias.
4. Aproveite a delegação de cadeia segura
Um dos grandes benefícios de um servidor de aplicativos é que as informações de identidade do usuário são enviadas automaticamente entre as camadas do sistema e entre aplicativos. Isso lhe fornece conexão única (SSO) transparente. Infelizmente, isso tem um efeito colateral potencialmente perigoso: personificação indevida.
O problema aqui é que, quando um usuário autentica para usar o aplicativo A, é possível q o aplicativo A faça uma chamada EJB remoto para o aplicativo B. O aplicativo B então vê as credenciais do usuário original. Em geral, isso é bom. Mas, e se o aplicativo A não for confiável? Nesse caso, o usuário que acessar o aplicativo A terá motivos para temer que ele acesse o aplicativo B em seu nome usando delegação. Imagine as implicações disso se o aplicativo A for “desimportante” e, portanto, desenvolvido de forma ad hoc, enquanto o aplicativo B for altamente sensível e gerencia informação confidencial. O problema aqui é que o aplicativo terá de confiar no aplicativo A simplesmente porque eles compartilham uma região de segurança em comum. Isso é ruim.
Há uma forma de contornar esse problema. Use um recurso do WebSphere Application Server descrito basicamente como “delegação em cadeia segura”. Usando WSSecurityHelper.getCallerList() ou getServerList(), o aplicativo B pode determinar para que aplicativos e servidores uma solicitação é passada. Se o aplicativo B for altamente sensível, talvez ele exija que a lista esteja vazia, implicando que esteja sendo usada diretamente pelo usuário. Consulte o Centro de Informações do WebSphere Application Server para obter mais informações sobre WSSecurityHelper.
5. Proteja a senha de TAM WebSEAL TAI
Quando SSO é configurado entre o IBM Tivoli Access Manager WebSEAL e o WebSphere Server, o WebSEAL envia sua senha secreta no cabeçalho HTTP em cada solicitação para garantir que o TAI possa funcionar quando chamado. Embora em geral isso não seja preocupante, visto que a conexão deve ser criptografada usando SSL, a senha do WebSEAL fica exposta a aplicativos da Web em execução no WebSphere Application Server. (Embora esta seção trate especificamente do TAI WebSEAL, essa exposição ocorre em qualquer TAI que envie uma senha para estabelecer a confiança.)
Um aplicativo da Web em execução no WebSphere Application Server e que não for confiável poderia pegar essa senha, abrir uma conexão HTTP com um servidor de aplicativos e afirmar ter qualquer identidade de usuário. Isso possibilitaria que um aplicativo intruso escrito de forma muito inteligente agisse como qualquer um.
Se estiver preocupado com esse tipo de ataque (que pode ser facilmente evitado com inspeções de código), evite que clientes não confiáveis se conectem ao contêiner de Web. Para isso, basta configurar um listener HTTPS mutuamente autenticado no contêiner de Web, como descrevemos na Parte 1. Daí, o aplicativo será incapaz de abrir uma conexão HTTPS com o contêiner de Web porque não terá a chave privada correta (apenas o WebSEAL ou o servidor da Web a terão).
6. Cuidado com permissões mais altas no código JMX customizado
Um aspecto do MBeans ao qual é preciso ficar atento é que seu uso implica em permissões elevadas de segurança Java 2. Se um aplicativo registra MBeans programaticamente com o tempo de execução do servidor de aplicativos, deve-se conceder permissões administrativas elevadas de código de chamada para que ele funcione. Essa habilidade poderia ser usada para executar operações administrativas ilícitas. Faça isso com grande cuidado. Uma boa abordagem é criar um módulo separado apenas para registrar o MBean e conceder apenas àquele módulo as permissões necessárias.
Um segundo modo de carregar MBeans é especificá-los administrativamente como Extension MBeans (a abordagem recomendada). Isso elimina o problema de ter de conceder de forma explícita autoridade administrativa ao código do aplicativo -- mas gera um novo problema: os MBeans agora são carregados por um carregador de classe do WebSphere Application Server de nível bem baixo, que é mais confiável. Em resultado disso, seus MBeans terão substancialmente mais acesso a APIs de WebSphere Application Server do que o código do usuário comum.
Se você decidir desenvolver MBeans customizados, revise com cuidado o código e o uso para garantir que não está introduzindo pontos fracos de segurança no sistema.
DynaCache fornece um cache compartilhado e distribuído para aplicativos do WebSphere Application Server. Contudo, não há controle de acesso no DynaCache; qualquer aplicativo em execução em um servidor de aplicativos pode acessar qualquer cache ao qual o servidor de aplicativos tenha acesso. Mais precisamente, qualquer aplicativo pode acessar qualquer cache acessível a partir daquele servidor e depois ver (ou modificar) todo o seu conteúdo.
Há dois tipos de caches a levar em conta. O próprio servidor de aplicativos mantém alguns caches internos ocultos que podem conter informações sensíveis (cache de servlet, caches de serviços da Web, caches de segurança). Também há caches criados pelo usuário, como caches Object Cache que são visíveis via JNDI.
Os caches internos não são registrados no JNDI de modo que são mais difíceis de localizar, mas pode-se acessá-los usando APIs internas. Um ponto positivo é que esses caches são por padrão replicados apenas para servidores dentro de um cluster, de modo que podemos ter certeza de que aplicativos em outros clusters não poderão ver os caches de informações em clusters diferentes.
Os caches definidos pelo usuário são visíveis no JNDI e podem ser procurados a partir de qualquer servidor na mesma célula. Um aplicativo pode modificar ou ler o cache depois de procurá-lo. Não existe maneira de impedir isso. Portanto, se sua preocupação for o isolamento de aplicativos, não use caches criados pelo usuário.
8. Use todos os recursos com cuidado
Muitos outros recursos do WebSphere Application Server, como áreas de trabalho, não permitem autorização no nível do aplicativo. Como acontece com DynaCache, use esses recursos com cuidado. Se sua preocupação for o isolamento de aplicativos, avalie com cuidado cada cenário de uso, procure pontos fracos em potencial e aja de acordo.
Normalmente, as células do WebSphere Application Server não confiam umas nas outras, de modo que é impossível usar SSO entre células. Mas é possível configurar as células para oferecerem suporte a SSO entre elas. Há muitas boas razões para fazer isso, mas ao fazê-lo estamos ampliando o domínio de confiança das células e é preciso ficar atento às implicações de segurança. Há três questões a levar em conta:
- Chaves LTPA compartilhadas
Para que duas células participem de forma transparente de um domínio SSO, elas devem compartilhar regiões compatíveis (ou seja, a mesma região no WebSphere Application Server V6.1, e regiões confiáveis na V7), compartilhar as chaves de criptografia LTPA e usar tokens de autenticação SSL compatíveis (para o tráfego entre os servidores). Tokens de autenticação SSL compatíveis simplesmente significam que o servidor de chamada deve ter acesso ao certificado de assinatura que corresponde ao certificado do servidor de recebimento, como se dá com qualquer comunicação SSL.
Depois de assegurar que duas células compartilham a mesma chave de criptografia LTPA, cria-se uma situação em que cada célula tem a capacidade de criar credenciais para outra célula – incluindo credenciais administrativas. Portanto, se uma célula ficar comprometida, ambas ficarão. Se estiver usando diversas células como modo de obter isolamento de aplicativos por razões de segurança, será preciso ativar a segurança Java 2 para limitar o acesso às APIs internas do WebSphere Application Server.
Se seu objetivo ao compartilhar a mesma chave de criptografia LTPA for apenas criar SSO na Web sem compartilhar assuntos customizados, poderá obter o mesmo resultado usando um servidor proxy de autenticação, como o WebSEAL do Tivoli Access Manager, sem compartilhar as chaves de criptografia LTPA.
- Asserção de identidade CSIv2
Se quiser, é possível fazer chamadas IIOP entre células e evitar compartilhar chaves de criptografia LTPA. Para isso, é preciso usar a asserção de identidade CSIv2 (isso também funciona ao entrar em contato com servidores EJB não WebSphere Application Server).
Considere este cenário simples: Suponha duas células, A e B, cada qual com servidores. Suponha também que os servidores da célula A precisem fazer chamadas RMI/IIOP para os servidores na célula B, mas não o contrário. Para que isso funcione, configure a asserção de identidade CSIv2. Os servidores da célula A farão asserção de identidade para os da célula B. Como configurar a asserção de identidade CSIv2 não será descrito aqui, apenas as implicações de fazê-lo.
Para que os servidores na célula B aceitem a asserção de identidade, o servidor de envio de dados na célula A deve se autenticar primeiro. Há duas maneiras de fazer isso no CSIv2: autenticação básica, na qual o servidor de envio de dados envia seu ID do usuário e senha, e autenticação por certificado de cliente, na qual o servidor de envio de dados se autentica usando seu próprio certificado.
Quando a autenticação está concluída, o servidor de recebimento verifica se o servidor de envio de dados é confiável para executar a asserção de identidade. Isso é configurado nos painéis de configuração do CSIv2, após o que o servidor de envio de dados envia ao servidor de recebimento de dados as informações de identificação do usuário de destino.
Vamos analisar as implicações dessa abordagem para a confiança. Os servidores na célula B confiam na célula A ao aceitar a asserção de identidade dela. Se a célula A for comprometida, a célula B também será -- mas quais são as implicações para a célula A?
- Se a célula A enviar o ID do usuário e senha do servidor para estabelecer confiança (o padrão), estará revelando seu ID do usuário e senha do servidor com autoridade administrativa integral para os servidores na célula B. Assim, a célula A agora confiará completamente em B. Isso não é nenhuma melhoria em relação a apenas compartilhar chaves LTPA.
- Se em vez disso a célula A enviar um ID do usuário e senha especificados (que estiverem configurados apenas para esse propósito), não estará revelando nada de importância para a célula B. A célula A não terá confiança na célula B.
- Se a célula A se autenticar usando seu próprio certificado, não revelará nada à célula B. A célula A não terá confiança na célula B.
Em resumo, a fim de que a célula A faça asserção de identidade para a célula B, esta última deve confiar na A. Isso é óbvio. Se não for desejável que a célula A confie na B, use um ID do usuário e senha especificados ou autenticação de certificado para a etapa de autenticação entre servidores, não o padrão, que é o envio do ID do servidor e da senha.
- Retornos de chamada para propagação de assunto
Se estiver sendo aproveitada a propagação de assunto entre células, lembre-se de que estas também podem estar fazendo chamadas fora da banda entre si para obterem os assuntos. Para deixar mais claro, veja um exemplo: Suponhamos que há dois servidores que compartilham um domínio SSO. Um usuário acessa o servidor A usando um navegador da Web e obtém uma sessão de autenticação (representada por um cookie LTPA no navegador). O usuário então acessa o servidor B. Este tenta obter o assunto do usuário do servidor A. Isso é chamado de propagação de assunto. Isso acontece trivialmente se os servidores estão no mesmo domínio de replicação do DynaCache. Se não estiverem no mesmo domínio, os retornos de chamada JMX são usados para obter o assunto. Naturalmente, servidores em células diferentes não estão no mesmo domínio de replicação do DynaCache. Portanto, nesse exemplo, o servidor B fará uma chamada JMX segura para o servidor A a fim de obter o assunto do usuário.
Como se dá com qualquer chamada administrativa, a chamada JMX exige autenticação e autorização. Nesse caso (a partir do WebSphere Application Server V6.1), essa confiança é estabelecida implicitamente pelo uso da chave LTPA compartilhada. Visto que o servidor B compartilha as chaves de criptografia LTPA como servidor A, este último confia nele para pedir informações de assunto.
No geral, os retornos de chamada não têm impacto significativo sobre a segurança além dos riscos já mencionados para o compartilhamento de chaves LTPA, mas eles introduzem outro caminho de rede que alguns talvez considerem um risco.
Essa situação não se aplica quando ocorre propagação de recebimento de dados usando IIOP. Nesse caso, o servidor de envio de dados simplesmente envia o assunto para o servidor de recebimento de dados. Não são necessários retornos de chamada JMX.
Embora esse tópico não esteja diretamente relacionado a fortalecimento, é um problema comum que se infiltra em designs de sistema que não levam em conta a segurança logo no início. Seja sempre muito cuidadoso ao controlar onde as identidades são estabelecidas e como são propagadas (se puderem ser). Muitos designs simplesmente supõem que a identidade é conhecida quando tecnologias práticas tornam isso inviável. Certifique-se de analisar com cuidado o fluxo de identidade no seu aplicativo para evitar desastres mais adiante no ciclo de desenvolvimento. Abaixo, dois casos comuns que envolvem recursos externos e, para o WebSphere Application Server V6 e posterior, as soluções.
- Autenticação de banco de dados versus de WebSphere Application Server
Um dos principais desafios dos sistemas corporativos é implementar adequadamente controles fortes de segurança do sistema. Em resumo, os dados críticos precisam ser protegidos com autorizações adequadas. O que torna esse desafio especialmente difícil em sistemas Java EE multicamada nos quais o código do aplicativo Java EE entra em contato com um banco de dados (usando JDBC, SQLJ, JPA ou beans CMP) é que, tradicionalmente, as informações de identificação do usuário são perdidas. "Usuário" nesse caso significa o usuário em nome de quem o aplicativo está em execução; ou seja, se Bob se autentica no aplicativo usando a segurança Java EE padrão, Bob é o usuário.
Em sistemas típicos baseados em Java EE, o contêiner mantém um conjunto de conexões autenticadas. Enquanto cada usuário se autentica no servidor de aplicativos (usando um dos vários mecanismos de autenticação do Java EE), as informações de identificação deles não ficam disponíveis no banco de dados. Isso se dá porque todo acesso ao banco de dados é feito usando uma entre várias conexões compartilhadas comuns do conjunto de conexões. Historicamente, isso tem resultado em os aplicativos terem de reinventar autorização de nível de banco de dados e funções de auditoria existentes dentro da camada de aplicativo. Isso é um desperdício se feito adequadamente e provavelmente é inseguro se mal feito.
Com o WebSphere Application Server V6, há uma solução elegante para esse problema. Com a V6.1, a propagação de identidade para o IBM DB2® é fornecida para uso imediato.
- MDBs não são executados em identidade enfileirada
Quando uma mensagem é enfileirada em um sistema de mensagens, a identidade do responsável pela chamada original normalmente não é relevante. Ou seja, o mecanismo do sistema de mensagens autoriza o acesso à fila com base na identidade de conexão, como já mencionado. Em geral, a fila nem registra a identidade do usuário.
Quando a mensagem é mandada para fora da fila, em geral por um MDB no Java EE, a identidade do responsável pela chamada original não está disponível -- mesmo que estivesse, seria ignorada. Os MDBs são executados em uma identidade de Java EE anônima ou em uma identidade "run-as" estática. Não são executados sob a identidade de fila de mensagem.
Não há suporte direto no WebSphere Application Server para atender a esse problema. Mas é possível fazer isso funcionar se estiver disposto a escrever um código customizado. A partir do WebSphere Application Server V6.0.2, o WebSphere Application Server suporta asserção de identidade do lado do servidor. Ou seja, o código do lado do servidor pode mudar sua identidade "run-as" Java EE usando JAAS sem fornecer uma senha. Em vez disso, ele simplesmente faz uma asserção das informações de identidade do usuário. Aqui está um exemplo simples disso usando código Java:
Listagem 3CallbackHandler wscbh = WSCallbackHandlerFactory.getInstance().getCallbackHandler(username, null); LoginContext lc = new LoginContext("system.RMI_INBOUND", wscbh); lc.login();
Repare que não é fornecida senha.
Isso pode ser combinado a ideias deste artigo sobre autenticação avançada para fazer a asserção de assuntos customizados. Também é possível fazer o WebSphere Application Server criar um cookie de LTPA, fazendo-o trabalhar para aplicativos da Web, como descrito neste artigo do Centro de Informações.
É claro que isso tem implicações de segurança e, assim, essa chamada é bloqueada por padrão ao usar a segurança Java 2. Mas é possível permiti-la concedendo ao código do aplicativo as permissões de segurança necessárias para o Java 2.
Limitações do WebSphere Application Server
Em geral, por meio de configuração cuidadosa, é possível criar um ambiente robusto e muito seguro usando o WebSphere Application Server. Contudo, esteja atento a uma limitação que costuma ser pequena e obscura, mas que pode ter um impacto para você.
Identidade do destino não verificada
Um aspecto muito sutil dos sistemas seguros é o conceito de validar o destino de uma solicitação. Normalmente, quando se pensa em autenticação, pensa-se em um servidor autenticando o cliente, mas e o contrário? Como o cliente sabe que o servidor é de fato o servidor desejado? A maioria de nós não percebe isso, mas os navegadores da Web executam essa verificação de forma implícita todos os dias. Quando é usado HTTPS, o navegador da Web valida que o nome do host do servidor da Web é o mesmo que o assunto do servidor da Web no seu certificado. Isso assegura que o servidor seja realmente aquele desejado pelo usuário (supondo-se, é claro, que o usuário saiba que nome do host acabou de ser usado; muitos não são assim tão cuidadosos).
O que talvez não seja óbvio é que a verificação executada pelos navegadores da Web não é parte inerente do SSL - é uma verificação específica do navegador executada fora do SSL. O inicializador (o servidor de chamada) precisa executar essa verificação do certificado de forma específica. O WebSphere Application Server não executa essa verificação. Portanto, quando um servidor de aplicativos (ou cliente) abre uma conexão SSL para um servidor, ele não está garantindo que o servidor seja realmente aquele desejado. Embora seja altamente improvável, é possível que um hacker que pudesse comprometer seu DNS interno ou rede pudesse também inserir um servidor malicioso na célula do WebSphere Application Server e roubar informações. Esse seria um ataque incrivelmente difícil -- muitos outros ataques são muito mais fáceis --, mas mesmo assim é bom estar ciente dessa possibilidade.
Pode-se remover todas as chaves de assinatura desnecessárias dos arquivos de armazenamento de confiança do servidor de aplicativos para evitar isso. Apenas certificados emitidos por assinantes confiáveis podem ser usados para executar esse ataque. Certificados não verificáveis do lado do servidor serão rejeitados pelos clientes durante o handshake SSL. Se a lista confiável for pequena (talvez contendo apenas os certificados padrão autoassinados), esse ataque se torna muito difícil. Visto que os armazenamentos de confiança não incluem por padrão nenhum assinante CA, o único assinante padrão com o qual se deve estar preocupado é o certificado de assinatura simulado para compatibilidade com versões anteriores. Se desejar incluir um certificado de assinatura CA no armazenamento de confiança de nível de célula compartilhado, estará se expondo a esse risco (embora seja pequeno).
Proteja seu ambiente de desenvolvimento de desktop
Ao pensar em fortalecimento da segurança, a maioria das pessoas tende a se concentrar nos sistemas de produção, que, naturalmente, são mais importantes. Mas também se deve gastar algum tempo garantindo que outros computadores, incluindo seus sistemas de desktop, também estejam razoavelmente seguros.
Para quem executa o IBM Rational Application Developer (ou o IBM WebSphere Studio mais antigo), essa é uma preocupação grave. O IDE de desktop contém um ambiente de tempo de execução do WebSphere Application Server que é integrado e totalmente funcional. Esse servidor de aplicativos tem portas abertas e é vulnerável a acesso remoto exatamente das maneiras descritas antes neste artigo. Cuide disso.
Fortalecendo o servidor de aplicativos integrado
No mínimo, deve-se ativar a segurança administrativa no ambiente de teste do servidor de aplicativos integrado. O Rational Application Developer 7.5 faz isso por padrão. Isso evitará os tipos mais escandalosos de ataque nos quais um intruso pode usar a infraestrutura administrativa integrada para implementar aplicativos mal-intencionados em seu desktop. Se você estiver executando o Rational Application Developer com autoridade administrativa, isso é muito grave. Talvez você também queira executar algumas outras etapas de fortalecimento indicadas neste artigo, embora garantir que a infraestrutura administrativa é segura seja, de longe, a etapa mais importante.
Como alternativa ao fortalecimento do servidor de aplicativos integrado, pode-se em vez disso decidir instalar um firewall de desktop que bloqueie o acesso ao computador. Essa abordagem pode ser bem eficaz se configurada de forma adequada. Um firewall que confie na inteira rede corporativa interna é de pouco valor nesse contexto.
Migrando de versões anteriores
Migrar de versão para versão do WebSphere Application Server levanta a questão da compatibilidade com versões anteriores. Da perspectiva da segurança, a abordagem recomendada para a migração de aplicativo é criar uma célula nova completa (do zero) e depois instalar seus aplicativos na nova célula (após testes rigorosos, é claro). Usando essa abordagem, pode-se beneficiar de todas as mudanças padrão na configuração feitas entre os releases.
Se, em vez disso, você decidir usar as ferramentas de migração de célula do WebSphere Application Server, que copiam a configuração e os aplicativos existentes para uma nova célula, você não se beneficiará de muitas melhorias feitas ao fortalecimento de segurança em cada grande release. Como é de esperar, isso se dá porque procuramos fazer o mínimo de mudanças possível na configuração existente a fim de assegurar que os aplicativos continuem a funcionar sem alteração. O efeito colateral disso é que as mudanças feitas na segurança por padrão não entrarão em vigor. Assim, por exemplo, se você migrar usando as ferramentas do WebSphere Application Server V6 para V7, terá de ler as duas versões, V6 e V7, deste artigo sobre fortalecimento, em vez de apenas a versão mais recente.
Este artigo em duas partes abrangeu muita coisa. Embora tenham sido discutidos aqui muitos aspectos da segurança, o tema principal de fortalecimento de um ambiente do WebSphere Application Server foi o foco principal. Esperamos que agora você disponha de informações básicas de que necessita para tornar seus sistemas Java EE seguros. Embora não tratadas aqui, procure outras fontes de informações para fortalecer outras partes da sua infraestrutura. O WebSphere Application Server é apenas uma peça de um quebra-cabeça muito maior.
Um subconjunto de itens descritos neste artigo pode ser verificado usando uma ferramenta automática conhecida como IBM Security Scanner for WebSphere Application Server, disponível para download.
Por fim, se estiver interessado em aprender mais sobre a segurança no WebSphere Application Server, entre em contato com os Serviços de Software IBM para WebSphere e obtenha uma aula customizada no seu local sobre segurança no WebSphere Application Server. Essa aula abrange fortalecimento de segurança, customização de autenticação, integração conexão única e uma variedade de outros tópicos em profundidade.
Gostaria de agradecer aos meus colegas Martin Lansche, Bill Hines, Bill O’Donnell, Paul Ilechko, Simon Kapadia e Tom Alcott por seus comentários e assistência valiosos.
Aprender
- Fortalecimento de segurança avançada do WebSphere Application Server V7, Parte 1: Visão geral e abordagem do fortalecimento de segurança
- Fortalecimento de segurança avançada do WebSphere Application Server V6, Parte 1
- Fortalecimento de segurança avançada do WebSphere Application Server V6, Parte 2
- Informações sobre o Rational AppScan
- The Top 5 Internal Security Threatsde Cindy Waxer
- Enterprise Application Security
- Redbook: IBM WebSphere 6.0 Security, SG-
246316, IBM Corp, 2005
- Understanding and Deploying LDAP Directory Services de Timothy Howes, et al, ISBN 0672323168
- Buffer Overflows – What Are They and What Can I Do About Them? de Larry Rodgers, CERT, 2001
- Understanding Malicious Content Mitigation for Web Developers
- Java Security Coding Guidelines
- Segurança de sistema de mensagens
- Securing connections between WebSphere Application Server and WebSphere MQ
- IBM WebSphere: Deployment and Advanced Configuration de Roland Barcia, Tom Alcott, Bill Hines e Keys Botzum, ISBN 0-131468-626
- Advanced Authentication in WebSphere Application Server
- Database identity propagation in WebSphere Application Server V6
- Informações de fortalecimento Apache (aplica-se também a IHS)
- Building Secure Servers with LINUX
- Firewall Port Assignments in WebSphere Application Server
- The (XML) threat is out there
- DB2 Technical Tip: Setting up SSL
- FIPS Configuration
- SSL, Certificate, and Key Management Enhancements in WebSphere Application Server V6.1
- WebSphere MQ Security heats up
- Web site OWASP que trata dos riscos de roubo de cookies no HTTP Only flag
- www.keysbotzum.com
-
WebSphere no IBM developerWorks
Obter produtos e tecnologias
- IBM Security Scanner Tool for WebSphere Application Server do suporte IBM
-
Faça o download da versão de avaliação do WebSphere Application Server V7
-
Faça o download do WebSphere Application Server for Developers - uma oferta sem custo
Keys Botzum é Senior Technical Staff Member dos Serviços de Software IBM para WebSphere. O Sr. Botzum tem mais de 10 anos de experiência em design de sistemas distribuídos em grande escala e, além disso, é especializado em segurança. O Sr. Botzum já trabalhou com uma variedade de tecnologias distribuídas, incluindo Sun RPC, DCE, CORBA, AFS e DFS. Recentemente, ele se concentra em J2EE e tecnologias relacionadas. Ele tem mestrado em Ciências da Computação pela Universidade Stanford e bacharelado em Matemática Aplicada/Ciências da Computação pela Universidade Carnegie Mellon. O Sr. Botzum já publicou diversos artigos sobre WebSphere e segurança no WebSphere. Outros artigos e apresentações de Keys Botzum se encontram em http://www.keysbotzum.com, bem como no WebSphere no IBM developerWorks . Ele também é coautor de IBM WebSphere: Deployment and Advanced Configuration.