{"id":4732,"date":"2026-09-21T13:40:22","date_gmt":"2026-09-21T11:40:22","guid":{"rendered":"https:\/\/davidperezgar.com\/?p=4732"},"modified":"2026-09-21T13:41:37","modified_gmt":"2026-09-21T11:41:37","slug":"una-linea-en-npmrc-que-blinda-tu-proyecto-contra-ataques-a-npm","status":"publish","type":"post","link":"https:\/\/davidperezgar.com\/es\/una-linea-en-npmrc-que-blinda-tu-proyecto-contra-ataques-a-npm\/","title":{"rendered":"Una l\u00ednea en .npmrc que blinda tu proyecto contra ataques a npm"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Si trabajas con WordPress y tienes un build de JavaScript por medio (Gutenberg, temas modernos, plugins con React\u2026), est\u00e1s usando npm. Y npm lleva meses siendo el patio de recreo favorito de los ataques de cadena de suministro: alguien compromete la cuenta del mantenedor de un paquete popular, publica una versi\u00f3n con c\u00f3digo malicioso, y en cuesti\u00f3n de horas hay miles de proyectos infectados por el mundo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La buena noticia: hay una l\u00ednea de configuraci\u00f3n que corta la mayor\u00eda de estos ataques en seco.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La l\u00ednea m\u00e1gica<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Abre (o crea) el archivo <code>.npmrc<\/code> en la ra\u00edz de tu proyecto y a\u00f1ade:<\/p>\n\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\"><code>min-release-age=7<\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Ya est\u00e1. Eso es todo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Qu\u00e9 hace exactamente<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Con esa l\u00ednea, npm ignora cualquier versi\u00f3n de cualquier paquete publicada hace menos de 7 d\u00edas. Es decir: aunque <code>paquete-popular@2.5.7<\/code> acabe de salir hace 3 horas, tu instalaci\u00f3n no la tocar\u00e1. Se quedar\u00e1 en la \u00faltima versi\u00f3n que ya tenga al menos una semana de vida.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfPor qu\u00e9 funciona esto contra los ataques? Porque cuando comprometen un paquete popular, la comunidad lo detecta muy r\u00e1pido \u2014normalmente en horas\u2014 y la versi\u00f3n maliciosa se retira. Con una ventana de 7 d\u00edas, t\u00fa ni siquiera llegas a instalarla. El ataque pasa por delante de tu proyecto sin tocarlo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Requisitos<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Necesitas <strong>npm 11.10.0 o superior<\/strong>. Comprueba tu versi\u00f3n con:<\/p>\n\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\"><code>npm --version\n<\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Y si te hace falta, actualiza con:<\/p>\n\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\"><code>npm install -g npm@latest\n<\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Dos cosas que NO arregla (importante saberlas)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Esto no es una bala de plata. Hay dos escenarios en los que <code>min-release-age<\/code> no te salva:<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\"><li><p><strong>Si tu <code>package-lock.json<\/code> ya est\u00e1 envenenado, da igual.<\/strong> El lockfile manda: si dice que hay que instalar la versi\u00f3n X, npm instala la versi\u00f3n X, tenga la antig\u00fcedad que tenga. Revisa siempre los cambios en el lockfile antes de mergear pull requests, especialmente los autom\u00e1ticos de Dependabot y compa\u00f1\u00eda.<\/p><\/li><li><p><strong><code>npx<\/code> se salta la protecci\u00f3n.<\/strong> <code>npx<\/code> ejecuta paquetes sin pasar por tu configuraci\u00f3n de instalaci\u00f3n, as\u00ed que la restricci\u00f3n no se aplica. Ojo con lo que ejecutas por ah\u00ed, sobre todo en scripts de CI.<\/p><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 deber\u00edas hacerlo hoy?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Porque el coste es literalmente escribir una l\u00ednea en un archivo, y el beneficio es blindarte contra el 90% de los ataques de cadena de suministro que est\u00e1n pasando ahora mismo en npm.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si mantienes un proyecto WordPress con build de JavaScript \u2014un tema propio, un plugin con bloques Gutenberg, un headless con Next.js encima\u2014 esta es probablemente la mejor relaci\u00f3n coste\/beneficio en seguridad que puedes conseguir hoy en tu stack.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No lo dejes para ma\u00f1ana. A\u00f1\u00e1delo, commitea, y a otra cosa.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Los ataques de cadena de suministro en npm est\u00e1n a la orden del d\u00eda. Con una sola l\u00ednea en tu .npmrc puedes evitar la inmensa mayor\u00eda de ellos en tus proyectos WordPress con build de JS. Te cuento cu\u00e1l es, c\u00f3mo funciona y qu\u00e9 limitaciones tiene.<\/p>\n","protected":false},"author":1,"featured_media":5024,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":7,"footnotes":""},"categories":[168],"tags":[],"class_list":["post-4732","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollo-web"],"_links":{"self":[{"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/posts\/4732","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/comments?post=4732"}],"version-history":[{"count":1,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/posts\/4732\/revisions"}],"predecessor-version":[{"id":5988,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/posts\/4732\/revisions\/5988"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/media\/5024"}],"wp:attachment":[{"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/media?parent=4732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/categories?post=4732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/davidperezgar.com\/es\/wp-json\/wp\/v2\/tags?post=4732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}