CodeGym /Java Blog /यादृच्छिक /जावा मध्ये सुरक्षा: सर्वोत्तम पद्धती
John Squirrels
पातळी 41
San Francisco

जावा मध्ये सुरक्षा: सर्वोत्तम पद्धती

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
सर्व्हर ऍप्लिकेशन्समधील सर्वात महत्वाचे मेट्रिक्स म्हणजे सुरक्षा. ही एक प्रकारची नॉन-फंक्शनल आवश्यकता आहे . जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 1सुरक्षिततेमध्ये अनेक घटक समाविष्ट आहेत. अर्थात, सर्व ज्ञात सुरक्षा तत्त्वे आणि सुरक्षा उपायांचा पूर्णपणे समावेश करण्यासाठी एकापेक्षा जास्त लेख लागतील, म्हणून आम्ही सर्वात महत्त्वाच्या गोष्टींवर लक्ष देऊ. या विषयात पारंगत असलेली व्यक्ती सर्व संबंधित प्रक्रिया सेट करू शकते, नवीन सुरक्षा छिद्रे निर्माण करणे टाळू शकते आणि कोणत्याही संघासाठी आवश्यक असेल. अर्थात, तुम्ही या पद्धतींचे पालन केल्यास तुमचा अर्ज 100% सुरक्षित असेल असा विचार करू नये. नाही! पण त्यांच्यासोबत हे नक्कीच अधिक सुरक्षित असेल. चल जाऊया.

1. Java भाषेच्या स्तरावर सुरक्षा प्रदान करा

सर्वप्रथम, Java मधील सुरक्षितता भाषेच्या क्षमतांच्या पातळीवर सुरू होते. प्रवेश सुधारक नसल्यास आम्ही काय करू? अराजकतेशिवाय काहीही होणार नाही. प्रोग्रामिंग भाषा आम्हाला सुरक्षित कोड लिहिण्यास मदत करते आणि अनेक अस्पष्ट सुरक्षा वैशिष्ट्यांचा देखील वापर करते:
  1. जोरदार टायपिंग. जावा ही स्टॅटिकली टाइप केलेली भाषा आहे. हे रनटाइमच्या वेळी टाइप-संबंधित त्रुटी पकडणे शक्य करते.
  2. ऍक्सेस मॉडिफायर्स. हे आम्हाला आवश्यकतेनुसार वर्ग, पद्धती आणि फील्डमध्ये प्रवेश सानुकूलित करण्यास अनुमती देतात.
  3. स्वयंचलित मेमरी व्यवस्थापन. यासाठी, जावा डेव्हलपर्सकडे कचरा गोळा करणारा आहे जो आम्हाला सर्वकाही मॅन्युअली कॉन्फिगर करण्यापासून मुक्त करतो. होय, कधीकधी समस्या उद्भवतात.
  4. बाइटकोड पडताळणी : जावा बायकोडमध्ये संकलित केले जाते, जे कार्यान्वित होण्यापूर्वी रनटाइमद्वारे तपासले जाते.
याव्यतिरिक्त, Oracle च्या सुरक्षा शिफारसी आहेत . अर्थात, ते भारदस्त भाषेत लिहिलेले नाही आणि ते वाचताना तुम्हाला अनेक वेळा झोप येऊ शकते, परंतु ते फायदेशीर आहे. विशेषतः, Java SE साठी सुरक्षित कोडिंग मार्गदर्शक तत्त्वे नावाचा दस्तऐवज महत्त्वाचा आहे. हे सुरक्षित कोड कसे लिहावे याबद्दल सल्ला देते. हा दस्तऐवज मोठ्या प्रमाणात अत्यंत उपयुक्त माहिती देतो. संधी असेल तर नक्की वाचा. या सामग्रीमध्ये तुमची आवड निर्माण करण्यासाठी, येथे काही मनोरंजक टिपा आहेत:
  1. सुरक्षा-संवेदनशील वर्गांना क्रमवारी लावणे टाळा. सीरिअलायझेशन सीरियलाइज्ड फाइलमधील क्लास इंटरफेस उघड करते, सीरियलाइज्ड डेटाचा उल्लेख न करता.
  2. डेटासाठी परिवर्तनीय वर्ग टाळण्याचा प्रयत्न करा. हे अपरिवर्तनीय वर्गांचे सर्व फायदे प्रदान करते (उदा. थ्रेड सुरक्षा). तुमच्याकडे बदल करण्यायोग्य वस्तू असल्यास, यामुळे अनपेक्षित वर्तन होऊ शकते.
  3. परत केलेल्या उत्परिवर्तनीय वस्तूंच्या प्रती बनवा. जर एखादी पद्धत अंतर्गत बदलण्यायोग्य ऑब्जेक्टचा संदर्भ देते, तर क्लायंट कोड ऑब्जेक्टची अंतर्गत स्थिती बदलू शकतो.
  4. आणि असेच…
