JavaRush /Blog Jawa /Random-JV /Keamanan ing Jawa: praktik paling apik

Keamanan ing Jawa: praktik paling apik

Diterbitake ing grup
Ing aplikasi server, salah sawijining indikator sing paling penting yaiku keamanan. Iki minangka salah sawijining jinis Persyaratan Non-Fungsi . Keamanan ing Jawa: praktik paling apik - 1Keamanan nduweni akeh komponen. Mesthine, supaya bisa nutupi kabeh prinsip lan tumindak protèktif sing wis dingerteni, sampeyan kudu nulis luwih saka siji artikel, mula ayo fokus ing sing paling penting. A wong sing uga versed ing topik iki, bakal bisa kanggo nyiyapake kabeh pangolahan lan mesthekake yen padha ora nggawe bolongan keamanan anyar, bakal dibutuhake ing tim sembarang. Mesthine, sampeyan ora kudu mikir yen sampeyan ngetutake praktik kasebut, aplikasi kasebut bakal aman. Ora! Nanging mesthi bakal luwih aman karo wong-wong mau. Tindak.

1. Nyedhiyakake keamanan ing tataran basa Jawa

Kaping pisanan, keamanan ing Jawa diwiwiti ing tingkat fitur basa. Iki sing bakal ditindakake yen ora ana modifikasi akses?... Anarki, ora kurang. Basa pamrograman mbantu kita nulis kode sing aman lan uga njupuk kauntungan saka akeh fitur keamanan implisit:
  1. Ketik sing kuwat. Java minangka basa sing diketik kanthi statis sing nyedhiyakake kemampuan kanggo ndeteksi kesalahan jinis nalika mbukak.
  2. Akses modifiers. Thanks kanggo wong-wong mau, kita bisa ngatur akses menyang kelas, metode lan lapangan kelas kanthi cara sing dibutuhake.
  3. Manajemen memori otomatis. Kanggo maksud iki, kita (Javaists;)) duwe Garbage Collector, sing mbebasake sampeyan saka konfigurasi manual. Ya, kadhangkala ana masalah.
  4. Pemeriksa bytecode: Java nglumpukake menyang bytecode, sing dicenthang dening runtime sadurunge mbukak.
Antarane liyane, ana rekomendasi saka Oracle babagan keamanan. Mesthine, ora ditulis kanthi "gaya dhuwur" lan sampeyan bisa uga turu kaping pirang-pirang nalika maca, nanging worth iku. Dokumen sing penting banget yaiku Pedoman Coding Aman kanggo Java SE , sing menehi tips babagan carane nulis kode aman. Dokumen iki ngemot akeh informasi sing migunani. Yen bisa, mesthine kudu diwaca. Kanggo narik kawigaten babagan materi iki, ana sawetara tips sing menarik:
  1. Aja nggawe seri kelas sensitif-aman. Ing kasus iki, sampeyan bisa njaluk antarmuka kelas saka file serialized, ora kanggo sebutno data sing lagi serialized.
  2. Coba ngindhari kelas data sing bisa diganti. Iki menehi kabeh keuntungan saka kelas immutable (contone safety thread). Yen ana obyek sing bisa diganti, iki bisa nyebabake prilaku sing ora dikarepake.
  3. Gawe salinan obyek sing bisa diganti. Yen cara ngasilake referensi menyang obyek sing bisa diganti internal, kode klien bisa ngganti kahanan internal obyek kasebut.
  4. Lan sakteruse…
Umumé, Secure Coding Guidelines for Java SE ngemot sawetara tips lan trik babagan carane nulis kode ing Jawa kanthi bener lan aman.

2. Ngilangi kerentanan injeksi SQL

Kerentanan unik. Keunikan kasebut yaiku salah sawijining sing paling misuwur lan salah sawijining kerentanan sing paling umum. Yen sampeyan ora kasengsem ing masalah keamanan, sampeyan ora bakal ngerti. Apa injeksi SQL? Iki minangka serangan ing basis data kanthi nyuntikake kode SQL tambahan sing ora dikarepake. Ayo kita duwe metode sing njupuk sawetara parameter kanggo takon database. Contone, jeneng panganggo. Kode kanthi kerentanan bakal katon kaya iki:
// Метод достает из базы данных всех пользователей с определенным именем
public List<User> findByFirstName(String firstName) throws SQLException {
   // Создается связь с базой данных
   Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);

   // Пишем sql request в базу данных с нашим firstName
   String query = "SELECT * FROM USERS WHERE firstName = " + firstName;

   // выполняем request
   Statement statement = connection.createStatement();
   ResultSet result = statement.executeQuery(query);

   // при помощи mapToUsers переводит ResultSet в коллекцию юзеров.
   return mapToUsers(result);
}

