{"id":338175,"date":"2023-03-31T20:28:20","date_gmt":"2023-03-31T19:28:20","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=qodana&#038;p=338175"},"modified":"2023-09-04T16:19:06","modified_gmt":"2023-09-04T15:19:06","slug":"mantenha-o-seu-codigo-php-seguro-com-a-taint-analysis-do-qodana","status":"publish","type":"qodana","link":"https:\/\/blog.jetbrains.com\/pt-br\/qodana\/2023\/03\/mantenha-o-seu-codigo-php-seguro-com-a-taint-analysis-do-qodana\/","title":{"rendered":"Mantenha o Seu C\u00f3digo PHP Seguro com a Taint Analysis do Qodana"},"content":{"rendered":"<p><em>Esta postagem do blog \u00e9 um oferecimento do Qodana \u2014 uma plataforma de qualidade de c\u00f3digo da JetBrains. Essa plataforma foi projetada para trazer an\u00e1lise est\u00e1tica pelo lado do servidor \u00e0 sua ferramenta preferida de CI. Por usar as mesmas inspe\u00e7\u00f5es de c\u00f3digo e os mesmos perfis que o PhpStorm e outros IDEs da JetBrains, o Qodana ajuda a garantir que haja verifica\u00e7\u00f5es consistentes da qualidade do c\u00f3digo tanto no seu IDE quanto no seu ambiente de CI<\/em>.<\/p>\n<p>Basta apenas um usu\u00e1rio para explorar uma vulnerabilidade no seu projeto e invadir o seu sistema. Para defender os programas contra entradas de dados maliciosas por usu\u00e1rios externos (conhecidas como \u201ctaints\u201d), as equipes de desenvolvimento adicionam a verifica\u00e7\u00e3o de taints \u00e0s suas rotinas de an\u00e1lise est\u00e1tica.\u00a0<\/p>\n<p>No primeiro lan\u00e7amento deste ano, a equipe do Qodana incorporou a taint analysis para PHP na vers\u00e3o de acesso antecipado (EAP). Este recurso est\u00e1 dispon\u00edvel apenas no Qodana para PHP 2023.1 (jetbrains\/qodana-php:2023.1-eap). O Qodana para PHP foi o primeiro linter que lan\u00e7amos; ent\u00e3o, decidimos deixar os desenvolvedores PHP tamb\u00e9m serem os primeiros a testarem nossas novas fun\u00e7\u00f5es de seguran\u00e7a. Planejamos adicionar mais linguagens no futuro, depois de termos coletado feedback suficiente.<\/p>\n<p>Continue lendo para saber mais sobre o que \u00e9 taint analysis e como ela funciona no Qodana.\u00a0<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-339554 size-medium\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/Blog_Featured_image_1280x600-17-1200x563.png\" alt=\"\" width=\"1200\" height=\"563\" \/><\/figure>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"EXPERIMENTE O QODANA GRATUITAMENTE\" href=\"https:\/\/www.jetbrains.com\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>COME\u00c7AR COM O QODANA<\/a><\/p>\n<h2>O que \u00e9 taint analysis?<\/h2>\n<p>Um taint \u00e9 qualquer valor que possa representar um risco de seguran\u00e7a quando modificado por um usu\u00e1rio externo. Se voc\u00ea tiver um taint no seu c\u00f3digo e dados externos n\u00e3o verificados puderem ser distribu\u00eddos a partes do seu programa, hackers poder\u00e3o executar esses fragmentos n\u00e3o verificados de c\u00f3digo para provocar inje\u00e7\u00e3o de SQL, overflow aritm\u00e9tico, cross-site scripting, path traversal e outros ataques. Geralmente, eles exploram essas vulnerabilidades para destruir o sistema, obter credenciais e outros dados e alterar o comportamento do sistema.<\/p>\n<p><!--more--><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-330043\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-34.png\" alt=\"\" width=\"1530\" height=\"590\" \/>\n<figcaption>Exemplo de um taint. S\u00e3o mostrados na tela dados arbitr\u00e1rios do par\u00e2metro GET. Por exemplo, usu\u00e1rios mal-intencionados podem explorar essa vulnerabilidade para interferir no layout do seu programa.\u00a0\u00a0<\/figcaption>\n<\/figure>\n<p>Como uma camada adicional de defesa contra dados de entrada mal-intencionados, as equipes de desenvolvimento executam uma taint analysis ao efetuarem uma auditoria de seguran\u00e7a na superf\u00edcie de ataque do programa.\u00a0<\/p>\n<p><strong>A taint analysis \u00e9 o processo de avaliar o fluxo de dados de entrada n\u00e3o confi\u00e1veis de usu\u00e1rio por todo o corpo de uma fun\u00e7\u00e3o ou m\u00e9todo. Seu objetivo principal \u00e9 determinar se algum dado de entrada n\u00e3o previsto pode afetar a execu\u00e7\u00e3o do programa de forma mal-intencionada.\u00a0<\/strong><\/p>\n<p><strong>Fontes de taints<\/strong> s\u00e3o locais onde um programa tem acesso a dados que podem potencialmente ser taints. Pontos-chave em um programa que podem ser suscet\u00edveis a permitir a entrada de taints s\u00e3o chamados <strong>taint sinks<\/strong>. Esses dados podem ser propagados aos sinks atrav\u00e9s de chamadas a fun\u00e7\u00f5es ou de atribui\u00e7\u00f5es.<\/p>\n<p>Se voc\u00ea fizer uma taint analysis manual, dever\u00e1 identificar todos os lugares onde voc\u00ea aceita dados de usu\u00e1rios externos e seguir cada um desses dados atrav\u00e9s do sistema \u2014 os dados com taints podem ser usados em dezenas de n\u00f3s. Depois, para evitar a propaga\u00e7\u00e3o dos taints, voc\u00ea deve fazer uma das duas abordagens descritas abaixo:<\/p>\n<ol>\n<li><strong>Higienizar os dados<\/strong>, isto \u00e9, coloc\u00e1-los em um estado seguro. No exemplo abaixo, removemos tags para resolver o taint.\u00a0<\/li>\n<\/ol>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329878\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-24.png\" alt=\"\" width=\"1600\" height=\"249\" \/><\/figure>\n<ol start=\"2\">\n<li><strong>Validar os dados<\/strong>, isto \u00e9, assegurar-se de que os dados adicionados seguem um padr\u00e3o necess\u00e1rio. No exemplo abaixo, ativamos a valida\u00e7\u00e3o da vari\u00e1vel <code>$<\/code><code>email<\/code>.\u00a0<\/li>\n<\/ol>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329926\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-25.png\" alt=\"\" width=\"1600\" height=\"365\" \/><\/figure>\n<p>Em outras palavras, a inspe\u00e7\u00e3o da taint analysis rastreia dados de usu\u00e1rio com taints desde a sua fonte at\u00e9 os seus sinks e d\u00e1 o alarme quando voc\u00ea trabalha com esses dados sem higieniz\u00e1-los ou valid\u00e1-los.\u00a0<\/p>\n<h2>Como funciona a taint analysis no Qodana<\/h2>\n<p>A taint analysis \u00e9 efetuada pelo Qodana para PHP a partir da vers\u00e3o 2023.1 EAP. Este recurso inclui uma inspe\u00e7\u00e3o que varre o c\u00f3digo e real\u00e7a o taint e a vulnerabilidade em potencial, tem a capacidade de abrir o problema no PhpStorm para resolv\u00ea-lo na mesma hora e inclui um grafo de fluxo de dados para visualizar o fluxo do taint.\u00a0<\/p>\n<h3>Exemplo n\u00ba 1. Inje\u00e7\u00e3o de SQL\u00a0<\/h3>\n<p>Vamos dar uma olhada em um exemplo de inje\u00e7\u00e3o de SQL e como o Qodana a detecta:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329937\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-26.png\" alt=\"\" width=\"1600\" height=\"825\" \/><\/figure>\n<p>Aqui, o Qodana mostra os seguintes taints na fun\u00e7\u00e3o system_admin():<\/p>\n<p>Marcadores 1-2: Dados de entrada do formul\u00e1rio do usu\u00e1rio s\u00e3o obtidos do array global <code>$<\/code><code>_POST<\/code>, sem nenhuma higieniza\u00e7\u00e3o ou valida\u00e7\u00e3o, e s\u00e3o atribu\u00eddos \u00e0 vari\u00e1vel <code>$<\/code><code>edit<\/code>. <strong>Isto \u00e9 um taint.<\/strong><\/p>\n<p>Marcador 3: A vari\u00e1vel com taint <code>$<\/code><code>edit<\/code> \u00e9 passada como argumento \u00e0 fun\u00e7\u00e3o <code>system_save_settings<\/code> sem nenhuma higieniza\u00e7\u00e3o adequada.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329949\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-27.png\" alt=\"\" width=\"1600\" height=\"527\" \/><\/figure>\n<p>Marcador 4: Agora os dados da vari\u00e1vel <code>$<\/code><code>edit<\/code> est\u00e3o no par\u00e2metro <code>$<\/code><code>edit<\/code>.<\/p>\n<p>Marcador 5: A vari\u00e1vel <code>$<\/code><code>edit<\/code> \u00e9 passada ao <code>foreach<\/code> com a chave <code>$<\/code><code>filename<\/code> e o valor <code>$<\/code><code>status<\/code>. As duas vari\u00e1veis cont\u00eam os dados com taint da vari\u00e1vel <code>$<\/code><code>edit<\/code> concatenada \u00e0 string. A chave <code>$<\/code><code>filename<\/code> est\u00e1 concatenada a uma string de SQL com taint e ir\u00e1 propagar dados com taint para um argumento passado a <code>db_query<\/code>.<\/p>\n<p>Marcador 6: A chave <code>$<\/code><code>filename<\/code> cont\u00e9m os dados com taint da vari\u00e1vel <code>$<\/code><code>edit<\/code> concatenada \u00e0 string.<\/p>\n<p>Marcador 7: A chave <code>$<\/code><code>filename<\/code> est\u00e1 concatenada a uma string de SQL com taint.<\/p>\n<p>Marcador 8: A string de SQL com taint ir\u00e1 propagar dados com taint a um argumento passado a <code>db_query<\/code>.<\/p>\n<p>Agora, vamos dar uma olhada em <code>db_query<\/code>:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329960\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-28.png\" alt=\"\" width=\"1600\" height=\"571\" \/><\/figure>\n<p>Marcador 9: A string com taint estar\u00e1 localizada no par\u00e2metro <code>$<\/code><code>query<\/code>.<\/p>\n<p>Marcador 10: Este par\u00e2metro ser\u00e1 um argumento da fun\u00e7\u00e3o <code>_db_query<\/code>.<\/p>\n<p>Vamos prosseguir para a fun\u00e7\u00e3o <code>_db_query<\/code>:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-330032\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-33.png\" alt=\"\" width=\"1600\" height=\"680\" \/><\/figure>\n<p>Marcador 11: Os dados com taint est\u00e3o localizados no primeiro par\u00e2metro <code>$<\/code><code>query<\/code> da fun\u00e7\u00e3o <code>_db_query<\/code>.<\/p>\n<p>Marcador 12: Os dados do par\u00e2metro s\u00e3o passados \u00e0 fun\u00e7\u00e3o <code>mysql_query<\/code>, que \u00e9 um sink.<\/p>\n<p>Todo o fluxo de dados acima ilustra como os dados se movem de <code>$<\/code><code>_POST[\"edit\"]<\/code> at\u00e9 <code>mysql_query($query) sem nenhuma higieniza\u00e7\u00e3o ou valida\u00e7\u00e3o. Isso permite a um atacante manipular a consulta SQL que foi concatenada a uma chave de <code>$<\/code><code>_POST[\"edit\"]<\/code> e assim acionar a <strong>inje\u00e7\u00e3o de SQL<\/strong>.\u00a0<\/code><\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>O Qodana identificar\u00e1 esses riscos na sua base de c\u00f3digo, juntamente com todos os n\u00f3s onde se usam dados com taint, para que voc\u00ea possa higienizar a tempo todos os dados com taint.\u00a0<\/p>\n<p><code><code><\/code><\/code><\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/resources.jetbrains.com\/storage\/products\/blog\/wp-content\/uploads\/Qodana\/taint-open.gif\" alt=\"\" \/>\n<p>\u00a0<\/p>\n<figcaption>Abrindo o problema no PhpStorm.<\/figcaption>\n<\/figure>\n<p><code><code><\/code><\/code><\/p>\n<h3>Exemplo n\u00ba 2. Problema de XSS<\/h3>\n<p><code><code><\/code><\/code><\/p>\n<p>Na interface de usu\u00e1rio do Qodana, voc\u00ea poder\u00e1 ver um grafo que mostra todo o fluxo do taint. \u00c9 assim que o Qodana mostrar\u00e1 a vulnerabilidade de XSS, que cont\u00e9m 2 fontes que seriam reunidas no marcador 5.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329971\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-29.png\" alt=\"\" width=\"1310\" height=\"750\" \/><\/figure>\n<p><code><code><\/code><\/code><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329982\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-30.png\" alt=\"\" width=\"1170\" height=\"714\" \/><\/figure>\n<p><code><code><\/code><\/code><\/p>\n<p><strong>Fonte 1<\/strong><\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcadores 1-2: Ser\u00e3o lidos os dados do arquivo <code>searchUpdate.pos<\/code> e dados com taint ser\u00e3o atribu\u00eddos \u00e0 vari\u00e1vel <code>$<\/code><code>start<\/code>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p><strong>Fonte 2<\/strong><\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcadores 3-4: Ser\u00e3o lidos os dados dos arquivos cujos caminhos estiverem localizados em <code>$<\/code><code>posFile<\/code> e dados com taint ser\u00e3o atribu\u00eddos \u00e0 vari\u00e1vel <code>$<\/code><code>start<\/code>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcador 5: Um estado com taint reunindo todos os ramos condicionais na vari\u00e1vel <code>$<\/code><code>start<\/code> ser\u00e1 passado como argumento ao m\u00e9todo <code>doUpdateSearchIndex<\/code>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Vamos dar uma olhada dentro do m\u00e9todo <code>doUpdateSearchIndex()<\/code>:<\/p>\n<p><code><code><\/code><\/code><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-329994\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-31.png\" alt=\"\" width=\"1170\" height=\"522\" \/><\/figure>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcadores 6-8: O par\u00e2metro <code>$<\/code><code>start<\/code> conter\u00e1 dados com taint nesta parte do fluxo de dados e ser\u00e1 passado dentro de uma string concatenada como argumento para o m\u00e9todo <code>output<\/code>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Vamos dar uma olhada dentro do m\u00e9todo <code>output<\/code>:<\/p>\n<p><code><code><\/code><\/code><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-330005\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-32.png\" alt=\"\" width=\"1170\" height=\"764\" \/><\/figure>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcador 9: Os dados com taint contidos dentro da string transmitida estar\u00e3o localizados no par\u00e2metro <code>$<\/code><code>out<\/code>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Marcador 10: Os dados do par\u00e2metro <code>$<\/code><code>out<\/code> ser\u00e3o transferidos \u00e0 fun\u00e7\u00e3o <code>print<\/code> sem nenhuma higieniza\u00e7\u00e3o. Esta fun\u00e7\u00e3o \u00e9 um sink e causa uma vulnerabilidade de XSS, que pode ser usada com m\u00e1s inten\u00e7\u00f5es.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Para se aproveitar dessa vulnerabilidade, um atacante pode, por exemplo, fazer o upload de um script de shell, em vez dos arquivos esperados nos marcadores 1 e 2, e pode colocar qualquer informa\u00e7\u00e3o na p\u00e1gina da Web, como resultado de uma fun\u00e7\u00e3o <code>print<\/code> n\u00e3o higienizada.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>O Qodana ir\u00e1 alertar sobre esta vulnerabilidade e dar\u00e1 a ela uma prioridade alta, para que voc\u00ea possa resolv\u00ea-la o mais rapidamente poss\u00edvel e evitar o hack.\u00a0\u00a0<\/p>\n<p><code><code><\/code><\/code><\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p><code><code><\/code><\/code><\/p>\n<p>A taint analysis ajuda a eliminar superf\u00edcies de ataque que possam ser usadas com m\u00e1s inten\u00e7\u00f5es. Portanto, \u00e9 um m\u00e9todo eficaz para reduzir riscos no seu software. Para saber mais detalhes sobre a taint analysis e o Qodana, explore a <a title=\"https:\/\/www.jetbrains.com\/help\/qodana\/getting-started.html\" href=\"https:\/\/www.jetbrains.com\/help\/qodana\/2023.1\/taint-analysis.html\" target=\"_blank\" rel=\"noreferrer noopener\">documenta\u00e7\u00e3o do Qodana<\/a>.<\/p>\n<p><code><code><\/code><\/code><\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"INTRODU\u00c7\u00c3O AO QODANA\" href=\"https:\/\/www.jetbrains.com\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>INTRODU\u00c7\u00c3O AO QODANA<\/a><\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Bom desenvolvimento e mantenha o seu c\u00f3digo saud\u00e1vel!<\/p>\n<p><em>Artigo original em ingl\u00eas por:<\/em><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":339554,"comment_status":"closed","ping_status":"closed","template":"","categories":[4089,947,89,907,6366],"tags":[991,76,190,45,477],"cross-post-tag":[6637],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/qodana\/338175"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/qodana"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/qodana"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=338175"}],"version-history":[{"count":6,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/qodana\/338175\/revisions"}],"predecessor-version":[{"id":339569,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/qodana\/338175\/revisions\/339569"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/339554"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=338175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=338175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=338175"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=338175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}