Dois aspectos do WebView: sobre o início rápido de projetos e o roubo de dados pessoais

Olá Habr!

Meu nome é Eugene, sou desenvolvedor Full Stack JS, a pilha atual é Node.js + React + React Native. Estou em desenvolvimento há mais de 10 anos. No desenvolvimento móvel, tentei diferentes ferramentas, desde o Cordova ao React Native. Tendo adquirido experiência com o Cardova, percebi que gostaria de criar interfaces nativas. Na minha opinião, o WebView não deve ser o aplicativo inteiro. Mas isso não significa que não deva ser usado.

A convite de colegas do Sberbank, neste post, quero falar sobre aplicativos móveis híbridos. Com a abordagem correta, é uma ótima maneira de implementar rapidamente a ideia de um produto que funcione bem, suficiente para o primeiro lançamento da sua inicialização.


Fonte: srishta.com

Também vou falar um pouco sobre como você pode usar o WebView e como os atacantes podem usá-lo contra você. Os exemplos no artigo serão mostrados usando a estrutura React Native, mas as mesmas idéias podem ser implementadas sem ela.

Um pouco sobre startups


Começarei com as diferenças fundamentais no lançamento de startups em nosso país e no Ocidente; mostrarei como o WebView pode ajudar aqui; darei exemplos de trabalho da interação de elementos da web e nativos, além de dicas de segurança para interagir com aplicativos de terceiros.

Como regra, para que uma startup seja bem-sucedida, ela precisa começar rapidamente. Se você perder tempo, seus concorrentes irão ignorá-lo. Isso é entendido tanto em nosso país quanto no Ocidente. Mas a abordagem russa para lançar, por via de regra, é muito mais completa - no mau sentido da palavra.

Todas as startups russas malsucedidas começam e se desenvolvem aproximadamente no mesmo cenário. Os erros mais comuns estão relacionados ao planejamento estratégico do desenvolvimento de produtos de software. A gerência acredita que o lançamento é possível somente após a implementação de 110% de todas as funcionalidades e todas as nuances. Com essa abordagem, surge rapidamente um déficit orçamentário, uma vez que os custos de desenvolvimento são altos e não há receita com uma startup. A busca por investimentos adicionais, um círculo interminável de aprovações e revisões leva muito tempo, o produto aparece no concorrente. É isso aí, a maratona está perdida.

As startups européias e americanas agem de maneira diferente. Para iniciantes, eles são limitados apenas à versão para web móvel com uma parte funcional minimamente suficiente. Pode ser visualizado em computadores e dispositivos móveis. E, nesta fase, o projeto está pronto para o lançamento! Após o lançamento, o aplicativo é feito para dispositivos móveis.

Como regra, o aplicativo não difere em recursos básicos da versão web. Ele expande as possibilidades de interação com o usuário, por exemplo, por meio de notificações push. Essa abordagem garante o cumprimento da condição principal - início rápido, primeiro lucro rápido. As receitas da primeira etapa podem ser investidas no desenvolvimento. No futuro, o projeto poderá ser escalado e desenvolvido conforme desejado, sem déficit orçamentário, executando uma abordagem interativa para adicionar novas funcionalidades e desenvolver a interface do usuário.

Proponho considerar mais detalhadamente o estágio em que já existe uma versão móvel do site e você precisa desenvolver um aplicativo para dispositivos móveis. Por isso, criamos um site, o que significa que estávamos desenvolvendo a API do servidor, a interface e a lógica de negócios. Dois dos três componentes são
- interface e lógica - estão presentes no aplicativo móvel. Concordo, não quero escrevê-los novamente.

Combinando o melhor de aplicativos nativos e da web


Existem ferramentas focadas no desenvolvimento de aplicativos nativos. Outros são para a web. A vantagem dos aplicativos nativos é que eles podem usar todo o potencial funcional do telefone. Mas desenvolvê-los em comparação com aplicativos da web é bastante difícil. A web oferece um início fácil, mas limita bastante os recursos do aplicativo.


* para reduzir a tautologia dos aplicativos da web, chamarei aplicativos móveis, cuja maior parte da lógica e da interface é implementada no lado do navegador

Os aplicativos híbridos criados usando o componente WebView permitem combinar todas as vantagens dos aplicativos nativos e da web. Obviamente, existem desenvolvedores meticulosos que são categoricamente contra o WebView em qualquer uma de suas manifestações. Eles argumentam isso com o fato de que o aplicativo deve ser imediatamente completamente nativo, para que você possa usar todos os recursos de um dispositivo móvel, além de fornecer um desempenho confortável da interface do usuário. Mas, em muitos casos, quando os recursos da versão móvel do site são suficientes, você pode reduzir o tempo do primeiro lançamento criando um aplicativo híbrido e gradualmente substituindo-o por um nativo.