मूलभूतपणे, Java SE साठी सुरक्षित कोडींग मार्गदर्शक तत्त्वे हा Java कोड योग्य आणि सुरक्षितपणे कसा लिहायचा यावरील टिप्स आणि युक्त्यांचा संग्रह आहे.

2. SQL इंजेक्शन भेद्यता दूर करा

ही एक विशेष प्रकारची अगतिकता आहे. हे विशेष आहे कारण ते सर्वात प्रसिद्ध आणि सर्वात सामान्य असुरक्षांपैकी एक आहे. जर तुम्हाला कॉम्प्युटर सिक्युरिटीमध्ये कधीच स्वारस्य नसेल, तर तुम्हाला त्याबद्दल माहिती नसेल. SQL इंजेक्शन म्हणजे काय? हा एक डेटाबेस हल्ला आहे ज्यामध्ये अपेक्षित नसलेल्या ठिकाणी अतिरिक्त SQL कोड इंजेक्ट करणे समाविष्ट आहे. समजा आमच्याकडे एक पद्धत आहे जी डेटाबेसची क्वेरी करण्यासाठी काही प्रकारचे पॅरामीटर स्वीकारते. उदाहरणार्थ, वापरकर्तानाव. असुरक्षित कोड यासारखे काहीतरी दिसेल:

// This method retrieves from the database all users with a certain name
public List findByFirstName(String firstName) throws SQLException {
   // Connect to the database
   Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);
  
   // Compose a SQL database query with our firstName
   String query = "SELECT * FROM USERS WHERE firstName = " + firstName;
  
   // Execute the query
   Statement statement = connection.createStatement();
   ResultSet result = statement.executeQuery(query);

   // Use mapToUsers to convert the ResultSet into a collection of users.
   return mapToUsers(result);
}

private List mapToUsers(ResultSet resultSet) {
   // Converts to a collection of users
}
या उदाहरणात, SQL क्वेरी वेगळ्या ओळीवर आगाऊ तयार केली जाते. मग काय अडचण आहे, बरोबर? कदाचित समस्या अशी आहे की String.format वापरणे चांगले होईल ? नाही? बरं, मग काय? चला स्वतःला परीक्षकाच्या शूजमध्ये ठेवू आणि firstName चे मूल्य म्हणून काय पास केले जाऊ शकते याचा विचार करूया . उदाहरणार्थ:
  1. आम्ही जे अपेक्षित आहे ते पास करू शकतो — एक वापरकर्तानाव. मग डेटाबेस सर्व वापरकर्त्यांना त्या नावाने परत करेल.
  2. आपण रिक्त स्ट्रिंग पास करू शकतो. त्यानंतर सर्व वापरकर्त्यांना परत केले जाईल.
  3. परंतु आम्ही खालील देखील पास करू शकतो: "'; ड्रॉप टेबल वापरकर्ते;". आणि इथे आम्हाला आता huuuuuuge समस्या आहेत. ही क्वेरी डेटाबेसमधून टेबल हटवेल. सर्व डेटा सोबत. सर्व.
