Executando verificação de segurança...
10

Jamais confie no front-end

jamais confie no front-end

É isso mesmo! Jamais confie no front-end. Cheirando a um certo “clickbait” neste título? Sim, não posso negar.🤭 No entanto, o 'front-end' mencionado neste título não se refere ao profissional da área, e sim à camada da aplicação responsável pela interface com a qual os usuários interagem.

Direcionado a desenvolvedores que estão começando sua jornada.

À medida que você inicia sua trajetória no mundo do desenvolvimento, entender a interação entre as camadas de uma aplicação e reconhecer a função crítica de cada uma na segurança e eficiência do sistema é vital. O front-end, muitas vezes visto somente como o ponto de contato visual e interativo com o usuário, tem um papel que vai muito além, incluindo a defesa da integridade e da performance da aplicação.

Este texto aborda a necessidade crucial de manter uma clara separação de responsabilidades, argumentando em defesa da qualidade do front-end ao isolar essa camada da carga excessiva de regras de negócio. Implementar regras de negócio de forma desenfreada no front-end pode comprometer não apenas a segurança, mas também a usabilidade e a manutenção da aplicação. É essencial entender como defender essa separação, garantindo que o front-end possa focar no que faz de melhor: proporcionar uma experiência de usuário de alta qualidade, ao mesmo tempo que se mantém seguro e eficiente.

O front-end é como uma casca de ovo

A casca do ovo é um exemplo incrível de design natural que, ao mesmo tempo, é resistente e frágil. Ela é forte o suficiente para proteger o embrião contra danos e variações no ambiente, funcionando como um escudo. No entanto, a forma e a estrutura do ovo são otimizadas para não apenas proteger, mas também para garantir que, quando chega a hora do filhote nascer, a casca seja suficientemente frágil. Isso permite que o filhote consiga quebrá-la e sair com facilidade. Embora esse equilíbrio entre ser dura para proteger e frágil para facilitar a eclosão seja essencial para a sobrevivência das aves, ele também introduz uma vulnerabilidade: a casca pode ser facilmente superada por predadores. Para mitigar essa ameaça, os pais das aves empregam várias estratégias de proteção, como escolher locais de nidificação seguros, camuflar o ninho, defender agressivamente a área, e até mesmo usar táticas de distração para afastar os predadores. Essas ações complementam as defesas naturais do ovo, mostrando como a natureza desenvolve soluções complexas e inteligentes, mesmo quando incluem compromissos inerentes à segurança do embrião.

Assim como a casca do ovo protege e conecta o seu conteúdo ao mundo exterior, o front-end de uma aplicação digital atua como a interface de interação entre os usuários e a aplicação, operando dentro do ambiente de um navegador. Além de enriquecer a experiência do usuário com sua funcionalidade e estética, o design do front-end precisa lidar com desafios específicos de segurança, pois está constantemente exposto e vulnerável no ecossistema do navegador. É fundamental, portanto, que os desenvolvedores de front-end sejam capazes de criar interfaces seguras e intuitivas, que garantam uma experiência de usuário satisfatória, mas também segura.

No entanto, apesar de sua importância crítica, o front-end carrega uma vulnerabilidade inerente: ele opera nas limitações e dos riscos do navegador, um ambiente que ele não pode controlar completamente. Assim como a casca do ovo, projetada para ser quebrada pelo filhote, a aplicação front-end é concebida para ser amplamente acessível. No entanto, essa mesma acessibilidade torna-a vulnerável a ataques de "predadores" digitais, como hackers e invasores que exploram suas vulnerabilidades de segurança.

Além disso, é importante reconhecer que invasores não se limitam a explorar vulnerabilidades apenas através dos navegadores; eles também utilizam uma variedade de ferramentas e técnicas que podem comprometer a segurança da aplicação, explorando múltiplos vetores de ataque e ampliando significativamente as ameaças potenciais.

Devido a essas vulnerabilidades, o front-end não é a camada destinada a garantir a segurança integral da aplicação. Em vez disso, ele deve ser parte de uma abordagem de segurança em camadas, onde medidas de proteção mais críticas são implementadas no back-end e em outros pontos do sistema. Assim como os pais das aves utilizam várias estratégias para proteger seus ovos, os desenvolvedores devem implementar defesas em múltiplos níveis, incluindo firewalls, sistemas de detecção de intrusão, e segurança robusta no back-end para proteger dados sensíveis e funcionalidades críticas do sistema.

As implicações de implementar regras de negócio exclusivamente no front-end

