Сегодня Android является одной из наиболее популярных мобильных платформ, используемой в смартфонах, планшетах, умных часах, телевизорах и даже автомобилях. Открытость платформы, широчайшее разнообразие используемых версий и реализаций выводит вопрос безопасности на первый план при создании Android-приложений.

Как известно, безопасность обеспечивается системой разрешений доступа на каждом конкретном Android-устройстве. Эта система призвана защищать важные данные и предотвращать несанкционированный доступ к информации или каналам связи.

По умолчанию ни у одного Android-приложения нет разрешения на проведение операций, которые могут повлиять на ОС, личные данные или другие приложения. Однако без подобного разрешения любое приложение станет бесполезным.

Разрешения являются своеобразным фильтром для функционала приложений, и только от пользователя зависит, давать ли доступ к данным во время инсталляции. Проблема в том, что пользователи обычно не читают, к чему именно хочет получить доступ приложение, и, не задумываясь, его разрешают. Такое поведение создаёт предпосылки для злоупотребления личными данными или даже модифицирования ядра.

Здесь мы рассмотрим существующую систему манифестов и разрешений в Android. Файл манифеста содержит информацию о пакете приложения, включая разрешения, поставщиков контента, сервисы, активности и широковещательных приёмников (broadcast receivers).

Пример общей структуры файла манифеста. Цветом выделены запросы на получение разрешений:



Самые опасные разрешения


Чтобы решить, к каким данным можно дать доступ, пользователь должен помнить о предназначении этого приложения. Например, «Зачем игре понадобился доступ к моей адресной книге или разрешение отправлять SMS?» Очевидно, что игры не предполагают отправки SMS. Подобные несоответствия функционала запросам доступа должны настораживать в первую очередь.

Разрешения, которые в будущем вы возможно захотите пересмотреть


  1. Запрос root-прав. Пользователь с root-правами может управлять системой без каких-либо ограничений. По умолчанию в Android таких прав не даётся, поскольку неопытные пользователи могут натворить бед. Root-права предоставляются процессом под названием “Rooting the Android device”. И если их получает злонамеренное приложение, то оно сможет делать всё, что ему заблагорассудится.

    Вот небольшой пример того, как приложение запускает shell-скрипт с правами привилегированного пользователя, чтобы перезагрузить устройство:

    	try {
    
        		String[] reboot = new String[] { "su", "-c", "reboot" };
        		//-c will cause the next argument to be treated as a command
    
       		Process process = Runtime.getRuntime().exec(reboot);
    
    process.waitFor();  //wait for the native process to finish executing.
    
          		} catch (Exception e) {
    
    Toast.makeText(getApplicationContext()," Device not rooted.\n Could not reboot...",Toast.LENGTH_SHORT).show();
    
        	}
    

    С помощью команды su приложение запускается с привилегированными правами, и если устройство рутованно, то оно перезагружается. Если же нет, то появляется сообщение:



    Чтобы запросить доступ к root:



    нужно добавить в файл манифеста строку:

    <uses-permission android:name="android.permission.ACCESS_SUPERUSER"></permission>
  2. Запрос разрешения на чтение и запись личных данных. Если вы хотите, чтобы пользователи не переживали за свои личные данные, то не используйте в манифесте подобные запросы:

    <uses-permission android:name="android.permission.READ_CALENDAR"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"></uses-permission>
    <uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
    <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>
  3. Разрешения, связанные с финансовыми расходами. Некоторые разрешения, бездумно предоставленные пользователями, могут стоить им денег. Чаще всего это отправка SMS/MMS и совершение голосовых вызовов. Причём происходить это может в фоновом режиме, без вызова стандартного телефонного приложения.
    Запрос на отправку сообщений:

    <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

    Запрос на совершение звонков:

    <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

    Простой пример отправки SMS:

    	String message = "Hello Android fans! ";
      		String number = "xxxxxxxxxxxx";
      		//it is preferable to use a complete international number
    
    SmsManager.getDefault().sendTextMessage(number, null, message, null, null);
    

    Обратите внимание, что данный код будет работать только в том случае, если соответствующий запрос содержится в файле манифеста:

    <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
  4. Доступ к данным геолокации. Если пользователь разрешит, то приложение в любое время сможет получать информацию о:

    • примерном местоположении пользователя согласно данным базовых станций и точек Wi-Fi;
    • точном местоположении пользователя согласно данным GPS, базовых станций и Wi-Fi.

    Запрос доступа к данным о примерном местоположении:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>

    Запрос доступа к данным о точном местоположении:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

    Вот как осуществляется получение данных о точном местоположении:

    public class MainActivity extends Activity implements LocationListener {
    
         private LocationManager locationManager;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
    
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
    
             locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
             locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                     3000, 10, this);
    
         }
    
      @Override
         public void onLocationChanged(Location location) {
    
             String myLocation ="Location changed...\n\nYou are located at: " + "\nLatitude: " + location.getLatitude()
                     + "\nLongitude: " + location.getLongitude();
    
             Toast.makeText(getApplicationContext(), myLocation, Toast.LENGTH_LONG).show();
         }
    
         @Override
         public void onProviderDisabled(String provider) {
    
             Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
             startActivity(intent);
             Toast.makeText(getApplicationContext(), "Gps is turned off... ",
                     Toast.LENGTH_SHORT).show();
         }
    
         @Override
         public void onProviderEnabled(String provider) {
    
             Toast.makeText(getApplicationContext(), "Gps is turned on... ",
                     Toast.LENGTH_SHORT).show();
         }
    
         @Override
         public void onStatusChanged(String provider, int status, Bundle extras) {
    
         }
    
      }
    

    Не забывайте, что работоспособность данного кода зависит от наличия соответствующего запроса в файле манифеста.

    Java-класс MainActivity внедряет LocationListener для получения нужных данных от устройства. Запрос текущего местоположения осуществляется вызовом requestLocationUpdates() в методе onCreate(). Когда местоположение изменяется, то для получения новых данных вызывается onLocationChanged(). Если GPS-данные недоступны, то вызывается метод onProviderDisabled(), передающий приложению информацию о местоположении.

  5. Доступ к аудио- и видео. Если пользователь даёт такие разрешения, то он рискует тем, что его будут прослушивать или использовать камеру смартфона для слежки. Запросы доступа в файле манифеста:

    <uses-permission android:name="android.permission.CAMERA"></uses-permission>
    <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"></uses-permission>
    <uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"></uses-permission>
    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
  6. Установка пакетов. Если дать такое разрешение, то приложение сможет устанавливать дополнительные пакеты без ведома пользователя.

    <permission android:name="android.permission.INSTALL_PACKAGES"></permission>
  7. Остановка фоновых процессов. Данное разрешение позволяет приложению вызывать killBackgroundProcesses(String), с чьей помощью оно может останавливать любые выполняющиеся в фоновом режиме процессы.

    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"></uses-permission>