यामुळे होणाऱ्या समस्यांची तुम्ही कल्पना करू शकता का? त्यापलीकडे तुम्हाला हवे ते लिहिता येते. तुम्ही सर्व वापरकर्त्यांची नावे बदलू शकता. तुम्ही त्यांचे पत्ते हटवू शकता. तोडफोडीला वाव अफाट आहे. हे टाळण्यासाठी, तुम्हाला रेडीमेड क्वेरीचे इंजेक्शन प्रतिबंधित करणे आवश्यक आहे आणि त्याऐवजी पॅरामीटर्स वापरून क्वेरी तयार करणे आवश्यक आहे. डेटाबेस क्वेरी तयार करण्याचा हा एकमेव मार्ग असावा. अशा प्रकारे तुम्ही ही असुरक्षा दूर करू शकता. उदाहरणार्थ:

// This method retrieves from the database all users with a certain name
public List findByFirstName(String firstName) throws SQLException {
   // Connect to the database
   Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);

   // Create a parameterized query.
   String query = "SELECT * FROM USERS WHERE firstName = ?";

   // Create a prepared statement with the parameterized query
   PreparedStatement statement = connection.prepareStatement(query);
  
   // Pass the parameter's value
   statement.setString(1, firstName);

   // Execute the query
   ResultSet result = statement.executeQuery(query);

   // Use mapToUsers to convert the ResultSet into a collection of users.
   return mapToUsers(result);
}

private List mapToUsers(ResultSet resultSet) {
   // Converts to a collection of users
}
अशा प्रकारे असुरक्षितता टाळली जाते. ज्यांना या लेखात खोलवर जायचे आहे त्यांच्यासाठी येथे एक उत्तम उदाहरण आहे . ही अगतिकता समजल्यावर तुम्हाला कसे कळेल? जर तुम्हाला खालील कॉमिकमध्ये विनोद मिळाला असेल, तर तुम्हाला कदाचित ही असुरक्षितता काय आहे हे स्पष्टपणे समजले असेल :Dजावा मधील सुरक्षा: सर्वोत्तम पद्धती - 2

3. अवलंबित्व स्कॅन करा आणि त्यांना अपडेट ठेवा

याचा अर्थ काय? जर तुम्हाला अवलंबित्व काय आहे हे माहित नसेल, तर मी समजावून सांगेन. अवलंबित्व हे कोड असलेले JAR संग्रहण आहे जे स्वयंचलित बिल्ड सिस्टीम (Maven, Gradle, Ant) वापरून एखाद्या प्रकल्पाशी जोडलेले असते जेणेकरुन दुसऱ्याच्या सोल्यूशनचा पुनर्वापर करता येईल. उदाहरणार्थ, Project Lombok , जे रनटाइममध्ये आमच्यासाठी गेटर्स, सेटर इ. व्युत्पन्न करते. मोठ्या ऍप्लिकेशन्समध्ये बरेच आणि बरेच अवलंबून असू शकतात. काही संक्रामक असतात (म्हणजे, प्रत्येक अवलंबित्वाची स्वतःची अवलंबित्व असू शकते, आणि असेच). परिणामी, आक्रमणकर्ते मुक्त-स्रोत अवलंबनांकडे अधिकाधिक लक्ष देत आहेत, कारण ते नियमितपणे वापरले जातात आणि त्यांच्यामुळे अनेक क्लायंटना समस्या येऊ शकतात. हे सुनिश्चित करणे महत्वाचे आहे की संपूर्ण अवलंबित्वाच्या झाडामध्ये कोणत्याही ज्ञात असुरक्षा नाहीत (होय, ते झाडासारखे दिसते). हे करण्याचे अनेक मार्ग आहेत.

अवलंबित्व निरीक्षणासाठी Snyk वापरा