private List<User> mapToUsers(ResultSet resultSet) {
   //переводит в коллекцию юзеров
}
Ing conto iki, query sql wis disiapake ing advance ing baris kapisah. Iku bakal katon sing apa masalah iku, tengen? Mungkin masalah iku luwih apik kanggo nggunakake String.format? ora? Apa banjur? Ayo kita sijine dhewe ing panggonan tester lan mikir bab apa sing bisa disampekake ing Nilai firstName. Tuladhane:
  1. Sampeyan bisa ngliwati apa sing dikarepake - jeneng pangguna. Banjur database bakal ngasilake kabeh pangguna kanthi jeneng kasebut.
  2. Sampeyan bisa ngliwati string kosong: banjur kabeh pangguna bakal bali.
  3. Utawa sampeyan bisa ngliwati ing ngisor iki: "''; PENGGUNA DROP TABLE;”. Lan ing kene bakal ana masalah sing luwih gedhe. Pitakonan iki bakal mbusak tabel saka database. Kanthi kabeh data. KABEH.
Apa sampeyan bisa mbayangno masalah apa sing bisa nyebabake? Banjur sampeyan bisa nulis apa wae sing dikarepake. Sampeyan bisa ngganti jeneng kabeh pangguna, sampeyan bisa mbusak alamate. Ruang lingkup sabotase iku jembar. Kanggo ngindhari iki, sampeyan kudu ngendhegake nyuntikake pitakon sing wis siap lan mung nggawe parameter kasebut. Iki kudu dadi siji-sijine cara kanggo takon database. Kanthi cara iki sampeyan bisa ngilangi kerentanan iki. Tuladha:
// Метод достает из базы данных всех пользователей с определенным именем
public List<User> findByFirstName(String firstName) throws SQLException {
   // Создается связь с базой данных
   Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);

   // Создаем параметризированный request.
   String query = "SELECT * FROM USERS WHERE firstName = ?";

   // Создаем подготовленный стейтмент с параметризованным requestом
   PreparedStatement statement = connection.prepareStatement(query);

   // Передаем meaning параметра
   statement.setString(1, firstName);

   // выполняем request
   ResultSet result = statement.executeQuery(query);

   // при помощи mapToUsers переводим ResultSet в коллекцию юзеров.
   return mapToUsers(result);
}

private List<User> mapToUsers(ResultSet resultSet) {
   //переводим в коллекцию юзеров
}
Kanthi cara iki, kerentanan iki bisa nyingkiri. Kanggo sing pengin nyilem luwih jero babagan masalah tinimbang artikel iki, iki minangka conto sing apik . Kepiye sampeyan ngerti yen sampeyan ngerti bagean iki? Yen guyonan ing ngisor iki wis jelas, mula iki minangka tandha manawa inti saka kerentanan wis jelas: D Keamanan ing Jawa: praktik paling apik - 2

3. Pindai lan tetep dependensi dianyari

Iki artine apa? Kanggo sing ora ngerti apa dependensi, Aku bakal nerangake: iku arsip jar karo kode sing disambungake menyang project nggunakake sistem mbangun otomatis (Maven, Gradle, Ant) kanggo nggunakake maneh solusi wong liya. Contone, Project Lombok , sing ngasilake getter, setter, lan liya-liyane kanggo kita nalika runtime. Lan yen kita ngomong babagan aplikasi gedhe, dheweke nggunakake macem-macem dependensi. Sawetara iku transitif (yaiku, saben dependensi bisa duwe dependensi dhewe, lan liya-liyane). Mula, panyerang saya tambah akeh perhatian marang dependensi open-source, amarga asring digunakake lan bisa nyebabake masalah kanggo akeh klien. Penting kanggo mesthekake yen ora ana kerentanan sing dikawruhi ing kabeh wit dependensi (sing persis kaya apa). Lan ana sawetara cara kanggo nindakake iki.