No desenvolvimento de aplicações digitais, uma eventual decisão técnica que pode emergir em diversos tipos de projetos é a implementação de regras de negócio na camada de front-end. Embora essa decisão possa ser vista como uma forma eficiente de filtrar e processar dados antes que eles alcancem as camadas mais profundas do sistema, tal abordagem traz consigo riscos significativos e implicações negativas para a segurança e integridade dos dados, especialmente se não houver uma revalidação adequada no backend.

Esta estratégia, não sendo uma prática padrão, pode ser adotada sob certas circunstâncias que parecem exigir uma aceleração do processo de desenvolvimento. No entanto, essa eficiência é potencialmente ilusória. Sem a revalidação das regras de negócio no backend, o sistema fica exposto a riscos de manipulação por partes com más intenções. E sem mesmo recorrer a recursos avançados de hackers, as ferramentas de desenvolvimento integradas aos navegadores modernos facilitam alterar processos definidos no front-end, permitindo a inserção de dados que podem não ser rigorosamente validados posteriormente. Lembre-se: no front-end, qualquer dado é mutável e qualquer interação disponível pode ser facilmente corrompida.

O front-end é a camada mais vulnerável em uma aplicação. E, na verdade, está tudo bem com isso. É uma realidade com a qual precisamos lidar de forma pragmática. A eficácia real na prevenção de invasões e na proteção de dados não reside no front-end, onde os dados não são efetivamente controlados e persistidos. Embora medidas de segurança no front-end sejam necessárias, é importante reconhecer que a responsabilidade por tornar uma aplicação inviolável não recai sobre esta estrutura. Estratégias robustas de segurança devem ser implementadas em todas as camadas da aplicação para assegurar uma defesa eficaz contra ameaças, principalmente em níveis além da interface do usuário.

Além disso, ao longo das últimas décadas, muitos projetos de software foram desenvolvidos com uma abordagem centrada na tecnologia, frequentemente iniciando com diagramas complexos, como os de entidade e relacionamento, em detrimento de protótipos focados no usuário. Essa prática pode resultar em produtos que, embora tecnicamente competentes, falham em atender às necessidades reais e às expectativas dos usuários finais.

Um dos grandes desafios quando regras de negócio são implementadas predominantemente no front-end é a desatenção à usabilidade e à experiência do usuário. Desenvolvedores front-end, responsáveis pelo design e pela interatividade do software, nestes casos, frequentemente precisam dividir seu foco entre implementar lógicas de negócio e aprimorar a experiência do usuário. Esse compromisso pode deteriorar a qualidade e a eficiência da experiência do usuário. Quanto mais regras de negócio são delegadas ao front-end, mais o desenvolvimento do software tende a ignorar as verdadeiras necessidades do usuário.

Regras de negócio no lugar certo

Benefícios de uma abordagem centralizada

É fundamental evitar a implementação de regras de negócio na camada de front-end sempre que possível, priorizando sua execução no back-end ou ainda mais próximo da fonte de dados. Esta abordagem não apenas simplifica a manutenção do sistema, mas também garante uma maior consistência dos dados ao longo de diferentes plataformas e dispositivos que podem acessar a aplicação.

Quando a lógica de negócio é centralizada próximo à persistência dos dados, como em uma API, evitamos duplicar implementações em diferentes clientes da aplicação, como por exemplo, entre repositórios de uma aplicação web e do aplicativo mobile. Além disso, esta estratégia reduz significativamente a complexidade no front-end, permitindo que as equipes de desenvolvimento se concentrem em melhorar a experiência do usuário sem se preocuparem com a validação e o processamento complexo dos dados.

Outra vantagem é que qualquer revisão ou atualização das regras de negócio pode ser implementada em um único local, garantindo que todas as instâncias da aplicação se comportem consistentemente e estejam sempre sincronizadas com as últimas mudanças. Isso não só otimiza os recursos de desenvolvimento, mas também fortalece a segurança ao minimizar as oportunidades de manipulação de dados no front-end.

Por fim, a definição de regras no back-end ajuda a assegurar que todos os dados recebidos e processados sejam consistentes e confiáveis, independentemente das múltiplas camadas de interação do usuário que possam existir. Assim, reforçamos a importância de uma arquitetura bem definida que separe claramente as responsabilidades de processamento de dados da interface do usuário.

O papel do desenvolvedor front-end na gestão de regras de negócio

Para desenvolvedores front-end, é essencial adotar uma postura proativa na gestão de onde as regras de negócio são implementadas. Embora possa ser tentador incorporar lógica de negócios diretamente no front-end da aplicação para atender a demandas imediatas ou prazos apertados, é crucial negociar e advogar para que essas regras sejam, dentro do possível, implementadas no backend.

