program tip

Android 8 : 일반 텍스트 HTTP 트래픽이 허용되지 않음

radiobox 2020. 9. 30. 09:12
반응형

Android 8 : 일반 텍스트 HTTP 트래픽이 허용되지 않음


Android 8 사용자로부터 백엔드 피드를 사용하는 내 앱에 콘텐츠가 표시되지 않는다는보고가있었습니다. 조사 후 Android 8에서 다음과 같은 예외가 발생하는 것을 발견했습니다.

08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

(패키지 이름, URL 및 기타 가능한 식별자를 제거했습니다)

Android 7 이하에서는 모든 것이 작동하지만 android:usesCleartextTrafficManifest에서 설정하지 않았 으며 (이를 설정해도 true도움이되지 않습니다. 이것이 기본값입니다) 네트워크 보안 정보를 사용하지도 않습니다. 을 호출 하면 동일한 apk 파일을 사용하여 이전 버전의 Android 8에 대해 NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()반환 됩니다. Android O에 대한 Google 정보에서 이에 대한 언급을 찾으려고했지만 성공하지 못했습니다.falsetrue


에 따르면 네트워크 보안 구성 -

Android 9 (API 레벨 28)부터 일반 텍스트 지원은 기본적으로 사용 중지됩니다.

https://koz.io/android-m-and-the-war-on-cleartext-traffic/도 살펴보십시오.

옵션 1 -

res / xml / network_security_config.xml 파일 생성-

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

옵션 2-

android : usesCleartextTraffic Doc

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

또한 @ david.s의 대답이 지적했듯이 android:targetSandboxVersion문제가 될 수도 있습니다.

매니페스트 문서 에 따르면 -

android:targetSandboxVersion

이 앱에서 사용할 대상 샌드 박스입니다. 샌드 박스 버전 번호가 높을수록 보안 수준이 높아집니다. 기본값은 1입니다. 2로 설정할 수도 있습니다.이 속성을 2로 설정하면 앱이 다른 SELinux 샌드 박스로 전환됩니다. 수준 2 샌드 박스에는 다음 제한 사항이 적용됩니다.

  • usesCleartextTrafficNetwork Security Config 의 기본값 은 false입니다.
  • Uid 공유는 허용되지 않습니다.

따라서 옵션 3-

당신이있는 경우 android:targetSandboxVersion<manifest>그 다음에 그것을 감소1

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?>
<manifest android:targetSandboxVersion="1">
    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

AndroidManifest에서이 매개 변수를 찾았습니다.

android:networkSecurityConfig="@xml/network_security_config"

@ xml / network_security_config는 network_security_config.xml에서 다음과 같이 정의됩니다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!--Set application-wide security config using base-config tag.-->
    <base-config cleartextTrafficPermitted="false"/>
</network-security-config>  

방금 cleartextTrafficPermitted를 true로 변경했습니다.


디버깅 중에는 일반 텍스트 만 허용하고 프로덕션에서 일반 텍스트를 거부하는 보안 이점은 유지하려고 할 수 있습니다. https를 지원하지 않는 개발 서버에서 내 앱을 테스트하기 때문에 유용합니다. 다음은 프로덕션에서 https를 적용하지만 디버그 모드에서 일반 텍스트를 허용하는 방법입니다.

build.gradle에서 :

// Put this in your buildtypes debug section:
manifestPlaceholders = [usesCleartextTraffic:"true"]

// Put this in your buildtypes release section
manifestPlaceholders = [usesCleartextTraffic:"false"]

AndroidManifest.xml의 애플리케이션 태그에서

android:usesCleartextTraffic="${usesCleartextTraffic}"

Android 9의 내 문제는 http가있는 도메인을 통해 webview에서 탐색하는 것입니다. 이 답변의 해결책

<application 
    android:networkSecurityConfig="@xml/network_security_config"
    ...>

과:

res / xml / network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

Change your url's from HTTP to HTTPS;

It works out!!!


<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
    </domain-config>
</network-security-config>

In the suggestion provided above I was providing my URL as http://xyz.abc.com/mno/

I changed that to xyz.abc.com then it started working.


It could be useful for someone.

We recently had the same issue for Android 9, but we only needed to display some Urls within WebView, nothing very special. So adding android:usesCleartextTraffic="true" to Manifest worked, but we didn't want to compromise security of the whole app for this. So the fix was in changing links from http to https


Ok, that is ⇒⇒ NOT ⇐⇐ the thousands repeat of add it to your Manifest, but an hint which base on this, but give you additional Benefit (and maybe some Background Info).

Android has a kind of overwriting functionality for the src-Directory.

By default, you have

/app/src/main

But you can add additional directories to overwrite your AndroidManifest.xml. Here is how it works:

  • Create the Directory /app/src/debug
  • Inside create the AndroidManifest.xml

Inside of this File, you don't have to put all the Rules inside, but only the ones you like to overwrite from your /app/src/main/AndroidManifest.xml

Here an Example how it looks like for the requested CLEARTEXT-Permission:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.yourappname">

    <application
            android:usesCleartextTraffic="true"
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:allowBackup="false"
            android:theme="@style/AppTheme">
    </application>

</manifest>

