android - वेबवार्ता onReceivedSslError के कार्यान्वयन पर Google Play से सुरक्षा चेतावनी से बचें




google-play android-webview (5)

मेरे पास एक लिंक है जो वेबव्यू में खुलेगा। समस्या यह है कि जब तक मैं इस तरह से onReceivedSslError को ओवरराइड नहीं करता, तब तक इसे खोला नहीं जा सकता है:

 @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }

मुझे Google play से सुरक्षा चेतावनी मिल रही है:

सुरक्षा चेतावनी आपके आवेदन में WebViewClient.onReceivedSslError हैंडलर का असुरक्षित कार्यान्वयन है। विशेष रूप से, कार्यान्वयन सभी SSL प्रमाणपत्र सत्यापन त्रुटियों को अनदेखा करता है, जिससे आपका ऐप मानव-मध्य हमलों के लिए असुरक्षित हो जाता है। एक हमलावर प्रभावित WebView की सामग्री को बदल सकता है, प्रेषित डेटा (जैसे लॉगिन क्रेडेंशियल) पढ़ सकता है, और जावास्क्रिप्ट के साथ ऐप के अंदर कोड निष्पादित कर सकता है।

SSL प्रमाणपत्र सत्यापन को ठीक से संभालने के लिए, SslErrorHandler.proceed () को लागू करने के लिए अपना कोड बदलें जब भी सर्वर द्वारा प्रस्तुत प्रमाण पत्र आपकी अपेक्षाओं को पूरा करता है, और SslErrorHandler.cancel () को आमंत्रित करें। प्रभावित डेवलपर (ईमेल) और वर्ग (तों) वाले ईमेल अलर्ट को आपके डेवलपर खाते के पते पर भेज दिया गया है।

जितनी जल्दी हो सके इस भेद्यता को संबोधित करें और उन्नत एपीके के संस्करण की संख्या बढ़ाएँ। SSL त्रुटि हैंडलर के बारे में अधिक जानकारी के लिए, कृपया डेवलपर सहायता केंद्र में हमारे दस्तावेज़ देखें। अन्य तकनीकी प्रश्नों के लिए, आप https://www.stackoverflow.com/questions पोस्ट कर सकते हैं और "एंड्रॉइड-सिक्योरिटी" और "SslErrorHandler" टैग का उपयोग कर सकते हैं। यदि आप इसके लिए जिम्मेदार 3 पार्टी लाइब्रेरी का उपयोग कर रहे हैं, तो कृपया सूचित करें। 3 पार्टी और मुद्दे को संबोधित करने के लिए उनके साथ काम करें।

यह पुष्टि करने के लिए कि आपने सही तरीके से अपग्रेड किया है, अपडेट किए गए संस्करण को डेवलपर कंसोल पर अपलोड करें और पांच घंटे बाद वापस जांचें। यदि ऐप सही ढंग से अपग्रेड नहीं किया गया है, तो हम एक चेतावनी प्रदर्शित करेंगे।

कृपया ध्यान दें, जबकि ये विशिष्ट मुद्दे WebView SSL का उपयोग करने वाले प्रत्येक ऐप को प्रभावित नहीं कर सकते हैं, यह सभी सुरक्षा पैच पर अद्यतित रहने के लिए सबसे अच्छा है। कमजोरियों वाले ऐप्स जो उपयोगकर्ताओं को समझौता करने के जोखिम के लिए उजागर करते हैं, उन्हें कंटेंट पॉलिसी के उल्लंघन और डेवलपर वितरण समझौते के खंड 4.4 में खतरनाक उत्पाद माना जा सकता है।

कृपया सुनिश्चित करें कि प्रकाशित सभी एप्लिकेशन डेवलपर वितरण अनुबंध और सामग्री नीति के अनुरूप हैं। यदि आपके कोई प्रश्न या चिंताएँ हैं, तो कृपया Google Play डेवलपर सहायता केंद्र के माध्यम से हमारी सहायता टीम से संपर्क करें।

अगर मैं onReceivedSslError (handler.proceed()) को onReceivedSslError (handler.proceed()) हूं, तो पेज नहीं खुलेगा।

क्या वैसे भी मैं वेबव्यू में पेज खोल सकता हूं और सुरक्षा अलर्ट से बच सकता हूं।


SSL प्रमाणपत्र सत्यापन को ठीक से संभालने के लिए, SslErrorHandler.proceed () को लागू करने के लिए अपना कोड बदलें जब भी सर्वर द्वारा प्रस्तुत प्रमाण पत्र आपकी अपेक्षाओं को पूरा करता है, और SslErrorHandler.cancel () को आमंत्रित करें।

जैसा कि ईमेल में कहा गया है, onReceivedSslError को यह हैंडल करना चाहिए कि उपयोगकर्ता अमान्य onReceivedSslError पेज पर जा रहा है, जैसे कि onReceivedSslError डायलॉग। आपको इसे सीधे आगे नहीं बढ़ाना चाहिए।

उदाहरण के लिए, मैं उपयोगकर्ता को पुष्टि करने के लिए एक चेतावनी संवाद जोड़ता हूं और लगता है कि Google अब चेतावनी नहीं दिखाता है।

@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(R.string.notification_error_ssl_cert_invalid);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}

ईमेल के बारे में अधिक बताएं।

विशेष रूप से, कार्यान्वयन सभी SSL प्रमाणपत्र सत्यापन त्रुटियों को अनदेखा करता है, जिससे आपका ऐप मानव-मध्य हमलों के लिए असुरक्षित हो जाता है।

ईमेल कहता है कि डिफ़ॉल्ट कार्यान्वयन ने एक महत्वपूर्ण एसएसएल सुरक्षा समस्या को नजरअंदाज कर दिया है। इसलिए हमें इसे अपने स्वयं के ऐप में संभालना होगा जो WebView का उपयोग करता है। उपयोगकर्ता को अलर्ट संवाद के साथ सूचित करना एक सरल तरीका है।


अब तक प्रस्तावित समाधान केवल सुरक्षा जांच को दरकिनार करते हैं, इसलिए वे सुरक्षित नहीं हैं।

मेरा सुझाव है कि ऐप में प्रमाणपत्र (ओं) को एम्बेड करें, और जब SslError होता है, तो जांच लें कि सर्वर प्रमाणपत्र एम्बेडेड प्रमाणपत्रों में से एक से मेल खाता है।

तो यहाँ कदम हैं:

  1. वेबसाइट से प्रमाण पत्र प्राप्त करें।

    • सफारी पर साइट खोलें
    • वेबसाइट के नाम के पास पैडलॉक आइकन पर क्लिक करें
    • शो सर्टिफिकेट पर क्लिक करें
    • प्रमाणपत्र को किसी फ़ोल्डर में खींचें और छोड़ें

