సర్వర్ అప్లికేషన్లలో అత్యంత ముఖ్యమైన మెట్రిక్లలో ఒకటి భద్రత. ఇది ఒక రకమైన పని చేయని అవసరం .
భద్రత అనేక భాగాలను కలిగి ఉంటుంది. వాస్తవానికి, తెలిసిన అన్ని భద్రతా సూత్రాలు మరియు భద్రతా చర్యలను పూర్తిగా కవర్ చేయడానికి ఒకటి కంటే ఎక్కువ కథనాలు అవసరం, కాబట్టి మేము చాలా ముఖ్యమైన వాటిపై నివసిస్తాము. ఈ అంశంలో బాగా ప్రావీణ్యం ఉన్న వ్యక్తి అన్ని సంబంధిత ప్రక్రియలను సెటప్ చేయవచ్చు, కొత్త భద్రతా రంధ్రాలను సృష్టించడాన్ని నివారించవచ్చు మరియు ఏ బృందంలోనైనా అవసరం అవుతుంది. అయితే, మీరు ఈ పద్ధతులను అనుసరిస్తే మీ అప్లికేషన్ 100% సురక్షితంగా ఉంటుందని మీరు అనుకోకూడదు. లేదు! కానీ అది ఖచ్చితంగా వారితో మరింత సురక్షితంగా ఉంటుంది. వెళ్దాం.
అలాగే, మీరు పై చిత్రం నుండి చూడగలిగినట్లుగా, కొత్త వెర్షన్లో దుర్బలత్వం పరిష్కరించబడితే, Snyk పరిష్కారాన్ని అందిస్తుంది మరియు పుల్ అభ్యర్థనను సృష్టిస్తుంది. ఓపెన్ సోర్స్ ప్రాజెక్ట్ల కోసం మీరు దీన్ని ఉచితంగా ఉపయోగించవచ్చు. ప్రాజెక్ట్లు క్రమమైన వ్యవధిలో స్కాన్ చేయబడతాయి, ఉదా. వారానికి ఒకసారి, నెలకు ఒకసారి. నేను Snyk స్కాన్కు నా పబ్లిక్ రిపోజిటరీలన్నింటినీ నమోదు చేసాను మరియు జోడించాను (దీని గురించి ప్రమాదకరమైనది ఏమీ లేదు, ఎందుకంటే అవి ఇప్పటికే అందరికీ పబ్లిక్గా ఉన్నాయి). Snyk తర్వాత స్కాన్ ఫలితాన్ని చూపించింది:
మరియు కొంతకాలం తర్వాత, Snyk-bot డిపెండెన్సీలను అప్డేట్ చేయాల్సిన ప్రాజెక్ట్లలో అనేక పుల్ అభ్యర్థనలను సిద్ధం చేసింది:
ఇంకా:
కొత్త సంస్కరణల కోసం దుర్బలత్వాలను కనుగొనడానికి మరియు నవీకరణలను పర్యవేక్షించడానికి ఇది ఒక గొప్ప సాధనం.

