Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Интенты (intent) — одна из ключевых идей Android. Интенты позволяют пересылать сообщения между компонентами приложений и системных сервисов с целью вызвать определенное действие. Запускаются приложения, открываются ссылки, инициируются звонки и многое другое в Android делается с помощью интентов.
Поверх интентов построен другой механизм — отложенные интенты (PendingIntent). Он позволяет передать интент другому приложению или компоненту системы, чтобы то могло отправить интент от имени передавшего его приложения.
Проблема отложенных интентов только в том, что в ряде случаев можно изменить записанный в них интент (это можно сделать, если не установлен флаг FLAG_IMMUTABLE
) и в итоге выполнить произвольное действие от имени передавшего PendingIntent приложения.
Отложенные интенты чаще всего используются в следующих компонентах:
NotificationListenerService
, который будет слушать все уведомления приложений и извлекать из них отложенные интенты.SliceViewManager
или ContentResolver
и затем получить PendingIntent всех слайсов.MediaBrowser
.AppWidgetHost
позволяет приложению прикинуться лаунчером и получить доступ к виджетам приложений. Далее PendingIntent можно извлечь из самого виджета.В качестве примера уязвимости в одном из этих компонентов приведем CVE-2020-0188. Это уязвимость в SliceProvider’е стандартных настроек Android. Благодаря тому что PendingIntent был открыт для изменения, его можно было вытащить с помощью ContentResolver
, а затем изменить так, чтобы прочитать приватные файлы приложения «Настройки»:
Intent hijackIntent =new Intent();
hijackIntent.setPackage(getPackageName());
hijackIntent.setDataAndType(Uri.parse("content://com.android.settings.files/my_cache/NOTICE.html"), "txt/html");
hijackIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
pi.send(getApplicationContext(),0,hijackIntent,null,null);
По сути, этот код заставляет приложение «Настройки» передать ссылку на свой внутренний файл с правами на чтение и запись приложению‑эксплоиту. Остается только принять интент, и можно делать с файлом все, что угодно.
Рекомендации разработчикам:
FLAG_IMMUTABLE
при создании PendingIntent.ComponetName
. В этом случае злоумышленник не сможет перенаправить интент.Are iPhones Really Better for Privacy? Comparative Study of iOS and Android Apps — исследование использования трекинговых библиотек в приложениях для Android и iOS. Авторы работы взяли 12 тысяч приложений для каждой платформы, проанализировали их код и сетевые подключения и пришли к следующим выводам:
Coroutines and Java Synchronization Don’t Mix — небольшая заметка о неочевидной для некоторых программистов особенности взаимодействия корутин Kotlin и блокировок.
Все мы знаем об аннотации @Synchronized
(или блоке synchronized
), которая говорит о том, что код функции может выполняться только в одном потоке одновременно:
repeat(2) {
thread {criticalSection() }
}
@Synchronized
fun criticalSection() {
println("Starting!")
Thread.sleep(10)
println("Ending!")
}
Два потока в этом примере выполнят код функции последовательно, один за другим:
Starting!
Ending!
Starting!
Ending!
Однако если мы заменим потоки корутинами, то все изменится:
val scope =CoroutineScope(Job())
repeat(2) {
scope.launch {criticalSectionsuspending() }
}
@Synchronized
suspend fun criticalSectionsuspending() {
println("Starting!")
delay(10)
println("Ending!")
}
Вывод будет таким:
Starting!
Starting!
Ending!
Ending!
Другими словами, аннотация @Synchronized
будто бы не работает в случае корутин.
На самом деле объяснение в том, что обе корутины в данном примере работают в одном потоке. А это влечет за собой два следствия:
Другими словами, @Synchronized
просто не имеет смысла для корутин, работающих в одном потоке. И вместо нее следует использовать класс Mutex
.
|
|