Snyk सर्व प्रकल्प अवलंबित्व आणि ज्ञात भेद्यता तपासते. तुम्ही Snyk वर नोंदणी करू शकता आणि GitHub द्वारे तुमचे प्रोजेक्ट इंपोर्ट करू शकता. जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 3तसेच, तुम्ही वरील चित्रावरून पाहू शकता की, नवीन आवृत्तीमध्ये असुरक्षा निश्चित केली असल्यास, Snyk निराकरण ऑफर करेल आणि पुल विनंती तयार करेल. तुम्ही ते मुक्त-स्रोत प्रकल्पांसाठी विनामूल्य वापरू शकता. प्रकल्प नियमित अंतराने स्कॅन केले जातात, उदा. आठवड्यातून एकदा, महिन्यातून एकदा. मी Snyk स्कॅनमध्ये माझे सर्व सार्वजनिक भांडार नोंदणीकृत केले आणि जोडले (यामध्ये काहीही धोकादायक नाही, कारण ते आधीपासूनच प्रत्येकासाठी सार्वजनिक आहेत). Snyk नंतर स्कॅन परिणाम दर्शविला: जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 4आणि काही काळानंतर, Snyk-bot ने अशा प्रकल्पांमध्ये अनेक पुल विनंत्या तयार केल्या ज्यामध्ये अवलंबित्व अद्यतनित करणे आवश्यक आहे: जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 5आणि देखील:जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 6असुरक्षा शोधण्यासाठी आणि नवीन आवृत्त्यांसाठी अद्यतनांचे निरीक्षण करण्यासाठी हे एक उत्तम साधन आहे.

GitHub सुरक्षा लॅब वापरा

GitHub वर काम करणारे कोणीही त्याच्या अंगभूत साधनांचा लाभ घेऊ शकतात. GitHub सिक्युरिटी लॅबची घोषणा या शीर्षकाच्या त्यांच्या ब्लॉग पोस्टमध्ये तुम्ही या दृष्टिकोनाबद्दल अधिक वाचू शकता . हे साधन, अर्थातच, Snyk पेक्षा सोपे आहे, परंतु आपण निश्चितपणे त्याकडे दुर्लक्ष करू नये. इतकेच काय, ज्ञात भेद्यतेची संख्या केवळ वाढेल, त्यामुळे Snyk आणि GitHub सुरक्षा लॅब या दोन्हींचा विस्तार आणि सुधारणा होत राहतील.

Sonatype DepShield सक्षम करा

तुम्ही तुमच्‍या रेपॉजिटरीज संचयित करण्‍यासाठी GitHub वापरत असल्‍यास, तुम्‍ही तुमच्‍या प्रोजेक्‍टमध्‍ये मार्केटप्‍लेसमधील अॅप्लिकेशन्सपैकी एक सोनाटाइप डेपशिल्‍ड जोडू शकता. हे अवलंबित्वांसाठी प्रकल्प स्कॅन करण्यासाठी देखील वापरले जाऊ शकते. शिवाय, जर त्याला काही सापडले तर, खाली दर्शविल्याप्रमाणे योग्य वर्णनासह एक GitHub समस्या व्युत्पन्न केली जाईल:जावा मधील सुरक्षा: सर्वोत्तम पद्धती - 7

4. गोपनीय डेटा काळजीपूर्वक हाताळा