Gunakake Snyk kanggo ngawasi

Alat Snyk mriksa kabeh dependensi proyek lan tandha kerentanan sing dikenal. Ing kono sampeyan bisa ndhaptar lan ngimpor proyek liwat GitHub, contone. Keamanan ing Jawa: praktik paling apik - 3Uga, kaya sing bisa dideleng saka gambar ing ndhuwur, yen versi sing luwih anyar duwe solusi kanggo kerentanan iki, Snyk bakal nawakake lan nggawe Panjaluk Tarik. Bisa digunakake kanthi gratis kanggo proyek sumber terbuka. Proyek bakal dipindai ing sawetara frekuensi: seminggu sepisan, saben wulan. Aku ndhaptar lan nambah kabeh repositori umum menyang scan Snyk (ora ana sing mbebayani: dheweke wis mbukak kanggo kabeh wong). Sabanjure, Snyk nuduhake asil scan: Keamanan ing Jawa: praktik paling apik - 4Lan sawise sawetara wektu, Snyk-bot nyiapake sawetara Pull-Requests ing proyek ngendi dependensi kudu dianyari: Keamanan ing Jawa: praktik paling apik - 5Lan iki liyane: Keamanan ing Jawa: praktik paling apik - 6Dadi iki alat banget kanggo nelusuri kerentanan lan ngawasi kanggo nganyari. versi anyar.

Gunakake Lab Keamanan GitHub

Sing makarya ing GitHub uga bisa njupuk kauntungan saka piranti sing dibangun. Sampeyan bisa maca liyane babagan pendekatan iki ing terjemahan saka blog sing Pengumuman Lab Keamanan GitHub . Alat iki, mesthi, luwih gampang tinimbang Snyk, nanging sampeyan ora kudu nglirwakake. Kajaba iku, jumlah kerentanan sing dikenal mung bakal tuwuh, mula Lab Keamanan Snyk lan GitHub bakal nambah lan nambah.

Aktifake Sonatype DepShield

Yen sampeyan nggunakake GitHub kanggo nyimpen repositori, sampeyan bisa nambah salah sawijining aplikasi menyang proyek saka MarketPlace - Sonatype DepShield. Kanthi bantuan, sampeyan uga bisa mindai proyek kanggo dependensi. Kajaba iku, yen nemokake apa wae, Masalah GitHub bakal digawe kanthi katrangan sing cocog, kaya sing ditampilake ing ngisor iki: Keamanan ing Jawa: praktik paling apik - 7

4. Nangani data sensitif kanthi ati-ati

Keamanan ing Jawa: praktik paling apik - 8Ing wicara basa Inggris, tembung "data sensitif" luwih umum. Pambocoran informasi pribadhi, nomer kertu kredit lan informasi pribadhi liyane saka klien bisa nimbulaké gawe piala irreparable. Kaping pisanan, sampeyan kudu nliti desain aplikasi lan nemtokake manawa ana data sing dibutuhake. Mbok ana sing ora perlu kanggo sawetara wong, nanging padha ditambahake kanggo mangsa sing durung teka lan ora kamungkinan teka. Kajaba iku, sajrone logging proyek, data kasebut bisa bocor. Cara prasaja kanggo nyegah data sensitif supaya ora mlebu log sampeyan yaiku ngresiki metode toString()entitas domain (kayata Panganggo, Siswa, Guru, lan liya-liyane). Iki bakal nyegah kothak sensitif supaya ora sengaja dicithak. Yen sampeyan nggunakake Lombok kanggo ngasilake metode toString(), sampeyan bisa nggunakake anotasi @ToString.Excludekanggo nyegah kolom digunakake ing output liwat metode kasebut toString(). Uga, ati-ati banget nalika nuduhake data karo jagad njaba. Contone, ana titik pungkasan http sing nuduhake jeneng kabeh pangguna. Ora perlu nuduhake ID unik internal pangguna. Kenging punapa? Amarga nggunakake, panyerang bisa entuk informasi liyane sing luwih rahasia babagan saben pangguna. Contone, yen sampeyan nggunakake Jackson kanggo serialize lan deserialize POJOs menyang JSON , sampeyan bisa nggunakake @JsonIgnorelan anotasi @JsonIgnorePropertieskanggo nyegah kothak tartamtu saka serialized utawa deserialized. Umumé, sampeyan kudu nggunakake kelas POJO beda kanggo macem-macem panggonan. Iki artine apa?
  1. Kanggo nggarap database, gunakake mung POJO - Entitas.
  2. Kanggo nggarap logika bisnis, transfer Entitas menyang Model.
  3. Kanggo nggarap jagad njaba lan ngirim panjalukan http, gunakake entitas katelu - DTO.