Implementar regras de negócio no backend não apenas simplifica a manutenção do front-end, mas também reduz a complexidade desnecessária que pode sobrecarregar o desenvolvimento e comprometer a experiência do usuário. Quando o front-end é liberado para focar na apresentação e interação com o usuário, os desenvolvedores podem concentrar seus esforços em criar interfaces mais rápidas, responsivas e acessíveis.

Além disso, ao garantir que as regras de negócio sejam tratadas no backend, os dados que chegam ao front-end estarão mais próximos do estado final que deve ser apresentado, minimizando os riscos de inconsistências e erros. Esta abordagem também favorece a segurança, já que a manipulação de dados sensíveis e a validação são realizadas em um ambiente controlado, longe das vulnerabilidades inerentes ao front-end.

É fundamental que desenvolvedores front-end promovam o diálogo e trabalhem em estreita colaboração com os demais membros da equipe para assegurar que a implementação de regras de negócio seja tanto eficaz quanto segura. Esta parceria não apenas eleva a qualidade do produto, mas também reforça a coesão entre os membros, um elemento chave para o sucesso de qualquer projeto de software.

Mitigando complexidades

Quando é inevitável a implementação das regras de negócio no front-end

Em alguns cenários, pode ser inevitável que certas regras de negócio sejam implementadas diretamente na aplicação cliente, devido a fatores como prazos apertados, requisitos específicos ou falta de argumentos técnicos para negociar mudanças. Nestes casos, é essencial que essas regras sejam gerenciadas de maneira a minimizar o impacto na camada que interage diretamente com o usuário final.

Para evitar redundância e manter a organização do código, é recomendável que essas regras de negócio sejam encapsuladas em uma camada específica no próprio front-end. Esta camada deve ser projetada para funcionar como um intermediário entre os componentes de UI e os dados recebidos, garantindo que as regras aplicadas não se espalhem por múltiplas áreas do repositório.

Isso permite uma manutenção mais simples e evita a duplicação de lógica, tornando o sistema mais fácil de atualizar e de corrigir. Além disso, essa abordagem oferece a flexibilidade necessária para que, caso a regra de negócio precise ser ajustada ou no futuro reimplementada no backend, a transição possa ser feita com menos esforço e interrupção.

Implementar uma camada intermediária no front-end que centralize a aplicação destas regras de negócio emergenciais não só ajuda a manter a organização do código, como também facilita a gestão de mudanças, proporcionando uma resposta mais ágil às necessidades do projeto sem comprometer a integridade da arquitetura da aplicação.

Adotando um BFF

A adoção de um Backend for Frontend (BFF) é uma estratégia que visa - além de outros benefícios - isolar a implementação de regras de negócio específicas para não sobrecarregar o repositório do front-end. No entanto, esta abordagem traz desafios adicionais. Um dos principais é que ela pode levar a uma expansão das responsabilidades do time de front-end, que além de focar na experiência e no fluxo do usuário, agora também precisa gerenciar um novo repositório com complexidades próprias.

Quando a implementação de uma regra de negócio no front-end se torna inevitável, é fundamental que toda a equipe esteja ciente de que, tecnicamente, essa não é a solução ideal. Esta transparência é crucial para manter a equipe alinhada com as melhores práticas de desenvolvimento e para compreender as possíveis implicações dessa escolha. É importante argumentar com clareza, apoiando-se nas análises e conclusões detalhadas neste texto, para que todos os envolvidos entendam os motivos da decisão e as limitações que ela pode impor ao projeto. Essa comunicação efetiva ajuda a prevenir mal-entendidos e prepara a equipe para possíveis desafios de manutenção e segurança que podem surgir como consequência dessa abordagem.

Compreendendo as regras de negócio

Ao longo deste texto, abordamos repetidamente o termo "regras de negócio". Mas o que exatamente são essas regras? Nesta seção, esclareceremos esse conceito fundamental e mostrar como ele se aplica em situações práticas numa aplicação.

Regras de negócio são diretrizes ou condições definidas que governam os processos dentro de uma aplicação para garantir a consistência, a lógica e a validade das operações e decisões. Vamos explorar isso com um exemplo prático:

Imagine uma interface de usuário onde a disponibilidade de um botão depende de certos critérios. Suponha que temos uma tela onde um botão deve ser habilitado apenas se certas propriedades retornadas por uma API atendam a uma regra específica. Por exemplo, um botão Editar só pode ser ativado se a combinação dos valores das propriedade status, disableDatetime e locked, corresponderem as regras ilustradas abaixo:

exemplo de regra de negócio no código javascript