1. జావా భాష స్థాయిలో భద్రతను అందించండి
అన్నింటిలో మొదటిది, జావాలో భద్రత భాష యొక్క సామర్థ్యాల స్థాయిలో ప్రారంభమవుతుంది. యాక్సెస్ మాడిఫైయర్లు లేకుంటే మనం ఏమి చేస్తాము? అరాచకం తప్ప మరేమీ ఉండదు. ప్రోగ్రామింగ్ భాష సురక్షిత కోడ్ని వ్రాయడంలో మాకు సహాయపడుతుంది మరియు అనేక అవ్యక్త భద్రతా లక్షణాలను కూడా ఉపయోగించుకుంటుంది:- బలమైన టైపింగ్. జావా అనేది స్థిరంగా టైప్ చేయబడిన భాష. ఇది రన్టైమ్లో టైప్-సంబంధిత ఎర్రర్లను క్యాచ్ చేయడం సాధ్యపడుతుంది.
- యాక్సెస్ మాడిఫైయర్లు. తరగతులు, పద్ధతులు మరియు ఫీల్డ్లకు అవసరమైన యాక్సెస్ను అనుకూలీకరించడానికి ఇవి మమ్మల్ని అనుమతిస్తాయి.
- ఆటోమేటిక్ మెమరీ నిర్వహణ. దీని కోసం, జావా డెవలపర్లు చెత్త కలెక్టర్ను కలిగి ఉన్నారు, ఇది ప్రతిదాన్ని మాన్యువల్గా కాన్ఫిగర్ చేయకుండా మమ్మల్ని విముక్తి చేస్తుంది. అవును, కొన్నిసార్లు సమస్యలు తలెత్తుతాయి.
- బైట్కోడ్ ధృవీకరణ : జావా బైట్కోడ్గా కంపైల్ చేయబడింది, ఇది అమలు చేయబడే ముందు రన్టైమ్ ద్వారా తనిఖీ చేయబడుతుంది.
- సెక్యూరిటీ-సెన్సిటివ్ క్లాస్లను సీరియల్ చేయడం మానుకోండి. సీరియలైజేషన్ అనేది సీరియల్ ఫైల్లోని క్లాస్ ఇంటర్ఫేస్ను బహిర్గతం చేస్తుంది, సీరియలైజ్ చేయబడిన డేటా గురించి ప్రత్యేకంగా చెప్పనక్కర్లేదు.
- డేటా కోసం మార్చబడే తరగతులను నివారించడానికి ప్రయత్నించండి. ఇది మార్పులేని తరగతుల యొక్క అన్ని ప్రయోజనాలను అందిస్తుంది (ఉదా. థ్రెడ్ భద్రత). మీరు మార్చగల వస్తువును కలిగి ఉంటే, అది ఊహించని ప్రవర్తనకు దారి తీస్తుంది.
- తిరిగి మారే వస్తువుల కాపీలను తయారు చేయండి. ఒక పద్ధతి అంతర్గత మార్చగల ఆబ్జెక్ట్కు సూచనను తిరిగి ఇస్తే, క్లయింట్ కోడ్ వస్తువు యొక్క అంతర్గత స్థితిని మార్చగలదు.
- మరియు అందువలన న…
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ని ఉపయోగించడం మంచిది ? కాదా? బాగా, అప్పుడు ఏమిటి? మనల్ని మనం ఒక టెస్టర్ షూస్లో ఉంచుకుని, ఫస్ట్నేమ్ విలువగా దేనిని పాస్ చేయవచ్చో ఆలోచిద్దాం . ఉదాహరణకి:
- మేము ఆశించినదానిని పాస్ చేయగలము — వినియోగదారు పేరు. అప్పుడు డేటాబేస్ ఆ పేరుతో వినియోగదారులందరికీ తిరిగి ఇస్తుంది.
- మేము ఖాళీ స్ట్రింగ్ను పాస్ చేయవచ్చు. అప్పుడు వినియోగదారులందరూ తిరిగి ఇవ్వబడతారు.
- కానీ మనం ఈ క్రింది వాటిని కూడా పాస్ చేయవచ్చు: "'; డ్రాప్ టేబుల్ యూజర్లు;". మరియు ఇక్కడ మనకు ఇప్పుడు huuuuuuge సమస్యలు ఉన్నాయి. ఈ ప్రశ్న డేటాబేస్ నుండి పట్టికను తొలగిస్తుంది. మొత్తం డేటాతో పాటు. అన్ని IT.
// 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
3. డిపెండెన్సీలను స్కాన్ చేయండి మరియు వాటిని నవీకరించండి
అంటే ఏమిటి? డిపెండెన్సీ అంటే ఏమిటో మీకు తెలియకపోతే, నేను వివరిస్తాను. డిపెండెన్సీ అనేది మరొకరి పరిష్కారాన్ని మళ్లీ ఉపయోగించేందుకు ఆటోమేటిక్ బిల్డ్ సిస్టమ్లను (మావెన్, గ్రేడిల్, యాంట్) ఉపయోగించి ప్రాజెక్ట్కు కనెక్ట్ చేయబడిన కోడ్తో కూడిన JAR ఆర్కైవ్. ఉదాహరణకు, ప్రాజెక్ట్ లాంబాక్ , ఇది రన్టైమ్లో మన కోసం గెట్టర్లు, సెట్టర్లు మొదలైనవాటిని ఉత్పత్తి చేస్తుంది. పెద్ద అప్లికేషన్లు చాలా మరియు చాలా డిపెండెన్సీలను కలిగి ఉంటాయి. కొన్ని ట్రాన్సిటివ్ (అంటే, ప్రతి డిపెండెన్సీకి దాని స్వంత డిపెండెన్సీలు ఉండవచ్చు మరియు మొదలైనవి). ఫలితంగా, దాడి చేసేవారు ఎక్కువగా ఓపెన్ సోర్స్ డిపెండెన్సీలపై శ్రద్ధ చూపుతున్నారు, ఎందుకంటే అవి క్రమం తప్పకుండా ఉపయోగించబడతాయి మరియు చాలా మంది క్లయింట్లు వాటి కారణంగా సమస్యలను ఎదుర్కొంటారు. మొత్తం డిపెండెన్సీ ట్రీలో (అవును, ఇది చెట్టులా కనిపిస్తోంది) తెలిసిన దుర్బలత్వాలు లేవని నిర్ధారించుకోవడం ముఖ్యం. దీన్ని చేయడానికి అనేక మార్గాలు ఉన్నాయి.డిపెండెన్సీ పర్యవేక్షణ కోసం Snykని ఉపయోగించండి
Snyk అన్ని ప్రాజెక్ట్ డిపెండెన్సీలను తనిఖీ చేస్తుంది మరియు తెలిసిన దుర్బలత్వాలను ఫ్లాగ్ చేస్తుంది. మీరు Snykలో నమోదు చేసుకోవచ్చు మరియు GitHub ద్వారా మీ ప్రాజెక్ట్లను దిగుమతి చేసుకోవచ్చు.



