{"id":338173,"date":"2023-03-31T20:21:52","date_gmt":"2023-03-31T19:21:52","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=qodana&#038;p=338173"},"modified":"2023-09-04T16:19:24","modified_gmt":"2023-09-04T15:19:24","slug":"proteja-el-codigo-php-con-el-analisis-de-codigo-no-seguro-de-qodana","status":"publish","type":"qodana","link":"https:\/\/blog.jetbrains.com\/es\/qodana\/2023\/03\/proteja-el-codigo-php-con-el-analisis-de-codigo-no-seguro-de-qodana\/","title":{"rendered":"Proteja el c\u00f3digo PHP con el an\u00e1lisis de c\u00f3digo no seguro de Qodana"},"content":{"rendered":"<p><em>Este art\u00edculo del blog es gracias a Qodana, una plataforma de JetBrains sobre la calidad del c\u00f3digo. Esta plataforma est\u00e1 dise\u00f1ada para llevar el an\u00e1lisis est\u00e1tico del servidor a su herramienta de integraci\u00f3n continua preferida. Con las mismas inspecciones de c\u00f3digo y perfiles que PhpStorm y otros IDE de JetBrains, Qodana asegura controles coherentes de calidad del c\u00f3digo tanto en el IDE como en el entorno de integraci\u00f3n continua<\/em>.<\/p>\n<p>Un \u00fanico usuario es capaz de explotar una vulnerabilidad en el proyecto y penetrar en el sistema. As\u00ed que, para evitar la entrada maliciosa de usuarios externos en los programas (conocida como \u00abtaints\u00bb o \u00abc\u00f3digo no seguro\u00bb), los equipos de desarrollo a\u00f1aden la comprobaci\u00f3n de c\u00f3digo no seguro a las rutinas de an\u00e1lisis est\u00e1tico.\u00a0<\/p>\n<p>En la primera versi\u00f3n de este a\u00f1o, el equipo de Qodana ha incluido el an\u00e1lisis de c\u00f3digo no seguro para PHP en el EAP. Esta funcionalidad solo est\u00e1 disponible en Qodana para PHP 2023.1 (jetbrains\/qodana-php:2023.1-eap). Qodana para PHP fue el primer linter que lanzamos, as\u00ed que decidimos dejar que los desarrolladores de PHP fueran tambi\u00e9n los primeros en probar esta nueva funcionalidad de seguridad. Tenemos pensado a\u00f1adir m\u00e1s lenguajes m\u00e1s adelante, en cuanto hayamos recogido suficientes comentarios.<\/p>\n<p>Siga leyendo para obtener m\u00e1s informaci\u00f3n acerca de qu\u00e9 es el an\u00e1lisis de c\u00f3digo no seguro y c\u00f3mo funciona en Qodana.\u00a0<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-339529 size-medium\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/Blog_Featured_image_1280x600-1-7-1200x563.png\" alt=\"\" width=\"1200\" height=\"563\" \/><\/figure>\n<p align=\"center\"><br \/><a class=\"jb-download-button\" title=\"PRUEBE QODANA GRATIS\" href=\"https:\/\/www.jetbrains.com\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>COMIENCE A USAR QODANA<\/a><\/p>\n<h2>\u00bfQu\u00e9 es el an\u00e1lisis de c\u00f3digo no seguro?<\/h2>\n<p>El c\u00f3digo no seguro es cualquier valor que pueda suponer un riesgo de seguridad cuando un usuario externo lo modifica. Si tiene c\u00f3digo no seguro en el c\u00f3digo y los datos externos no verificados pueden distribuirse a trav\u00e9s del programa, los hackers pueden ejecutar estos fragmentos de c\u00f3digo para provocar una inyecci\u00f3n SQL, desbordamiento aritm\u00e9tico, complementos entre sitios o recorridos de ruta, entre otras cosas. Normalmente, explotan estas vulnerabilidades para destruir el sistema, secuestrar credenciales y otros datos, y cambiar el comportamiento del 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>Ejemplo de c\u00f3digo no seguro. Los datos arbitrarios del par\u00e1metro GET se muestran en la pantalla. Por ejemplo, los usuarios maliciosos pueden aprovechar esta vulnerabilidad para manipular el dise\u00f1o del programa.\u00a0\u00a0<\/figcaption>\n<\/figure>\n<p>A modo de capa extra de defensa contra entradas maliciosas, los equipos de desarrollo ejecutan el an\u00e1lisis de c\u00f3digo no seguro con una auditor\u00eda de seguridad en la superficie de ataque del programa.\u00a0<\/p>\n<p><strong>El an\u00e1lisis de c\u00f3digo no seguro es el proceso de evaluar el flujo de entradas de usuarios no fiables a trav\u00e9s del cuerpo de una funci\u00f3n o un m\u00e9todo. Su objetivo principal es determinar si esa entrada no anticipada puede afectar a la ejecuci\u00f3n del programa de forma maliciosa.\u00a0<\/strong><\/p>\n<p>Las <strong>fuentes de c\u00f3digo no seguro<\/strong> son lugares en los que un programa accede a datos potencialmente no seguros. Los puntos clave de un programa susceptibles de permitir entradas que contienen c\u00f3digo no seguro se denominan <strong>receptores de c\u00f3digo no seguro<\/strong>. Estos datos pueden propagarse a los receptores a trav\u00e9s de llamadas a funciones o asignaciones.<\/p>\n<p>Si ejecuta el an\u00e1lisis de c\u00f3digo no seguro de forma manual, debe detectar todos los lugares en los que acepta datos de usuarios externos y seguir cada uno de los datos a trav\u00e9s del sistema: los datos contaminados pueden utilizarse en muchos nodos. A continuaci\u00f3n, para evitar la propagaci\u00f3n del c\u00f3digo no seguro, debe adoptar uno de los dos enfoques que se describen a continuaci\u00f3n:<\/p>\n<ol>\n<li><strong>Limpiar los datos<\/strong>, es decir, transformarlos a un estado seguro. En el ejemplo siguiente, hemos eliminado las etiquetas para resolver el c\u00f3digo no seguro.\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 los datos<\/strong>, es decir, comprobar que los datos a\u00f1adidos se ajustan a un patr\u00f3n requerido. En el ejemplo siguiente, activamos la validaci\u00f3n para la variable <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>En otras palabras, la inspecci\u00f3n del an\u00e1lisis de c\u00f3digo no seguro rastrea los datos del usuario con c\u00f3digo no seguro desde su origen hasta los receptores, y avisa si se est\u00e1 trabajando con esos datos sin haberlos limpiado o validado.\u00a0<\/p>\n<h2>C\u00f3mo funciona el an\u00e1lisis de c\u00f3digo no seguro en Qodana<\/h2>\n<p>Qodana analiza el c\u00f3digo no seguro para PHP a partir de la versi\u00f3n 2023.1 EAP. Esta funcionalidad incluye una inspecci\u00f3n que escanea el c\u00f3digo y resalta el c\u00f3digo no seguro y la posible vulnerabilidad, la posibilidad de abrir el problema en PhpStorm para abordarlo en el momento, y un gr\u00e1fico de flujo de datos que visualiza el flujo del c\u00f3digo no seguro.\u00a0<\/p>\n<h3>Ejemplo n.\u00ba 1. Inyecci\u00f3n SQL\u00a0<\/h3>\n<p>Veamos un ejemplo de inyecci\u00f3n SQL y c\u00f3mo Qodana la 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>Aqu\u00ed, Qodana nos muestra el c\u00f3digo no seguro en la funci\u00f3n system_admin():<\/p>\n<p>Marcadores 1-2: los datos de la entrada del formulario del usuario se recuperan del vector global <code>$<\/code><code>_POST<\/code> sin ning\u00fan tipo de limpieza o validaci\u00f3n y se asignan a la variable <code>$<\/code><code>edit<\/code>. <strong>Esto es c\u00f3digo no seguro<\/strong>.<\/p>\n<p>Marcador 3: la variable no segura <code>$<\/code><code>edit<\/code> se pasa a la funci\u00f3n system_save_settings como un argumento sin ning\u00fan tipo de limpieza.<\/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: ahora, los datos de la variable <code>$<\/code><code>edit<\/code> se encuentran en el par\u00e1metro <code>$<\/code><code>edit<\/code>.<\/p>\n<p>Marcador 5: la variable <code>$<\/code><code>edit<\/code> se pasa a <code>foreach<\/code> con la clave <code>$<\/code><code>filename<\/code> y el valor <code>$<\/code>status. Ambas variables contienen los datos con c\u00f3digo no seguro de la variable <code>$<\/code><code>edit<\/code> concatenados con la cadena. La clave <code>$<\/code><code>filename<\/code> se concatena con una cadena SQL con c\u00f3digo no seguro y, despu\u00e9s, propagar\u00e1 los datos con c\u00f3digo no seguro a un argumento pasado a db_query.<\/p>\n<p>Marcador 6: la clave <code>$<\/code><code>filename<\/code> contiene los datos con c\u00f3digo no seguro de la variable <code>$<\/code><code>edit<\/code> concatenados con la cadena.<\/p>\n<p>Marcador 7: la clave <code>$<\/code><code>filename<\/code> est\u00e1 concatenada con una cadena SQL con c\u00f3digo no seguro.<\/p>\n<p>Marcador 8: la cadena SQL con c\u00f3digo no seguro propagar\u00e1 los datos con c\u00f3digo no seguro a un argumento pasado a la funci\u00f3n <code>db_query<\/code>.<\/p>\n<p>Veamos ahora la consulta <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: la cadena con c\u00f3digo no seguro se encontrar\u00e1 en el par\u00e1metro <code>$<\/code><code>query<\/code>.<\/p>\n<p>Marcador 10: este par\u00e1metro ser\u00e1 un argumento de la funci\u00f3n <code>_db_query<\/code>.<\/p>\n<p>Pasemos a la funci\u00f3n <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: los datos con c\u00f3digo no seguro se encuentran en el primer par\u00e1metro <code>$<\/code><code>query<\/code> de la funci\u00f3n <code>_db_query<\/code>.<\/p>\n<p>Marcador 12: los datos del par\u00e1metro se pasan a la funci\u00f3n <code>mysql_query<\/code>, que es un receptor.<\/p>\n<p>Todo el flujo de datos anterior ilustra c\u00f3mo los datos se mueven desde <code>$<\/code><code>_POST[\"edit\"]<\/code> a la funci\u00f3n <code>mysql_query($query) sin ning\u00fan tipo de limpieza o validaci\u00f3n. Esto permite al atacante manipular la consulta SQL que se concaten\u00f3 con una clave de <code>$<\/code><code>_POST[\"edit\"]<\/code> y desencadenar la <strong>inyecci\u00f3n SQL<\/strong>.\u00a0<\/code><\/p>\n<p><code><code><\/code><\/code><\/p>\n<p>Qodana detectar\u00e1 estos riesgos en el c\u00f3digo base junto con todos los nodos donde se utilizan datos con c\u00f3digo no seguro, para que pueda limpiar correctamente todos los datos con c\u00f3digo no seguro.\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>Abrir la incidencia en PhpStorm.<\/figcaption>\n<\/figure>\n<p><code><code><\/code><\/code><\/p>\n<h3>Ejemplo n.\u00ba 2. Problema de XSS<\/h3>\n<p><code><code><\/code><\/code><\/p>\n<p>En la interfaz de usuario de Qodana, puede ver un gr\u00e1fico que muestra todo el flujo del c\u00f3digo no seguro. As\u00ed es como Qodana mostrar\u00e1 la vulnerabilidad de XSS, que contiene dos fuentes que se fusionar\u00edan en el 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>Fuente 1<\/strong><\/p>\n<p><code>\n<\/code><\/p>\n<p><code>Marcadores 1-2: se leer\u00e1n los datos del archivo <\/code>searchUpdate.pos y se asignar\u00e1n los datos con c\u00f3digo no seguro a la variable <code>$<\/code><code>start<\/code>.<\/p>\n<p><strong>Fuente 2<\/strong><\/p>\n<p>Marcadores 3-4: se leer\u00e1n los datos de los archivos cuya ruta se encuentre en <code>$<\/code><code>posFile<\/code> y se asignar\u00e1n los datos con c\u00f3digo no seguro a la variable <code>$<\/code><code>start<\/code>.<\/p>\n<p>Marcador 5: un estado fusionado con c\u00f3digo no seguro de todas las ramas condicionales en la variable <code>$<\/code><code>start<\/code> se pasar\u00e1 como argumento al m\u00e9todo doUpdateSearchIndex.<\/p>\n<p>Veamos el interior del m\u00e9todo <code>doUpdateSearchIndex()<\/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>Marcadores 6-8: el par\u00e1metro <code>$<\/code><code>start<\/code> contendr\u00e1 datos con c\u00f3digo no seguro en este fragmento del flujo de datos y, despu\u00e9s, se pasar\u00e1n dentro de una cadena concatenada como argumento al m\u00e9todo <code>output<\/code>.<\/p>\n<p>Veamos el interior del m\u00e9todo <code>output<\/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>Marcador 9: los datos con c\u00f3digo no seguro dentro de la cadena transmitida se ubicar\u00e1n en el par\u00e1metro <code>$<\/code><code>out<\/code>.<\/p>\n<p>Marcador 10: los datos del par\u00e1metro <code>$<\/code><code>out<\/code> se transferir\u00e1n a la funci\u00f3n <code>print<\/code> sin ning\u00fan tipo de limpieza. Esta funci\u00f3n es un receptor y provoca una vulnerabilidad de XSS, que se puede explotar.<\/p>\n<p>Para ello, un atacante puede, por ejemplo, cargar un script de shell en lugar de los archivos esperados en los marcadores 1 y 2, y poner cualquier tipo de informaci\u00f3n en la p\u00e1gina web como resultado de una funci\u00f3n print sin limpiar.<\/p>\n<p>Qodana le avisar\u00e1 de esta vulnerabilidad y le dar\u00e1 una prioridad alta para que pueda resolverla lo antes posible y evitar el hackeo.\u00a0\u00a0<\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>El an\u00e1lisis de c\u00f3digo no seguro ayuda a eliminar las superficies de ataque explotables, por lo que es un m\u00e9todo eficaz para reducir el riesgo al que se expone el software. Para obtener m\u00e1s informaci\u00f3n sobre el an\u00e1lisis de c\u00f3digo no seguro y Qodana, consulte la <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\">documentaci\u00f3n de Qodana<\/a>.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"COMIENCE A USAR QODANA\" href=\"https:\/\/www.jetbrains.com\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>COMIENCE A USAR QODANA<\/a><\/p>\n<p>\u00a1Que tenga un desarrollo feliz y mantenga limpio su c\u00f3digo!<\/p>\n<p><em>Art\u00edculo original en ingl\u00e9s de:<\/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":339529,"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\/es\/wp-json\/wp\/v2\/qodana\/338173"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/qodana"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/qodana"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=338173"}],"version-history":[{"count":8,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/qodana\/338173\/revisions"}],"predecessor-version":[{"id":339574,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/qodana\/338173\/revisions\/339574"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/339529"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=338173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=338173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=338173"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=338173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}