Search code examples
androidretrofit2

Android error for CLEARTEXT communication to xxxxx not permitted by network security policy


The error CLEARTEXT communication to xxx not permitted by network security policy occurs when I connect the api server with tls 1.2 to retrofit. I know that this error occurs when you connect to http, is there any other reason? Is there anything I missed? My api server only compatible tls 1.2 My project target sdk 33, retrofit ver 2.9.0, okhttp 4.9.2

I want not use like this

At first, only the address was changed, but it didn't work, so make a ca certificate with fullchain.pem and add a client using ok http, the above error occurs.


object RetrofitObj {
    private const val BASE_URL = base_api_url

    fun create(context: Context): Retrofit {

        val tmf: TrustManagerFactory? = getTrustManagerFactory(context)
        var sslsocket = tmf?.let { getSSLSocketFactory(it) }
        val hostnameVerifier = HostnameVerifier { _, session ->
            HttpsURLConnection.getDefaultHostnameVerifier().run {
                verify(VERIFY_DOMAIN, session)
            }
        }

        val client = sslsocket?.let {
            OkHttpClient.Builder()
                .sslSocketFactory(it, tmf?.trustManagers?.get(0) as X509TrustManager)
                .hostnameVerifier(hostnameVerifier)
                .build()
        }

        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

    }

    private fun getTrustManagerFactory(context: Context): TrustManagerFactory? {
        val cf: CertificateFactory = CertificateFactory.getInstance("X.509")
        val caInput: InputStream = context.resources.openRawResource(R.raw.fullchain2)
        val ca: X509Certificate = caInput.use {
            cf.generateCertificate(it) as X509Certificate
        }

        val keyStoreType = KeyStore.getDefaultType()
        val keyStore = KeyStore.getInstance(keyStoreType).apply {
            load(null, null)
            setCertificateEntry("ca", ca)
        }

        val tmfAlgorithm: String = TrustManagerFactory.getDefaultAlgorithm()
        val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm).apply {
            init(keyStore)
        }
        return tmf
    }

    private fun getSSLSocketFactory(
        tmf: TrustManagerFactory
    ): SSLSocketFactory? {
        val sslContext: SSLContext = SSLContext.getInstance("TLS")
        sslContext.init(null, tmf.trustManagers, null)
        return sslContext.socketFactory
    }


Solution

  • Let's see this article: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

    Basically, CSP (Content Security Policy) is an additional layer of security that aims to protect against data injection and XSS (cross-site-scripting)

    In order to enable CSP, your web server needs to return a Content-Security-Policy header (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)

    Its syntax is of

    Content-Security-Policy: <policy-directive>; <policy-directive>
    

    where policy-directive (items separated by semicolon) is always of the form of

    <directive> <value>
    

    Alternatively, instead of a response header, you can also use a meta tag to the same effect. Example:

    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; img-src https://*; child-src 'none';" />
    

    So, when you get an error complaining about CSP being violated, these are the items you need to check:

    • the source of the content (denoted as XXX in your question)
    • the response headers of the request (usually the first request in the Network tab of your browser's dev tools)
    • any meta tags

    Now that you have everything you need in order to solve this problem, you will need to check what the policy is, what attempt of action was prevented by it and issue changes on your CSP that will make sure that CSP will allow that action in the future if you want to allow it.

    Otherwise, if it's something you did not want in the first place, then find out why the behavior mentioned occurs and perform the necessary steps.