GitHub సెక్యూరిటీ ల్యాబ్ని ఉపయోగించండి
GitHubలో పనిచేసే ఎవరైనా దాని అంతర్నిర్మిత సాధనాల ప్రయోజనాన్ని పొందవచ్చు. మీరు GitHub సెక్యూరిటీ ల్యాబ్ని అనౌన్సింగ్ అనే పేరుతో వారి బ్లాగ్ పోస్ట్లో ఈ విధానం గురించి మరింత చదవవచ్చు . ఈ సాధనం, వాస్తవానికి, Snyk కంటే సరళమైనది, కానీ మీరు దీన్ని ఖచ్చితంగా నిర్లక్ష్యం చేయకూడదు. ఇంకా ఏమిటంటే, తెలిసిన దుర్బలత్వాల సంఖ్య మాత్రమే పెరుగుతుంది, కాబట్టి Snyk మరియు GitHub సెక్యూరిటీ ల్యాబ్ రెండూ విస్తరించడం మరియు మెరుగుపరచడం కొనసాగుతాయి.Sonatype DepShieldని ప్రారంభించండి
మీరు మీ రిపోజిటరీలను నిల్వ చేయడానికి GitHubని ఉపయోగిస్తే, మీరు మీ ప్రాజెక్ట్లకు MarketPlaceలోని అప్లికేషన్లలో ఒకటైన Sonatype DepShieldని జోడించవచ్చు. డిపెండెన్సీల కోసం ప్రాజెక్ట్లను స్కాన్ చేయడానికి కూడా దీనిని ఉపయోగించవచ్చు. అంతేకాకుండా, అది ఏదైనా కనుగొంటే, దిగువ చూపిన విధంగా తగిన వివరణతో GitHub ఇష్యూ రూపొందించబడుతుంది:
4. రహస్య డేటాను జాగ్రత్తగా నిర్వహించండి
మేము ప్రత్యామ్నాయంగా "సెన్సిటివ్ డేటా" అనే పదబంధాన్ని ఉపయోగించవచ్చు. కస్టమర్ యొక్క వ్యక్తిగత సమాచారం, క్రెడిట్ కార్డ్ నంబర్లు మరియు ఇతర సున్నితమైన సమాచారాన్ని లీక్ చేయడం వల్ల కోలుకోలేని హాని జరుగుతుంది. అన్నింటిలో మొదటిది, మీ అప్లికేషన్ రూపకల్పనను నిశితంగా పరిశీలించండి మరియు మీకు నిజంగా ఈ లేదా ఆ డేటా అవసరమా అని నిర్ణయించండి. బహుశా మీ వద్ద ఉన్న కొంత డేటా మీకు నిజంగా అవసరం లేకపోవచ్చు — భవిష్యత్తు కోసం జోడించబడిన డేటా రాని మరియు వచ్చే అవకాశం లేదు. అదనంగా, మీరు చాలా మంది అనుకోకుండా లాగింగ్ ద్వారా అటువంటి డేటాను లీక్ చేస్తారు. మీ లాగ్లలో సున్నితమైన డేటాను నమోదు చేయకుండా నిరోధించడానికి సులభమైన మార్గం ఏమిటంటే , డొమైన్ ఎంటిటీల (వినియోగదారు, విద్యార్థి, ఉపాధ్యాయుడు, మొదలైనవి) యొక్క toString() పద్ధతులను స్క్రబ్ చేయడం . ఇది రహస్య ఫీల్డ్లను అనుకోకుండా అవుట్పుట్ చేయకుండా మిమ్మల్ని నిరోధిస్తుంది. మీరు toString()ని రూపొందించడానికి Lombokని ఉపయోగిస్తేపద్ధతి, toString() పద్ధతి యొక్క అవుట్పుట్లో ఫీల్డ్ని ఉపయోగించకుండా నిరోధించడానికి మీరు @ToString.Exclude ఉల్లేఖనాన్ని ఉపయోగించవచ్చు . అలాగే, బయటి ప్రపంచానికి డేటాను పంపేటప్పుడు చాలా జాగ్రత్తగా ఉండండి. వినియోగదారులందరి పేర్లను చూపించే HTTP ఎండ్పాయింట్ని కలిగి ఉన్నారని అనుకుందాం. వినియోగదారు యొక్క ప్రత్యేక అంతర్గత IDని చూపించాల్సిన అవసరం లేదు. ఎందుకు? ఎందుకంటే దాడి చేసే వ్యక్తి వినియోగదారు గురించి ఇతర, మరింత సున్నితమైన సమాచారాన్ని పొందేందుకు దీనిని ఉపయోగించవచ్చు. ఉదాహరణకు, మీరు JSON నుండి/నుండి POJOని సీరియల్ చేయడానికి/డీరియలైజ్ చేయడానికి జాక్సన్ని ఉపయోగిస్తే, మీరు @JsonIgnore మరియు @JsonIgnorePropertiesని ఉపయోగించవచ్చునిర్దిష్ట ఫీల్డ్ల సీరియలైజేషన్/డీరియలైజేషన్ను నిరోధించడానికి ఉల్లేఖనాలు. సాధారణంగా, మీరు వేర్వేరు ప్రదేశాలలో వేర్వేరు POJO తరగతులను ఉపయోగించాలి. అంటే ఏమిటి?- డేటాబేస్తో పని చేస్తున్నప్పుడు, ఒక రకమైన POJO (ఒక ఎంటిటీ) ఉపయోగించండి.
- వ్యాపార లాజిక్తో పని చేస్తున్నప్పుడు, ఒక ఎంటిటీని మోడల్గా మార్చండి.
- బయటి ప్రపంచంతో పని చేస్తున్నప్పుడు మరియు HTTP అభ్యర్థనలను పంపుతున్నప్పుడు, విభిన్న ఎంటిటీలను (DTOలు) ఉపయోగించండి.
బలమైన ఎన్క్రిప్షన్ మరియు హ్యాషింగ్ అల్గారిథమ్లను ఉపయోగించండి
కస్టమర్ల గోప్యమైన డేటా తప్పనిసరిగా సురక్షితంగా నిల్వ చేయబడాలి. దీన్ని చేయడానికి, మేము గుప్తీకరణను ఉపయోగించాలి. పనిని బట్టి, మీరు ఏ రకమైన గుప్తీకరణను ఉపయోగించాలో నిర్ణయించుకోవాలి. అదనంగా, బలమైన ఎన్క్రిప్షన్కు ఎక్కువ సమయం పడుతుంది, కాబట్టి దాని అవసరం దాని కోసం గడిపిన సమయాన్ని ఎంత సమర్థిస్తుందో మళ్లీ మీరు పరిగణించాలి. వాస్తవానికి, మీరు మీరే ఎన్క్రిప్షన్ అల్గారిథమ్ను వ్రాయవచ్చు. కానీ ఇది అనవసరం. మీరు ఈ ప్రాంతంలో ఇప్పటికే ఉన్న పరిష్కారాలను ఉపయోగించవచ్చు. ఉదాహరణకు, 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 ఖాతాలో అనుసరించాల్సిందిగా నేను సాంప్రదాయకంగా సూచిస్తున్నాను . అక్కడ నేను చదువుతున్న మరియు పనిలో దరఖాస్తు చేస్తున్న వివిధ సాంకేతికతలతో కూడిన నా క్రియేషన్లను పోస్ట్ చేస్తాను.ఉపయోగకరమైన లింకులు
- Guru99: SQL ఇంజెక్షన్ ట్యుటోరియల్
- ఒరాకిల్: జావా సెక్యూరిటీ రిసోర్స్ సెంటర్
- ఒరాకిల్: జావా SE కోసం సురక్షిత కోడింగ్ మార్గదర్శకాలు
- Baeldung: జావా భద్రత యొక్క ప్రాథమిక అంశాలు
- మీడియం: మీ జావా భద్రతను పవర్-అప్ చేయడానికి 10 చిట్కాలు
- Snyk: 10 జావా భద్రతా ఉత్తమ పద్ధతులు
- GitHub: GitHub సెక్యూరిటీ ల్యాబ్ని ప్రకటించడం: ప్రపంచ కోడ్ను భద్రపరచడం, కలిసి
GO TO FULL VERSION