Android Marshmallow


В шестой версии Android, анонсированной в мае 2015 года, реализован новый механизм разрешений. Теперь они будут запрашиваться не во время установки приложения, а при первой попытке использования какой-либо функции. Будем надеяться, что это существенно облегчит жизнь как разработчикам, так и пользователям.

Комментарии (6)


  1. HotIceCream
    06.10.2015 13:57
    +2

    android.permission.INSTALL_PACKAGES

    Не вводите в заблуждение людей — это разрешение доступно только системным приложениям. Что бы приложение стало системным — надо еще помучиться.

    Вот его объявление:

    <permission android:name=«android.permission.INSTALL_PACKAGES»
    android:label="@string/permlab_installPackages"
    android:description="@string/permdesc_installPackages"
    android:protectionLevel=«signature|system» />


    android.permission.KILL_BACKGROUND_PROCESSES

    Опять же убьет не все приложения. А только те, которые работают в фоне (За исключением foreground service).

    android.permission.SEND_SMS

    Информация немного неактуальна. Сейчас отправлять смс могут не все подрят приложения, а только выбранные в качестве смс мэнеджера. Если я не путаю ничего)


    1. Ganster41
      06.10.2015 14:39
      +1

      И отправлять, и принимать SMS могут все. А вот управлять хранилищем — только выбранное по-умолчанию.


  1. petrovichtim
    06.10.2015 15:48

    С помощью команды su приложение запускается с привилегированными правами, и если устройство рутованно, то оно перезагружается. Если же нет, то появляется сообщение:

    Рут не так работает.
    Если устройство рутовано, то оно или спросит дать доступ приложению к руту или вообще ничего не спросит, а просто выполнит команду.
    Если устройство не рутовано, то вывалится ошибка, а в текущем примере просто сообщение.


    1. lopatoid
      07.10.2015 10:59

      Причём нестандартный пермишн android.permission.ACCESS_SUPERUSER не имеет никакого значения, тут подробнее:
      https://plus.google.com/+Chainfire/posts/Ka3ujLb4bJu


  1. KamiSempai
    06.10.2015 16:53

    Будем надеяться, что это существенно облегчит жизнь как разработчикам, так и пользователям.
    Сильно сомневаюсь на счет разработчиков.


  1. bahusvip
    07.10.2015 16:41

    Теперь они будут запрашиваться не во время установки приложения, а при первой попытке использования какой-либо функции.

    Не совсем так. Если приложение будет собираться под более старые версии (android:targetSdkVersion), то все права будут запрашиваться при установке с помощью диалога, как и раньше. После установки пользователь сможет вручную отозвать разрешения.