Las extensiones tienen acceso a privilegios especiales dentro del navegador, lo que las convierte en un objetivo atractivo para los atacantes. Si se vulnera una extensión, todos los usuarios de esa extensión se vuelven vulnerables a intrusiones no deseadas y maliciosas. Incorpora estas prácticas para mantener segura una extensión y proteger a sus usuarios.
Protege las cuentas de desarrollador
El código de la extensión se sube y actualiza a través de las Cuentas de Google. Si se hackean las cuentas de los desarrolladores, un atacante podría enviar código malicioso directamente a todos los usuarios. Protege estas cuentas habilitando la autenticación de dos factores , de preferencia con una llave de seguridad.
Usa los roles de miembro adecuados
Si tu publicador tiene varios miembros, asegúrate de que el rol otorgado a cada usuario sea el adecuado.
Nunca uses HTTP
Cuando solicites o envíes datos, evita una conexión HTTP. Supón que cualquier conexión HTTP tendrá intrusos o contendrá modificaciones. Siempre se debe preferir HTTPS, ya que tiene seguridad integrada que evita la mayoría de los ataques de intermediarios.
Solicita permisos mínimos
El navegador Chrome limita el acceso de una extensión a los privilegios que se solicitaron de forma explícita en el manifiesto. Las extensiones deben minimizar sus permisos registrando solo las APIs y los sitios web de los que dependen.
Limitar los privilegios de una extensión limita lo que un posible atacante puede explotar.
fetch() de origen cruzado
Una extensión solo puede usar fetch() y XMLHttpRequest() para obtener recursos de la extensión y de los dominios especificados en los permisos. Ten en cuenta que el controlador fetch del service worker intercepta las llamadas a ambos.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"host_permissions": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"manifest_version": 3
}
En el ejemplo anterior, esta extensión solicita acceso a todo el contenido de developer.chrome.com y los subdominios de Google, ya que incluye "https://developer.chrome.com/*" y "https://*.google.com/*" en los permisos. Si la extensión se viera comprometida, solo tendría permiso para interactuar con los sitios web que cumplan con el patrón de coincidencia. El atacante solo tendría una capacidad limitada para acceder a "https://user_bank_info.com" o interactuar con "https://malicious_website.com".
Limita los campos del manifiesto
Incluir claves y permisos innecesarios en el manifiesto crea vulnerabilidades y hace que una extensión sea más visible. Limita los campos del manifiesto a aquellos de los que depende la extensión.
Se puede conectar de forma externa
Usa el campo "externally_connectable" para declarar con qué extensiones externas y páginas web intercambiará información la extensión. Restringe con quién se puede conectar externamente la extensión a fuentes de confianza.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
Recursos accesibles desde la Web
Si haces que los recursos sean accesibles a través de la Web en "web_accessible_resources", los sitios web y los atacantes podrán detectar la extensión.
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
Cuantos más recursos accesibles a la Web haya disponibles, más vías podrá explotar un posible atacante. Mantén estos archivos al mínimo.
Incluye una política de seguridad del contenido explícita
Incluye una política de seguridad de contenido para la extensión en el manifiesto para evitar ataques de secuencias de comandos entre sitios. Si la extensión solo carga recursos propios, registra lo siguiente:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
Si la extensión necesita usar WebAssembly o aumentar las restricciones en las páginas en zona de pruebas, se pueden agregar de la siguiente manera:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
"sandboxed_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"manifest_version": 3
}
Evita usar document.write() y innerHTML
Si bien puede ser más sencillo crear elementos HTML de forma dinámica con document.write() y innerHTML, la extensión y las páginas web de las que depende quedan expuestas a que los atacantes inserten secuencias de comandos maliciosas. En su lugar, crea nodos DOM de forma manual y usa innerText para insertar contenido dinámico.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
Usa las secuencias de comandos de contenido con cuidado
Si bien las secuencias de comandos de contenido se ejecutan en un mundo aislado, no son inmunes a los ataques:
- Las secuencias de comandos de contenido son la única parte de una extensión que interactúa directamente con la página web. Por este motivo, las páginas web hostiles pueden manipular partes del DOM de las que depende la secuencia de comandos de contenido o aprovechar comportamientos sorprendentes de los estándares web, como los elementos con nombre.
- Para interactuar con el DOM de las páginas web, las secuencias de comandos de contenido deben ejecutarse en el mismo proceso de renderizador que la página web. Esto hace que las secuencias de comandos de contenido sean vulnerables a la filtración de datos a través de ataques de canal lateral (p.ej., Spectre) y a la apropiación por parte de un atacante si una página web maliciosa compromete el proceso de renderizador.
Las operaciones que usan datos sensibles (como la información privada de un usuario) o las APIs de Chrome con acceso a las funciones del navegador se deben realizar en el service worker de las extensiones. Evita exponer accidentalmente privilegios de extensión a secuencias de comandos de contenido:
- Supón que los mensajes de una secuencia de comandos de contenido podrían haber sido creados por un atacante (p.ej., valida y depura todas las entradas, y protege tus secuencias de comandos de las secuencias de comandos entre sitios).
- Supón que cualquier dato que se envíe a la secuencia de comandos de contenido podría filtrarse a la página web. No envíes datos sensibles (p.ej., secretos de la extensión, datos de otros orígenes web o historial de navegación) a las secuencias de comandos de contenido.
- Limita el alcance de las acciones con privilegios que pueden activar las secuencias de comandos de contenido. No permitas que las secuencias de comandos de contenido activan solicitudes a URLs arbitrarias ni pasen argumentos arbitrarios a las APIs de extensiones (p.ej., no permitas que se pasen URLs arbitrarias a los métodos
fetch()ochrome.tabs.create()).
Registra y limpia las entradas
Protege una extensión de secuencias de comandos maliciosas limitando los objetos de escucha solo a lo que espera la extensión, validando los remitentes de los datos entrantes y limpiando todas las entradas.
Una extensión solo debe registrarse para runtime.onMessageExternal si espera comunicación de un sitio web o una extensión externos. Siempre valida que el remitente coincida con una fuente de confianza.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Incluso los mensajes a través del evento runtime.onMessage de la propia extensión deben analizarse para garantizar que el MessageSender no provenga de un script de contenido vulnerado.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});