Към съдържанието

Една буква разлика в URL на Hugging Face Chat UI дава пълен достъп до всички чатове

Една буква разлика в URL на Hugging Face Chat UI дава пълен достъп до всички чатовеСнимка: Shutterstock

# Архитектурен пропуск в Hugging Face Chat UI пълно заобикаляне на административната автентикация и експорт на чужди чатове чрез елементарен URL трик с %61dmin

Христо Ласков

Христо Ласков работи помежду технологиите, дизайна, бизнеса, сигурността и комуникациите. Създава, разглобява и се опитва да разбере защо нещата работят.

Ако някога сте се чудили защо нарушеният контрол на достъпа (Broken Access Control) упорито държи първото място в класацията OWASP Top 10, един-единствен ред код от популярния интерфейс за изкуствен интелект Hugging Face Chat UI дава съвършения отговор. Оказва се, че разделението между поверителните разговори на потребителите и пълното им публично източване може да виси на една обикновена проверка на стринг.

За проблема съобщава изследователят Паскале Пилитери (Pasquale Pillitteri), анализирайки кода на официалния проект huggingface/chat-ui. Уязвимостта засяга административните API маршрути и по-специално ендпойнта за експорт на данни (/admin/export), който съхранява пълната история на чатовете.

Анатомия на разминаването: Как работи трикът с %61

Защитата на административния интерфейс разчита на защитен хук (guard), който изисква таен ключ ADMIN_API_SECRET, ако заявката е насочена към административната част на приложението. Логиката за проверка изглежда по следния начин:

text
if (event.url.pathname.startsWith(`${base}/admin/`)) {
    /* изисква валиден ADMIN_API_SECRET */
}

Уловката е в архитектурното разминаване (parser mismatch) между два компонента на платформата:

  • Обектът event.url следва стандарта WHATWG URL. Неговото свойство .pathname не декодира т.нар. percent-encoding за стандартни символи от латиницата. Когато нападател изпрати заявка към /%61dmin/export (където %61 е шестнадесетичният код на буквата „a“), event.url.pathname връща точно "/%61dmin/export". Тъй като този низ не започва с /admin/, условието се оценява като false и проверката за автентикация просто се пропуска.

  • В същото време рутерът на SvelteKit вътрешно прилага функцията decodeURI() при разпределянето на пътищата. Тъй като decodeURI('%61') === 'a', SvelteKit маршрутизира заявката директно към легитимния административен хендлър /admin/export.

Крайният резултат: заявката стига до административния скрипт, защитният филтър е заобиколен без токен за достъп, а нападателят получава възможност да свали базата данни с чатовете на всички потребители.

Не е ясно дали уязвимостта е експлоатирана или не, а самите Hugging Face са уколнчиви в коментарите си по темата.

Риск за self-hosted инсталации

Проблемът е особено критичен за организации, които са внедрили исталация на Hugging Face Chat UI с публичен достъп от интернет, разчитайки на фабричната защита на тайния административен ключ. Всеки неавтентикиран външен потребител може да изпрати една-единствена манипулирана заявка и да получи достъп до конфиденциалните диалози с невронните мрежи.

За да се защитите:

  • ъпдейтнете Hugging Face Chat UI - макар и тохомълком, казусът е решен в този комит, където проверката за автентникация вече се осъществява по route id, а не по стринга;

  • ако пишете приложения, избягвайте проверка на права за достъп чрез низови операции от типа на startsWith() в middleware-а си – защитата трябва да се управлява директно на ниво контролер или route;

  • ограничете мрежовия достъп до административните интерфейси през защитна стена, VPN или Reverse Proxy филтри, които блокират кодирани управляващи пътища.

Източник: pasqualepillitteri.it ↗ (нов прозорец)

Още за Уязивмости, експлойти, ъпдейти