With this knowledge it's now easy as 1,2,3 for you to overload your Permissions depending on your debug | main | release Enviroment.

The big benefit on it... you don't have debug-stuff in your production-Manifest and you keep an straight and easy maintainable structure


For React Native projects

It was already fixed on RN 0.59. You can find on upgrade diff from 0.58.6 to 0.59 You can apply it without upgrading you RN versionust follow the below steps:

Create files:

android/app/src/debug/res/xml/react_native_config.xml -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="false">localhost</domain>
    <domain includeSubdomains="false">10.0.2.2</domain>
    <domain includeSubdomains="false">10.0.3.2</domain>
  </domain-config>
</network-security-config>

android/app/src/debug/AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

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

  <application tools:targetApi="28"
      tools:ignore="GoogleAppIndexingWarning" 
      android:networkSecurityConfig="@xml/react_native_config" />
</manifest>

Check the accepted answer to know the root cause.


Okay, I have figured this out. It is due to the Manifest parameter android:targetSandboxVersion="2", that I have added because we also have Instant App version - it should make sure than once user upgrades from Instant App to regular app, he will not loose his data with the transfer. However as the vague description suggest:

Specifies the target sandbox this app wants to use. Higher sanbox versions will have increasing levels of security.

The default value of this attribute is 1.

It obviously also adds new level of security policy, at least on Android 8.


To apply these various answers to Xamarin.Android, you can use class and assembly level Attributes vs. manually editing the AndroidManifest.xml

Internet permission of course is needed (duh..):

[assembly: UsesPermission(Android.Manifest.Permission.Internet)]

Note: Typically assembly level attributes are added to your AssemblyInfo.cs file, but any file, below the using and above the namespace works.

Then on your Application subclass (create one if needed), you can add NetworkSecurityConfig with a reference to an Resources/xml/ZZZZ.xml file:

#if DEBUG
[Application(AllowBackup = false, Debuggable = true, NetworkSecurityConfig = "@xml/network_security_config")]
#else
[Application(AllowBackup = true, Debuggable = false, NetworkSecurityConfig = "@xml/network_security_config"))]
#endif
public class App : Application
{
    public App(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }
    public App() { }

    public override void OnCreate()
    {
        base.OnCreate();
    }
}

Create a file in the Resources/xml folder (create the xml folder if needed).

Example xml/network_security_config file, adjust as needed (see other answers)

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
          <domain includeSubdomains="true">www.example.com</domain>
          <domain includeSubdomains="true">notsecure.com</domain>
          <domain includeSubdomains="false">xxx.xxx.xxx</domain>
    </domain-config>
</network-security-config>

You can also use the UsesCleartextTraffic parameter on the ApplicationAttribute:

#if DEBUG
[Application(AllowBackup = false, Debuggable = true, UsesCleartextTraffic = true)]
#else
[Application(AllowBackup = true, Debuggable = false, UsesCleartextTraffic = true))]
#endif

I am also got the same "Cleartext HTTP traffic not permitted" error while developing my Application. I am using Retrofit2 for network calls in my application and I have two project environments(dev & production). My Production domain is having SSL certificate with HTTPS calls and dev won't have https. The configuration is added in the build flavors. But when I change to dev, this issue will trigger. So I have added below-solution for that.

I have added cleartext traffic in the manifest

 android:usesCleartextTraffic="true"

Then I have added a connection spec in the retrofit configuration class OKHttp creation time.

 .connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))

Complete OkHttpClient creation is given below

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(10, TimeUnit.SECONDS)
        .connectTimeout(10, TimeUnit.SECONDS)
        .cache(null)
        .connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
        .addInterceptor(new NetworkInterceptor(context))
        .addInterceptor(createLoggingInterceptor())
        .addInterceptor(createSessionExpiryInterceptor())
        .addInterceptor(createContextHeaderInterceptor())
        .build();

adding these paramter in header resolved my issue in apiSauce

"Content-Type": "application/x-www-form-urlencoded",
  Accept: "application/json"

Upgrade to React Native 0.58.5 or higher version. They have includeSubdomain in their config files in RN 0.58.5.

ChangeLog

In Rn 0.58.5 they have declared network_security_config with their server domain. Network security configuration allows an app to permit cleartext traffic from a certain domain. So no need to put extra effort by declaring android:usesCleartextTraffic="true" in the application tag of your manifest file. It will be resolved automatically after upgrading the RN Version.


After changed API version 9.0 getting the error Cleartext HTTP traffic to YOUR-API.DOMAIN.COM not permitted (targetSdkVersion="28"). in xamarin, xamarin.android and android studio.

Two steps to solve this error in xamarin, xamarin.android and android studio.

Step 1: Create file resources/xml/network_security_config.xml

In network_security_config.xml

<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">mobapi.3detrack.in</domain>
  </domain-config>
</network-security-config>

Step 2: update AndroidManifest.xml -

Add android:networkSecurityConfig="@xml/network_security_config" on application tag. e.g:

<application android:label="your App Name" android:icon="@drawable/icon" android:networkSecurityConfig="@xml/network_security_config">

In my case that URL is not working in browser also.

I check with https://www.google.com/

webView.loadUrl("https://www.google.com/")

And it worked for me.

참고URL : https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted

반응형