आम्ही पर्यायाने "संवेदनशील डेटा" वाक्यांश वापरू शकतो. ग्राहकाची वैयक्तिक माहिती, क्रेडिट कार्ड क्रमांक आणि इतर संवेदनशील माहिती लीक केल्याने कधीही भरून न येणारे नुकसान होऊ शकते. सर्व प्रथम, आपल्या अनुप्रयोगाच्या डिझाइनकडे बारकाईने लक्ष द्या आणि आपल्याला खरोखर या किंवा त्या डेटाची आवश्यकता आहे का ते निर्धारित करा. कदाचित तुमच्याकडे असलेल्या काही डेटाची तुम्हाला खरोखर गरज नसेल — जो डेटा भविष्यासाठी जोडला गेला आहे जो आला नाही आणि येण्याची शक्यता नाही. याव्यतिरिक्त, आपण बरेचजण अनवधानाने लॉगिंगद्वारे असा डेटा लीक करतात. संवेदनशील डेटाला तुमच्या लॉगमध्ये प्रवेश करण्यापासून रोखण्याचा एक सोपा मार्ग म्हणजे डोमेन घटकांच्या toString() पद्धती (जसे की वापरकर्ता, विद्यार्थी, शिक्षक इ.) स्क्रब करणे . हे तुम्हाला चुकून गोपनीय फील्ड आउटपुट करण्यापासून प्रतिबंधित करेल. तुम्ही toString() जनरेट करण्यासाठी Lombok वापरत असल्यासपद्धत, toString() पद्धतीच्या आउटपुटमध्ये फील्ड वापरण्यापासून रोखण्यासाठी तुम्ही @ToString.Exclude भाष्य वापरू शकता . तसेच, बाहेरील जगाला डेटा पाठवताना खूप काळजी घ्या. समजा आपल्याकडे HTTP एंडपॉइंट आहे जो सर्व वापरकर्त्यांची नावे दर्शवतो. वापरकर्त्याचा युनिक इंटर्नल आयडी दाखवण्याची गरज नाही. का? कारण आक्रमणकर्ता वापरकर्त्याबद्दल इतर, अधिक संवेदनशील माहिती मिळविण्यासाठी याचा वापर करू शकतो. उदाहरणार्थ, तुम्ही JSON वर/वरून POJO सीरियलाइज/डिसिरियलाइज करण्यासाठी जॅक्सन वापरत असल्यास , तुम्ही @JsonIgnore आणि @JsonIgnoreProperties वापरू शकता.विशिष्‍ट फील्‍डचे सीरिअलायझेशन/डिसिरियलायझेशन रोखण्‍यासाठी भाष्ये. सर्वसाधारणपणे, तुम्हाला वेगवेगळ्या ठिकाणी वेगवेगळे POJO वर्ग वापरावे लागतील. याचा अर्थ काय?
  1. डेटाबेससह काम करताना, एक प्रकारचा POJO (एक घटक) वापरा.
  2. बिझनेस लॉजिकसह काम करताना, एखाद्या घटकाला मॉडेलमध्ये रूपांतरित करा.
  3. बाहेरील जगासोबत काम करताना आणि HTTP विनंत्या पाठवताना, भिन्न संस्था (DTOs) वापरा.
अशा प्रकारे आपण स्पष्टपणे परिभाषित करू शकता की कोणती फील्ड बाहेरून दृश्यमान असतील आणि कोणती दिसणार नाहीत.

मजबूत एन्क्रिप्शन आणि हॅशिंग अल्गोरिदम वापरा

ग्राहकांचा गोपनीय डेटा सुरक्षितपणे संग्रहित करणे आवश्यक आहे. हे करण्यासाठी, आम्हाला एनक्रिप्शन वापरण्याची आवश्यकता आहे. कार्यावर अवलंबून, तुम्हाला कोणत्या प्रकारचे एन्क्रिप्शन वापरायचे ते ठरवावे लागेल. याव्यतिरिक्त, सशक्त एन्क्रिप्शनला अधिक वेळ लागतो, म्हणून तुम्हाला त्याची गरज किती योग्य आहे याचा विचार करणे आवश्यक आहे. अर्थात, तुम्ही स्वतः एक एन्क्रिप्शन अल्गोरिदम लिहू शकता. पण हे अनावश्यक आहे. आपण या क्षेत्रात विद्यमान उपाय वापरू शकता. उदाहरणार्थ, Google Tink :

<!-- https://mvnrepository.com/artifact/com.google.crypto.tink/tink -->
<dependency>
   <groupid>com.google.crypto.tink</groupid>
   <artifactid>tink</artifactid>
   <version>1.3.0</version>
</dependency>
एन्क्रिप्शन आणि डिक्रिप्शनचा समावेश असलेले हे उदाहरण वापरून काय करायचे ते पाहू:

private static void encryptDecryptExample() {
   AeadConfig.register();
   KeysetHandle handle = KeysetHandle.generateNew(AeadKeyTemplates.AES128_CTR_HMAC_SHA256);

   String plaintext = "Elvis lives!";
   String aad = "Buddy Holly";

   Aead aead = handle.getPrimitive(Aead.class);
   byte[] encrypted = aead.encrypt(plaintext.getBytes(), aad.getBytes());
   String encryptedString = Base64.getEncoder().encodeToString(encrypted);
   System.out.println(encryptedString);

   byte[] decrypted = aead.decrypt(Base64.getDecoder().decode(encrypted), aad.getBytes());
   System.out.println(new String(decrypted));
}