देखें https://www.markbrilman.nl/2012/03/howto-save-a-certificate-via-safari-on-mac/

  1. प्रमाण पत्र (.cer फ़ाइल) को अपने ऐप के Res / कच्चे फ़ोल्डर में कॉपी करें

  2. अपने कोड में, लोडएसएसएलसी सर्टिफिकेट () कहकर प्रमाण पत्र लोड करें

    private static final int[] CERTIFICATES = {
            R.raw.my_certificate,   // you can put several certificates
    };
    private ArrayList<SslCertificate> certificates = new ArrayList<>();
    
    private void loadSSLCertificates() {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            for (int rawId : CERTIFICATES) {
                InputStream inputStream = getResources().openRawResource(rawId);
                InputStream certificateInput = new BufferedInputStream(inputStream);
                try {
                    Certificate certificate = certificateFactory.generateCertificate(certificateInput);
                    if (certificate instanceof X509Certificate) {
                        X509Certificate x509Certificate = (X509Certificate) certificate;
                        SslCertificate sslCertificate = new SslCertificate(x509Certificate);
                        certificates.add(sslCertificate);
                    } else {
                        Log.w(TAG, "Wrong Certificate format: " + rawId);
                    }
                } catch (CertificateException exception) {
                    Log.w(TAG, "Cannot read certificate: " + rawId);
                } finally {
                    try {
                        certificateInput.close();
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (CertificateException e) {
            e.printStackTrace();
        }
    }
  3. जब कोई SslError होती है, तो जाँचें कि सर्वर प्रमाणपत्र एक एम्बेडेड प्रमाणपत्र से मेल खाता है। ध्यान दें कि सीधे प्रमाण पत्र की तुलना करना संभव नहीं है, इसलिए मैं प्रमाण पत्र डेटा को एक बंडल में डालने के लिए SslCertificate.saveState का उपयोग करता हूं, और फिर मैं सभी बंडल प्रविष्टियों की तुलना करता हूं।

    webView.setWebViewClient(new WebViewClient() {
    
        @Override
        public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    
            // Checks Embedded certificates
            SslCertificate serverCertificate = error.getCertificate();
            Bundle serverBundle = SslCertificate.saveState(serverCertificate);
            for (SslCertificate appCertificate : certificates) {
                if (TextUtils.equals(serverCertificate.toString(), appCertificate.toString())) { // First fast check
                    Bundle appBundle = SslCertificate.saveState(appCertificate);
                    Set<String> keySet = appBundle.keySet();
                    boolean matches = true;
                    for (String key : keySet) {
                        Object serverObj = serverBundle.get(key);
                        Object appObj = appBundle.get(key);
                        if (serverObj instanceof byte[] && appObj instanceof byte[]) {     // key "x509-certificate"
                            if (!Arrays.equals((byte[]) serverObj, (byte[]) appObj)) {
                                matches = false;
                                break;
                            }
                        } else if ((serverObj != null) && !serverObj.equals(appObj)) {
                            matches = false;
                            break;
                        }
                    }
                    if (matches) {
                        handler.proceed();
                        return;
                    }
                }
            }
    
            handler.cancel();
            String message = "SSL Error " + error.getPrimaryError();
            Log.w(TAG, message);
        }
    
    
    });

उपयोगकर्ता को कोई भी संदेश दिखाने से पहले मुझे हमारे ट्रस्टस्टोर की जांच करने की आवश्यकता थी इसलिए मैंने ऐसा किया:

public class MyWebViewClient extends WebViewClient {
private static final String TAG = MyWebViewClient.class.getCanonicalName();

Resources resources;
Context context;

public MyWebViewClient(Resources resources, Context context){
    this.resources = resources;
    this.context = context;
}

@Override
public void onReceivedSslError(WebView v, final SslErrorHandler handler, SslError er){
    // first check certificate with our truststore
    // if not trusted, show dialog to user
    // if trusted, proceed
    try {
        TrustManagerFactory tmf = TrustManagerUtil.getTrustManagerFactory(resources);

        for(TrustManager t: tmf.getTrustManagers()){
            if (t instanceof X509TrustManager) {

                X509TrustManager trustManager = (X509TrustManager) t;

                Bundle bundle = SslCertificate.saveState(er.getCertificate());
                X509Certificate x509Certificate;
                byte[] bytes = bundle.getByteArray("x509-certificate");
                if (bytes == null) {
                    x509Certificate = null;
                } else {
                    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                    Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
                    x509Certificate = (X509Certificate) cert;
                }
                X509Certificate[] x509Certificates = new X509Certificate[1];
                x509Certificates[0] = x509Certificate;

                trustManager.checkServerTrusted(x509Certificates, "ECDH_RSA");
            }
        }
        Log.d(TAG, "Certificate from " + er.getUrl() + " is trusted.");
        handler.proceed();
    }catch(Exception e){
        Log.d(TAG, "Failed to access " + er.getUrl() + ". Error: " + er.getPrimaryError());
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        String message = "SSL Certificate error.";
        switch (er.getPrimaryError()) {
            case SslError.SSL_UNTRUSTED:
                message = "O certificado não é confiável.";
                break;
            case SslError.SSL_EXPIRED:
                message = "O certificado expirou.";
                break;
            case SslError.SSL_IDMISMATCH:
                message = "Hostname inválido para o certificado.";
                break;
            case SslError.SSL_NOTYETVALID:
                message = "O certificado é inválido.";
                break;
        }
        message += " Deseja continuar mesmo assim?";

        builder.setTitle("Erro");
        builder.setMessage(message);
        builder.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                handler.proceed();
            }
        });
        builder.setNegativeButton("Não", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                handler.cancel();
            }
        });
        final AlertDialog dialog = builder.create();
        dialog.show();
    }
}
}