Os aplicativos híbridos nem sempre são ruins e nem extensíveis. Eles podem ser convenientes e produtivos. Com o uso adequado, essa abordagem ajuda a obter tempo suficiente para desenvolver um aplicativo de qualidade e não para liberar um aplicativo nativo às pressas.

Existem várias situações em que é aconselhável usar aplicativos híbridos. Eles são bons como um esboço temporário para um início rápido - quando temos uma versão móvel do site pronta e o aplicativo móvel era necessário "ontem". Esse aplicativo pode ser criado em poucas horas, executado na produção. Os usuários terão a oportunidade de trabalhar com um aplicativo móvel, e você terá a oportunidade de trabalhar em uma versão mais completa em períodos de tempo menos restritos (se necessário).

Aqui está um exemplo. Recentemente, os colegas precisavam urgentemente de um aplicativo móvel. Na versão web, ele tinha oito itens de menu e os exibimos através do WebView. E então eles substituíram um item. Aconteceu o lançamento do aplicativo não em um mês ou três, mas em apenas alguns dias. Depois de gradualmente transferido para o nativo.

Uma solução híbrida nem sempre é temporária. Seus recursos permitem reutilizar no aplicativo a base de código criada anteriormente para a versão web. Por exemplo, animações específicas já criadas no Canvas. O WebView também é conveniente ao usar algum tipo de serviço de terceiros. Outra opção é quando você possui uma interface complexa que é mais fácil de conectar via WebView.

Como usar a visualização na web


Pegue um script popular. Queremos usar a versão móvel do site e o menu nativo. Criamos um aplicativo nativo com um menu, mas, em vez de conteúdo, conectamos a versão móvel do site via WebView (até o momento, sem alterações).


No gif você pode ver 2 menus. O menu à direita faz parte do site, implementado na Web, à esquerda é o menu nativo, implementado dentro do aplicativo móvel. Para obter a primeira aproximação ao aplicativo nativo, precisamos apenas ocultar o menu implementado na web. Aqui está a quantidade de código necessária para exibir a versão da Web dentro do aplicativo via WebView:

export default (props) => (  <Layout {...props} name="Example1">    <WebView source={{uri: '<a href="https://provincehotels.ru/">https://provincehotels.ru/</a>'}} style={{flex:1}} />  </Layout> ); 

O próximo exemplo é sobre como a parte nativa pode interagir com a web.


O robô é desenhado no Canvas, isso faz parte do site. E a mudança para ele é criada na interface do usuário nativa. Será diferente em telefones diferentes. Podemos controlar os movimentos do robô usando um interruptor. Você pode e vice-versa - com alguns elementos da interface da web para influenciar o aplicativo. O React Native fornece para isso uma API especial para interação entre a web e a parte nativa.

Abaixo está o código para usar esta animação. Layout - todo o espaço. O Picker é uma parte nativa que pode selecionar nas opções suspensas para o estado do robô. WebView - um contêiner para exibir a web, dentro do qual um robô é desenhado.

 const states = [ 'Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing' ]; const uri = 'https://artexoid.ru/181212/example2/'; export default class Example2 extends React.Component { myWebView = React.<i>createRef</i>(); state = {   robot: states[0] }; render() {   return (     <Layout { ...this.props } name="Example2">       <Picker         mode="dropdown"         selectedValue={this.state.robot}         onValueChange={(item) => {           this.setState({robot: item});           this.myWebView.current.postMessage(item);         }}       >         {states.map((item => <Picker.Item key={item} label={item} value={item} /> ))}       </Picker>       <WebView ref={this.myWebView} source={{uri}} style={{flex:1}} />     </Layout>   ); } } 

Tais casos surgem frequentemente. Por exemplo, solicitamos testes e certificação de dentistas. Para cada resposta do teste, a animação foi desenhada dentro das perguntas, implementada usando o Canvas na web. O desafio foi criar um aplicativo móvel, com esse teste. Usando o WebView, conseguimos exibir animações da Web, enquanto construímos o restante da interface nativamente. A animação funcionou bem mesmo em smartphones mais antigos.

Como são feitas as injeções?


Até 2013, o navegador Opera usava seu próprio mecanismo Presto, mas depois foi transferido para o mecanismo Blink do Google. Muitos usuários estão muito chateados. O vídeo “Why Opera Webkit” lança luz sobre os motivos dessa transição. Os principais culpados são grandes empresas como Google ou Facebook, que não testaram o código de seus produtos no Opera e proibiram a exibição de páginas neste navegador, citando o fato de que não é popular o suficiente com os usuários.