Se a condição acima resultar em um valor falso, correspondendo o usuário não ter essa permissão, o botão será desativado, e um tooltip instrutivo será mostrado, detalhando o motivo da desabilitação.

o botão desabilitado e o tooltip apresentado

No front-end, essa regra pode ser implementada usando estruturas condicionais (como if ou operadores ternários) para verificar as propriedades retornadas pela API. Se as condições forem atendidas, o botão é habilitado; caso contrário, é desabilitado e o tooltip apresentado.

Por que centralizar regras de negócio?

Evita redundâncias de implementação: Resolver as regras de negócio no backend impede que a mesma lógica seja implementada em múltiplos pontos da aplicação, o que não só economiza tempo e recursos, mas também facilita a manutenção.

Integridade e persistência de dados: Muitas regras de negócio são essenciais para garantir que os dados sejam armazenados corretamente. Ao centralizar essas regras no backend, asseguramos que elas sejam aplicadas de maneira uniforme, independentemente de como ou onde os dados são acessados.

Foco na experiência do usuário (UX): Quando as regras de negócio são tratadas no backend, o desenvolvedor front-end pode concentrar-se em otimizar a experiência do usuário, alinhando o design e a funcionalidade com as necessidades do usuário final, sem se distrair com complexidades de negócio.

Documentação e manutenção: Centralizar as regras de negócio no backend facilita a documentação e a manutenção, pois existe um único local onde as regras são definidas e modificadas, ao invés de múltiplas instâncias espalhadas pelo front-end.

Segurança reforçada: Manter as regras de negócio no backend ajuda a evitar vulnerabilidades de segurança, como Insecure Direct Object References (IDOR), que ocorrem quando um aplicativo expõe referências a objetos internos sem devidas verificações de autorização.

Consistência entre as diferentes frentes: Com as regras de negócio implementadas no backend, todos os clientes da aplicação, seja web, mobile ou desktop, operam com a mesma lógica, garantindo consistência nos dados manipulados e armazenados.

Facilidade em atualizações: Quando é necessário alterar uma regra de negócio, a modificação no backend se propaga automaticamente a todos os clientes. Isso elimina a necessidade de atualizar cada cliente individualmente, o que reduz o risco de inconsistências entre diferentes versões da aplicação.

Reforçando a Segurança no Front-end: Medidas Essenciais

Embora o front-end possa ser visto como uma "casquinha de ovo", frágil e suscetível a manipulações, é crucial não subestimar a importância de implementar controles de segurança robustos. Essas medidas são essenciais para proteger a aplicação e os usuários de ameaças e vulnerabilidades comuns. Aqui estão algumas práticas recomendadas:

Uso de Content Security Policy (CSP): Implementar headers CSP ajuda a prevenir ataques de injeção, limitando os recursos que o navegador está autorizado a carregar. Isso pode ser crucial para bloquear conteúdos maliciosos antes que eles causem danos.

Proteção Contra CSRF (Cross-Site Request Forgery): Aplicar tokens CSRF em formulários e requisições AJAX é uma prática fundamental para evitar que ações indesejadas sejam executadas em nome dos usuários sem o seu conhecimento.

Armazenamento Seguro de Dados Locais: É importante garantir que todos os dados sensíveis armazenados localmente, como tokens de autenticação ou informações pessoais, sejam criptografados e protegidos contra acesso indevido.

Headers de Segurança HTTP: Implementar cabeçalhos como X-Frame-Options, X-XSS-Protection e Strict-Transport-Security é vital para proteger os usuários contra ataques de clickjacking e cross-site scripting (XSS), assegurando que o navegador adote medidas preventivas contra essas vulnerabilidades.

Prevenção de Cross-Site Scripting (XSS): XSS é uma vulnerabilidade que permite a injeção de scripts maliciosos em páginas web. A implementação de uma política de segurança rigorosa para validar e sanitizar entradas do usuário pode mitigar esse risco significativamente.

Validação e Sanitização de Entradas: Assegurar que todas as entradas do usuário sejam validadas e sanitizadas antes de serem processadas ou armazenadas é essencial para prevenir uma variedade de ataques, garantindo que apenas dados limpos e seguros sejam aceitos.

Jackson Ricardo Schroeder | Desenvolvedor front-end

5

Nao e a questao do frontend, mas sim do cliente, seja um aplicativo/desktop/web, nunca se deve confiar no cliente pois pode ser adulterado. Toda logica deve estar no servidor, assim tambem como toda a conexao feita com o banco de dados.

(meu texto esta sem acentos devido meu teclado ser em ingles)

-1
1

Apesar de serem interligados eles possuem funções distintas e é natural que seja assim dado o objetivo que cada um deles possui.