Menu ▾ ▴

seguranca

Mobius One

Home > Segurança para produção

Segurança para produção

Delphi e Lazarus · Nível: intermediário

Em uma frase: a lista do que ligar antes de pôr um servidor RAL na internet.

Quase tudo vem desligado para não mudar o comportamento de quem atualiza. Ligar
é com você. Na 1.2 são propriedades do servidor; na 2.0 🚧 são
plugins.

A lista

# O quê Até a 1.2 A partir da 2.0 🚧
1 HTTPS HTTPS igual, ou o certificado automático
2 Login nas rotas que não são públicas Authentication (Autenticação) igual
3 Não mostrar o texto do erro num 500 (pode ter nome de tabela e SQL) HideErrorDetails := True (1.2 🚧) igual
4 Cabeçalhos de segurança SecurityHeaders := [rshContentTypeOptions, rshFrameOptions, rshReferrerPolicy, rshStrictTransport] (1.2 🚧) TRALSecurityHeadersPlugin.Headers
5 CORS só para as origens que você conhece CORSOptions.AllowOrigin := 'https://meusite.com.br' TRALCORSPlugin.Options.AllowOrigin
6 Força bruta: bloquear o IP depois de N senhas erradas Security.Options := [rsoBruteForceProtection], Security.BruteForce TRALBruteForcePlugin (MaxTry, ExpirationTime)
7 Flood: recusar quem pede rápido demais rsoFloodProtection, Security.FloodTimeInterval TRALFloodPlugin.Interval
8 ../ no caminho rsoPathTransvBlackList TRALPathTraversalPlugin
9 Tamanho máximo do pedido MaxRequestSize (bytes) TRALLimitsPlugin.MaxRequestSize
10 Compressão-bomba (1 MB que vira 1 GB) RALMaxDecompressedSize := 512 * 1024 * 1024 (unit RALCompress) igual
11 Banco pela rede: aprovar cada SQL TRALDBModule.OnValidateSQL igual
12 Arquivos: servir só a pasta certa TRALWebModule.DocumentRoot, BlockedExtensions, FollowLinks := False igual
13 Fila de pedidos, para não cair com pico — TRALConcurrencyPlugin (Desempenho)
14 Registrar os erros evento OnServerError do servidor igual
15 XML que chega (SOAP, storage XML) — os limites de ReaderOptions/Options (XML); no SOAP o DOCTYPE é sempre recusado

Os itens 3 a 9 respondem com 403, 413 ou 405 antes de a sua rota rodar.

Detalhes que pegam

CORS. Desde a 1.2 🚧, AllowOrigin vazio recusa toda página de outro site
(antes era *, todo mundo). * com AllowCredentials não funciona: os navegadores
recusam. Vários sites: separe por vírgula.

Cabeçalhos de segurança. O que cada opção envia (os valores que a OWASP
recomenda para uma API):

Opção Cabeçalho enviado
rshContentTypeOptions X-Content-Type-Options: nosniff
rshFrameOptions X-Frame-Options: DENY
rshReferrerPolicy Referrer-Policy: no-referrer
rshStrictTransport Strict-Transport-Security: max-age=31536000, só em HTTPS. Atrás de um proxy que faz o HTTPS, quem envia é o proxy
rshContentSecurityPolicy Content-Security-Policy: default-src 'none'; frame-ancestors 'none'

O último proíbe tudo numa página: use só em servidor que não serve HTML (sem
WebModule e sem Swagger). Páginas de um WebModule precisam de uma política própria.

Força bruta. Desde a 1.2 🚧 só conta senha conferida e recusada: pedido
sem login, token vencido e 403 da sua regra não contam. Libere seus próprios IPs
(lista branca) para não se bloquear.

OnValidateSQL (banco pela rede, DBWare). Sem ele, qualquer cliente
logado roda qualquer SQL, inclusive DELETE. Exemplo: só deixar SELECT:

procedure TForm1.ValidaSQL(ASender: TObject; ARequest: TRALRequest;
  const ASQL: StringRAL; var AAllow: Boolean);
begin
  AAllow := SameText(Copy(Trim(ASQL), 1, 6), 'SELECT');
end;

No DAO do FireDAC (TRALFDConnection), o ApplyUpdates tem o seu próprio:
OnValidateApplyUpdates (1.2 🚧).

WebModule. Desde a 1.2 🚧, DocumentRoot vazio não serve nada (antes servia a
pasta do executável, com .ini, certificados e banco). Aponte para uma pasta só
de arquivos públicos e bloqueie extensões perigosas:

RALWebModule1.DocumentRoot := 'www';                      // pasta ao lado do .exe
RALWebModule1.BlockedExtensions.Text := 'ini'#13'db'#13'sqlite'#13'pfx'#13'key';
RALWebModule1.FollowLinks := False;                        // não seguir atalhos

Chaves e senhas (JWT, AES, certificado): fora do código-fonte e do .dfm.
Leia de variável de ambiente ou de arquivo protegido ao iniciar.

Swagger público mostra todas as rotas: RequireAuth := True no
TRALSwaggerModule. O mesmo vale para o WSDL do servidor SOAP:
WSDLRequireAuth := True.

XML (2.0 🚧). O leitor do RAL limita profundidade, atributos e expansão de
entidades, e nunca lê uma entidade externa sem o OnResolveEntity - o que
fecha a bomba de entidades e o XXE. Não ligue OnResolveEntity para XML que
vem de fora. Ver XML.

Atualize o RAL. O changelog tem uma seção Security com as falhas
corrigidas.

Veja também


Related

Wiki: Home
Wiki: _Sidebar
Wiki: autenticacao
Wiki: dbware
Wiki: desempenho
Wiki: https
Wiki: modulo soap
Wiki: mqtt seguranca
Wiki: pedido resposta
Wiki: plugins
Wiki: problemas comuns
Wiki: producao
Wiki: recursos
Wiki: roadmap
Wiki: stored procedures
Wiki: swagger
Wiki: web module
Wiki: xml