Kanthi cara iki sampeyan bisa nemtokake kanthi jelas lapangan sing bakal katon saka njaba lan sing ora bakal katon.

Gunakake algoritma enkripsi lan hashing sing kuat

Data pelanggan rahasia kudu disimpen kanthi aman. Kanggo nindakake iki, sampeyan kudu nggunakake enkripsi. Gumantung ing tugas, sampeyan kudu mutusake apa jinis enkripsi sing bakal digunakake. Kajaba iku, enkripsi sing luwih kuat mbutuhake wektu luwih akeh, mula maneh sampeyan kudu nimbang sepira kabutuhan kanggo mbenerake wektu sing ditindakake. Mesthi, sampeyan bisa nulis algoritma dhewe. Nanging iki ora perlu. Sampeyan bisa njupuk kauntungan saka solusi sing ana ing wilayah iki. Contone, 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>
Ayo ndeleng carane nggunakake, nggunakake conto carane encrypt siji cara lan liyane:
private static void encryptDecryptExample() {
   AeadConfig.register();
   KeysetHandle handle = KeysetHandle.generateNew(AeadKeyTemplates.AES128_CTR_HMAC_SHA256);

   String plaintext = "Цой жив!";
   String aad = "Юрий Клинских";

   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));
}

Enkripsi sandhi

Kanggo tugas iki, paling aman nggunakake enkripsi asimetris. Kenging punapa? Amarga aplikasi kasebut pancen ora perlu dekripsi sandhi maneh. Iki minangka pendekatan umum. Ing kasunyatan, nalika pangguna ngetik sandhi, sistem enkripsi lan mbandhingake karo apa sing ana ing sandhi. Enkripsi ditindakake kanthi nggunakake cara sing padha, supaya sampeyan bisa nyana yen cocog (yen sampeyan ngetik sandhi sing bener;), mesthi). BCrypt lan SCrypt cocok kanggo tujuan iki. Loro-lorone minangka fungsi siji arah (hashes kriptografi) kanthi algoritma komputasi sing rumit sing mbutuhake wektu akeh. Iki persis sing sampeyan butuhake, amarga deciphering iku bakal ditindakake ing salawas-lawase. Contone, Spring Security ndhukung sawetara algoritma. SCryptPasswordEncoderSampeyan uga bisa nggunakake BCryptPasswordEncoder. Apa algoritma enkripsi sing kuwat saiki bisa uga lemah ing taun ngarep. Akibaté, kita nyimpulake yen perlu mriksa algoritma sing digunakake lan nganyari perpustakaan kanthi algoritma.

Tinimbang output

Dina iki kita ngomong babagan safety lan, mesthi, akeh perkara sing ditinggalake. Aku mung mbukak lawang menyang donya anyar kanggo sampeyan: donya sing urip dhewe. Kanthi keamanan iku padha karo politik: yen sampeyan ora melu politik, politik bakal melu sampeyan. Cara tradisional, aku saranake langganan akun Github . Ing kana aku ngirim karya babagan macem-macem teknologi sing daksinaoni lan ditrapake ing karya.

pranala migunani

Ya, meh kabeh artikel ing situs kasebut ditulis nganggo basa Inggris. Apa kita seneng utawa ora, Inggris iku basa kanggo programer kanggo komunikasi. Kabeh artikel, buku, lan majalah paling anyar babagan program ditulis nganggo basa Inggris. Mulane pranala menyang rekomendasi biasane ana ing basa Inggris:
  1. Habr: SQL Injection kanggo Pamula
  2. Oracle: Java Security Resource Center
  3. Oracle: Pedoman Coding Aman kanggo Java SE
  4. Baeldung: Dasar Keamanan Jawa
  5. Sedheng: 10 tips kanggo nguatake keamanan Java
  6. Snyk: 10 praktik paling apik keamanan java
  7. JR: Pengumuman Lab Keamanan GitHub: nglindhungi kabeh kode sampeyan bebarengan
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION