Introducción
Dado el florecimiento del ecosistema NFT en Ethereum y el aumento de los problemas de seguridad relacionados, publicaremos una serie de blogs para presentar estos problemas de seguridad y ofrecer algunas sugerencias a los desarrolladores para proteger los contratos. En este blog, presentaremos el problema de reentrada en los contratos NFT y cómo mitigar la vulnerabilidad relacionada.
¿Qué es la Reentrada?
Según wikipedia
En informática, se dice que un programa de computadora o subrutina es reentrante si múltiples invocaciones pueden ejecutarse de forma segura y concurrente en múltiples procesadores, o en un sistema de un solo procesador, donde un procedimiento reentrante puede interrumpirse en medio de su ejecución y luego ser llamado de nuevo con seguridad ("reentrarse") antes de que sus invocaciones anteriores completen la ejecución.
En un contrato inteligente, la reentrada puede ocurrir cuando una función ejecuta una llamada externa a otro contrato, que a su vez invoca la función original (u otras funciones) antes de que la invocación original retorne. Si la llamada externa es controlada por una entidad no confiable (por ejemplo, un contrato malicioso), puede provocar un resultado inesperado. Esto se debe a que, en algunas funciones, el resultado depende del estado del contrato. El estado del contrato se actualizará después de la llamada externa. Sin embargo, la invocación reentrante de la función usará el estado antiguo en lugar del actualizado.
La reentrada ha sido un problema frecuente en los contratos inteligentes, por ejemplo, el ataque a MakerDAO, el ERC777 en Uniswap, y otros (busca Reentrada en BlockSec Academy).
Reentrada en NFT

Para los contratos NFT, existen algunas llamadas a funciones externas implícitas que los desarrolladores podrían pasar por alto. Estas incluyen las funciones onERC721Received y onERC1155Received. La función onERC721Received fue diseñada para verificar si el contrato receptor puede manejar NFTs (para evitar que los NFTs queden bloqueados para siempre). Esta función se invoca en safeTransferFrom y _safeMint del contrato ERC721. Una similar existe en el contrato ERC1155. Debido a estas llamadas a funciones externas, la reentrada podría ocurrir sin que los desarrolladores de contratos lo noten.
Reentrada en una Sola Función
La reentrada en una sola función es la forma más simple de ataque de reentrada. En este tipo de ataque de reentrada, la función re-invocada es la misma que la función original. Un atacante puede invocar la función repetidamente antes de que la primera invocación de la función se complete. En los contratos NFT, esto suele ocurrir en las funciones relacionadas con la operación de mint.
Por ejemplo, algunos proyectos NFT pueden dar a cada usuario la oportunidad de acuñar un NFT de forma gratuita, establecer el suministro máximo de todo el proyecto, o establecer la cantidad máxima de NFTs que un usuario puede tener. Normalmente, estas restricciones se verifican antes de la operación de acuñación real. Pero si los estados relacionados con estas restricciones se actualizan después de la función safeMint, el atacante puede reingresar a esta función de acuñación y eludir las restricciones, ya que los estados relacionados son los mismos que en la primera invocación de esta función. El ataque de reentrada de HypeBears publicado en nuestro blog anterior es un ejemplo.
Una reentrada en una sola función más complicada ocurre cuando la función safeMint se usa en un bucle y las restricciones se verifican antes de que el bucle comience. En este escenario, aunque algunos estados se actualicen automáticamente antes de la llamada externa, las llamadas restantes a la función safeMint en el bucle aún pueden eludir la validación, ya que el bucle ya ha comenzado y la validación ocurre antes de que el bucle empiece.
Por ejemplo, en el ejemplo mostrado en otra publicación, la función mintNFT verificará si la cantidad de NFTs que el usuario desea acuñar más el suministro actual puede superar el suministro máximo. La función safeMint actualiza el suministro total antes de la llamada externa onERC721Received. Un atacante aún puede explotarlo ya que la función safeMint solo incrementa el suministro total en 1 cada vez. Por lo tanto, si el atacante reingresa a la función mintNFT en la primera llamada a la función safeMint en el bucle, el suministro total se convierte en el suministro anterior más 1, en lugar del suministro anterior más la cantidad de NFTs que serán acuñados por la primera llamada a mintNFT.
Reentrada entre Funciones
En lugar de ingresar a la misma función, el atacante puede ingresar a otra función que comparte o depende de los estados con la función de origen. Hemos detallado algunos casos en nuestros blogs anteriores para el caso Revest y el caso OMNI.
Resumen y Sugerencias
Aquí hay algunas sugerencias para que los desarrolladores de contratos inteligentes NFT mitiguen la amenaza de reentrada.
- Usa el Patrón Checks-Effects-Interactions en tu código.
- Ten cuidado al usar cualquier biblioteca de terceros que introduzca llamadas externas. Para los contratos NFT, sé cauteloso con la devolución de llamada implícita de las funciones
onERC721ReceivedyonERC1155Received.
Lee el Otro Artículo de Esta Serie
Acerca de BlockSec
BlockSec es una empresa pionera en seguridad blockchain establecida en 2021 por un grupo de expertos en seguridad de renombre mundial. La empresa está comprometida a mejorar la seguridad y la usabilidad para el emergente mundo Web3 con el fin de facilitar su adopción masiva. Con este fin, BlockSec ofrece servicios de auditoría de seguridad de contratos inteligentes y cadenas EVM, la plataforma Phalcon para el desarrollo de seguridad y el bloqueo proactivo de amenazas, la plataforma MetaSleuth para el rastreo e investigación de fondos, y la extensión MetaSuites para que los desarrolladores de web3 naveguen eficientemente en el mundo cripto.
Hasta la fecha, la empresa ha atendido a más de 300 distinguidos clientes como MetaMask, Uniswap Foundation, Compound, Forta y PancakeSwap, y ha recibido decenas de millones de dólares en dos rondas de financiación de destacados inversores, incluidos Matrix Partners, Vitalbridge Capital y Fenbushi Capital.
Sitio web oficial: https://blocksec.com/
Cuenta oficial de Twitter: https://twitter.com/BlockSecTeam