ठीक करें जो मेरे लिए काम करता है वह सिर्फ अक्षम है onReceivedSslError फ़ंक्शन को AuthorizationWebViewClient में परिभाषित किया गया है। इस स्थिति में SSL त्रुटि के मामले में handler.cancel को बुलाया जाएगा। हालाँकि यह One Drive SSL प्रमाणपत्र के साथ अच्छा है। Android 2.3.7, Android 5.1 पर परीक्षण किया गया।


Google सुरक्षा चेतावनी के अनुसार : इंटरफ़ेस X509TrustManager का असुरक्षित कार्यान्वयन , Google Play 11 जुलाई 2016 से X509TrustManager समर्थन नहीं करेगा:

नमस्ते Google Play डेवलपर,

इस ईमेल के अंत में सूचीबद्ध आपका ऐप (इंटरफ़ेस) इंटरफ़ेस X509TrustManager के असुरक्षित कार्यान्वयन का उपयोग करता है। विशेष रूप से, दूरस्थ दूरस्थ होस्ट के लिए HTTPS कनेक्शन स्थापित करते समय कार्यान्वयन सभी SSL प्रमाणपत्र सत्यापन त्रुटियों को अनदेखा करता है, जिससे आपका ऐप मानव-मध्य हमलों के लिए असुरक्षित हो जाता है। एक हमलावर प्रेषित डेटा (जैसे लॉगिन क्रेडेंशियल) पढ़ सकता है और यहां तक ​​कि HTTPS कनेक्शन पर प्रेषित डेटा को बदल सकता है। यदि आपके खाते में 20 से अधिक प्रभावित ऐप हैं, तो कृपया पूर्ण सूची के लिए डेवलपर कंसोल की जांच करें।

एसएसएल प्रमाणपत्र सत्यापन को ठीक से संभालने के लिए, जब भी सर्वर द्वारा प्रस्तुत प्रमाणपत्र आपकी अपेक्षाओं पर खरा नहीं उतरता है तो सर्टिफिकेट या इललीगल एग्जिटसेप्शन को बढ़ाने के लिए अपने कस्टम X509TrustManager इंटरफ़ेस के CheckServerTrusted पद्धति में अपना कोड बदलें। तकनीकी प्रश्नों के लिए, आप स्टैक ओवरफ्लो में पोस्ट कर सकते हैं और "एंड्रॉइड-सिक्योरिटी" और "ट्रस्टमैनेजर" टैग का उपयोग कर सकते हैं।

कृपया इस समस्या को जल्द से जल्द हल करें और उन्नत किए गए एपीके के संस्करण संख्या को बढ़ाएं। 17 मई 2016 से, Google Play किसी भी नए ऐप या अपडेट के प्रकाशन को रोक देगा जिसमें इंटरफ़ेस X509TrAFager का असुरक्षित कार्यान्वयन होगा।

यह सुनिश्चित करने के लिए कि आपने सही परिवर्तन किए हैं, अपने ऐप के अपडेटेड वर्जन को डेवलपर कंसोल में जमा करें और पाँच घंटे बाद वापस देखें। यदि ऐप सही ढंग से अपग्रेड नहीं किया गया है, तो हम एक चेतावनी प्रदर्शित करेंगे।

हालांकि ये विशिष्ट मुद्दे ट्रस्टमैनेजर कार्यान्वयन के साथ हर ऐप को प्रभावित नहीं कर सकते हैं, लेकिन SSL प्रमाणपत्र सत्यापन त्रुटियों को अनदेखा नहीं करना सबसे अच्छा है। कमजोरियों वाले ऐप्स, जो उपयोगकर्ताओं को समझौता करने के जोखिम के लिए उजागर करते हैं, सामग्री नीति के उल्लंघन और डेवलपर वितरण समझौते के खंड 4.4 में खतरनाक उत्पाद माने जा सकते हैं।

...





sslerrorhandler