पासवर्ड एन्क्रिप्ट करत आहे

या कार्यासाठी, असममित एन्क्रिप्शन वापरणे सर्वात सुरक्षित आहे. का? कारण अनुप्रयोगाला पासवर्ड डिक्रिप्ट करण्याची खरोखर गरज नाही. हा मानक दृष्टिकोन आहे. प्रत्यक्षात, जेव्हा वापरकर्ता पासवर्ड एंटर करतो, तेव्हा सिस्टम ते एन्क्रिप्ट करते आणि पासवर्ड स्टोअरमध्ये अस्तित्वात असलेल्या गोष्टींशी त्याची तुलना करते. समान एन्क्रिप्शन प्रक्रिया केली जाते, म्हणून आम्ही अपेक्षा करू शकतो की ते जुळतील, जर योग्य पासवर्ड प्रविष्ट केला असेल, अर्थातच :) येथे BCrypt आणि SCrypt योग्य आहेत. संगणकीयदृष्ट्या जटिल अल्गोरिदमसह दोन्ही एक-मार्गी कार्ये (क्रिप्टोग्राफिक हॅश) आहेत ज्यांना बराच वेळ लागतो. आपल्याला नेमके हेच हवे आहे, कारण थेट गणनेस कायमचा (चांगले, बराच वेळ) लागेल. स्प्रिंग सिक्युरिटी अल्गोरिदमच्या संपूर्ण श्रेणीचे समर्थन करते. आम्ही SCryptPasswordEncoder आणि BCryptPasswordEncoder वापरू शकतो. सध्या मजबूत एन्क्रिप्शन अल्गोरिदम मानली जाणारी गोष्ट पुढील वर्षी कमकुवत मानली जाऊ शकते. परिणामी, आम्ही असा निष्कर्ष काढतो की आम्ही वापरत असलेले अल्गोरिदम आम्ही नियमितपणे तपासले पाहिजे आणि आवश्यकतेनुसार, एन्क्रिप्शन अल्गोरिदम असलेल्या लायब्ररी अपडेट करा.

निष्कर्षाऐवजी

आज आपण सुरक्षेबद्दल बोललो आणि साहजिकच अनेक गोष्टी पडद्याआड राहिल्या. मी नुकतेच तुमच्यासाठी नवीन जगाचे दार उघडले आहे, असे जग ज्याचे स्वतःचे जीवन आहे. सुरक्षितता ही राजकारणासारखीच असते: जर तुम्ही स्वतःला राजकारणात व्यस्त न ठेवता, तर राजकारण तुमच्यातच व्यस्त होईल. मी पारंपारिकपणे सुचवितो की तुम्ही मला GitHub खात्यावर फॉलो करा . तेथे मी माझ्या विविध तंत्रज्ञानाचा समावेश असलेली माझी निर्मिती पोस्ट करतो ज्याचा मी अभ्यास करत आहे आणि कामावर अर्ज करतो.

उपयुक्त दुवे

  1. गुरु९९: एसक्यूएल इंजेक्शन ट्यूटोरियल
  2. ओरॅकल: जावा सुरक्षा संसाधन केंद्र
  3. ओरॅकल: Java SE साठी सुरक्षित कोडिंग मार्गदर्शक तत्त्वे
  4. बेल्डुंग: जावा सुरक्षेची मूलतत्त्वे
  5. मध्यम: तुमची Java सुरक्षा पॉवर-अप करण्यासाठी 10 टिपा
  6. Snyk: 10 Java सुरक्षा सर्वोत्तम पद्धती
  7. GitHub: GitHub सिक्युरिटी लॅबची घोषणा करणे: जगाचा कोड एकत्रितपणे सुरक्षित करणे
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION