In qualità di programmatore o sviluppatore, l'importanza di creare applicazioni sicure non può essere trascurata.
La sicurezza del software affronta la gestione degli attacchi dannosi identificando potenziali vulnerabilità nel software e adottando le precauzioni necessarie per proteggerle.
Il software non potrà mai essere sicuro al 100% perché gli sviluppatori possono ignorare un bug, introdurre nuovi bug mentre correggono quelli esistenti o introdurre nuove vulnerabilità tramite gli aggiornamenti.
Tuttavia, esistono due metodi principali che tutti gli sviluppatori di software possono utilizzare per garantire la creazione di software sicuro. Si tratta di scrivere codice sicuro fin dall'inizio e testarlo in modo efficace.
La sicurezza del software gioca un ruolo estremamente importante
Come scrivere codice sicuro
Scrivere codice sicuro ha solo una cosa da fare: la gestione degli errori. Se riesci ad anticipare ogni valore potenziale che l'utente può fornire all'applicazione e generare una risposta nel programma per quel valore, stai scrivendo un codice sicuro.
Questo è molto più semplice di quanto si possa pensare, poiché tutti i bravi sviluppatori sanno quasi tutto delle applicazioni che sviluppano. Pertanto, dovresti conoscere ogni valore richiesto dalla tua applicazione per eseguire un'attività (valori approvati) e comprendere che qualsiasi altro valore che potrebbe esistere è un valore non approvato.
Scrivi un codice sicuro
Supponiamo di voler creare un programma che accetti solo due valori interi dall'utente ed esegua su di essi un'operazione di addizione. Da buon sviluppatore, ora sai tutto sulla tua applicazione. Conosci tutti i valori che questo programma accetterà (valori interi) e conosci il compito che questo programma svolgerà (un'operazione di addizione).
Esempio di creazione di un programma in Java
import java.util.Scanner;
public class Main {
//The main function that executes the program and collects the two values
public static void main(String[] args) {
System.out.println("Please enter your two integer values: ");
int value1;
int value2;
Scanner input = new Scanner(System.in);
value1 = input.nextInt();
value2 = input.nextInt();
addition(value1, value2);
input.close();
}
//the function that collects the two values and displays their sum
private static void addition(int value1, int value2) {
int sum;
sum = value1 + value2;
System.out.println("The sum of the two integer values you entered: "+ sum);
}
}
Il codice precedente crea un'applicazione che soddisfa esattamente i requisiti. Una volta eseguito, produrrà la seguente riga nella console:
Please enter your two integer values:
L'applicazione rimarrà quindi in pausa finché l'utente non inserirà due valori interi nella console (ovvero inserire il primo valore, premere il tasto Invio e ripetere).
Se l'utente inserisce i valori 5 e 4 nella console, il programma produce il seguente output:
The sum of the two integer values you entered: 9
È fantastico. Il programma fa esattamente quello che dovrebbe fare. Tuttavia, se un utente malevolo entra e inserisce un valore non intero, come "g", nella tua applicazione, si verificherà un problema. Questo perché nell'applicazione non è presente codice che protegga da valori non approvati.
A questo punto, la tua applicazione andrà in crash, creando un potenziale gateway nella tua applicazione in modo che gli hacker sappiano esattamente cosa fare dopo.
Esempio di sicurezza del programma
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
//The main function that executes the program and collects the two values
public static void main(String[] args) {
try {
System.out.println("Please enter your two integer values: ");
int value1;
int value2;
//using the scanner class to read each input from the user,
//and assign it to is respective variable (throws an exception if the values are not integers)
Scanner input = new Scanner(System.in);
value1 = input.nextInt();
value2 = input.nextInt();
//calls the addition function and passes the two values to it
addition(value1, value2);
//closes the input stream after it has come to the end of its use
input.close();
//handle all the errors thrown in the try block
}catch(InputMismatchException e){
System.out.println("Please enter a valid integer value.");
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
//the function that collects the two values and displays their sum
private static void addition(int value1, int value2) {
int sum;
sum = value1 + value2;
System.out.println("The sum of the two integer values you entered: "+ sum);
}
}
Il codice precedente è sicuro perché esegue la gestione delle eccezioni. Pertanto, se si immette un valore non intero, il programma genererà la seguente riga di codice:
Please enter a valid integer value.
Cos'è la gestione delle eccezioni?
La gestione delle eccezioni
In sostanza, la gestione delle eccezioni è la versione moderna della gestione degli errori, in cui si separa il codice di gestione degli errori dal normale codice di gestione. Nell'esempio precedente, tutto il codice di gestione normale (o il codice che potenzialmente causa eccezioni) si trova nel blocco try e tutto il codice di gestione degli errori si trova nel blocco catch.
Se guardi più da vicino l'esempio sopra, vedrai che ci sono due blocchi catch. Il primo accetta un argomento InputMismatchException : questo è il nome dell'eccezione generata se viene immesso un valore non intero. Il secondo accetta l' argomento Exception , e questo è importante perché il suo scopo è trovare eventuali eccezioni nel codice che lo sviluppatore non ha trovato durante il test.
Controlla il codice
Non dovresti mai sottovalutare il potere di testare e ripetere il test del codice. Molti sviluppatori (e utenti di app) riscontrano nuovi bug dopo che il software è stato reso disponibile al pubblico.
Un test approfondito del tuo codice ti assicura di sapere cosa farà la tua applicazione in ogni situazione immaginabile e ciò ti consente di proteggerla dalle violazioni dei dati.
Considera l'esempio sopra. Cosa succede se, una volta completato, testi l'applicazione solo con valori interi? Potresti lasciare l'applicazione pensando di aver identificato con successo tutti i potenziali errori quando in realtà non è così.
La realtà è che potresti non essere in grado di identificare tutti i potenziali errori. Questo è il motivo per cui la gestione degli errori funziona insieme al test del codice. Testare il programma qui sopra rivela un potenziale errore che si verificherà in una situazione particolare.
Tuttavia, se esiste qualche altro errore che non è apparso durante il test, il secondo blocco catch nel codice precedente lo gestirà.
Sicurezza della banca dati
Se la tua applicazione si connette a un database, il modo migliore per impedire l'accesso a quel database è garantire che tutti gli aspetti dell'applicazione siano sicuri. Tuttavia, cosa succede se la tua applicazione è progettata con l'unico scopo di fornire un'interfaccia a detto database?
È qui che le cose diventano un po’ più interessanti. Nella sua forma più elementare, i database consentono agli utenti di aggiungere, recuperare, aggiornare ed eliminare dati. Un sistema di gestione di database è un'applicazione che consente agli utenti di interagire direttamente con un database.
La maggior parte dei database contiene dati sensibili, pertanto, per mantenere l'integrità e limitare l'accesso a questi dati, esiste un requisito: il controllo dell'accesso.
Controllo di accesso
Il controllo degli accessi mira a mantenere l'integrità del database determinando i tipi di persone che possono accedere al database e limitando il tipo di accesso di cui dispongono. Pertanto, un buon sistema di gestione del database deve essere in grado di registrare chi ha avuto accesso al database, quando e cosa ha fatto.
Può inoltre impedire agli utenti registrati di accedere o modificare dati con i quali non sono autorizzati a interagire.