Por exemplo, você acessa o Gmail pelo Opera e vê: "Erro de JavaScript". Você escreve para o suporte e obtém a resposta: "O Opera não é suportado conosco, não escreveremos código para ele". Primeiro, o Opera contratou desenvolvedores para escrever injeções, um código especial que foi incorporado ao Gmail e permitiu que ele funcionasse no Opera. Mas gradualmente sites como o Gmail ficaram maiores. Opera desistiu e mudou o motor.

Então, o que eu estou falando? Ah, sim, é hora de falar sobre injeções:


No gif - um exemplo de injeção que altera o comportamento dos sites. Suponha que tenhamos o site de outra pessoa e façamos uma injeção de estilos - ocultamos o menu à direita e o controle deslizante que sai à direita. Esta é uma injeção de estilos. A lógica do site não muda, apenas a exibição.

 const addStyles=` const newCSS = 'div[class*=svgHamburger],div[class*=drawerPanel] { display: none !important; }'       head = document.head || document.getElementsByTagName('head')[0],       style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(newCSS)); head.appendChild(style); `; const uri = 'https://provincehotels.ru/'; export default (props) => ( <Layout { ...props } name="Example1">   <WebView source={{uri }} style={{flex:1}} injectedJavaScript={addStyles} javaScriptEnabled={true} /> </Layout> ); 

O código escrito em verde é injeção. Ele oculta os elementos, você não pode clicar neles, não pode interagir com eles. Parece um aplicativo completamente nativo, sem controles da web.

A próxima injeção é mais interessante. Digamos que tenhamos um aplicativo móvel e ele tenha um navegador móvel embutido.


Uma pessoa segue o link e nós a substituimos facilmente pela página do Facebook na qual você precisa digitar um nome de usuário e senha. Se uma pessoa entra, o aplicativo a intercepta. Aqui está o código :

 const addScripts=` document   .querySelector('input[type=password]')   .addEventListener("change", (event) => alert(event.target.value)); `; const uri = 'https://www.facebook.com/'; export default (props) => ( <Layout { ...props } name="Example4">   <WebView source={{uri }} style={{flex:1}} injectedJavaScript={addScripts} javaScriptEnabled={true} /> </Layout> ); 

Esse código é chamado de injeção lógica. Geralmente é mais difícil, mas não muito. Ou seja, roubar uma senha é mais fácil do que ocultar controles.

Minuto de paranóia: navegadores incorporados em aplicativos


Como você sabe, muitos aplicativos têm navegadores embutidos (WebView) - por exemplo, VKontakte, Telegram, Gmail, WhatsApp e assim por diante. Podemos confiar em grandes empresas, mas o WebView também é usado por um grande número de aplicativos com um pequeno número de estrelas e autores duvidosos - por exemplo, leitores de QR, gerenciadores de arquivos, câmeras, etc. ... Você instala o aplicativo, lê o código, clica no link, insira dados confidenciais - e o aplicativo, como mostrado no exemplo anterior, tem acesso a eles. E você não pode acompanhar para onde esses dados fluem. Portanto, para abrir links, use apenas navegadores confiáveis.

Existem sites que solicitam um nome de usuário e senha a cada vez. E há quem faça isso raramente - uma vez por mês, uma vez por ano. Curiosamente, a segunda opção é mais segura em termos de vazamento de dados através do WebView. Por exemplo, você entra no site a partir de algum navegador esquerdo. O site requer um nome de usuário e senha, e isso não lhe parece estranho - sempre o faz. E no caso em que raramente é necessária autorização, você ficará cauteloso.

Curiosamente, a autenticação de dois fatores não protege contra esse ataque - apenas contra roubo de senha. O fato é que, após a confirmação, um token é retornado em resposta a você, o qual, por sua vez, ainda não possui autorização de dois fatores e é fácil interceptá-lo. Ou seja, se você digitou o login e o código do SMS uma vez, o navegador recebe um token, que pode ser usado repetidamente. Com esse token confirmado, ele pode fazer o que quiser, enquanto o token permanecer relevante. Em geral, não confie demais nos navegadores internos.

Você pode se familiarizar com os exemplos desta postagem através de aplicativos de demonstração. No sistema operacional Android, você precisa baixar o Expo Project - uma ferramenta para trabalhar com JavaScript e React Native. Depois de instalar o Expo, você só precisa ler o código QR:



Os dispositivos IOS são mais complicados: a Apple proibiu a distribuição de aplicativos dessa maneira. Portanto, os curiosos terão que criar o aplicativo a partir da fonte no GitHub. Obrigado pela atenção!

Source: https://habr.com/ru/post/pt440710/


All Articles