ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 33
Abonament PDF

Dezvoltarea aplicațiilor securizate în Java

Silviu Dumitrescu
Line manager@Telenav



Diana Bălan
Map analyst@Telenav



PROGRAMARE


Vom începe acest articol cu câteva considerente generale despre securitate. Astfel, scopul securizării calculatoarelor este acela de a proteja informațiile existente pe acestea de furt, de corupere sau dezastre naturale.

Securitatea trebuie înțeleasă ca o măsură de compromis. De exemplu, cea mai bună metodă de a face o aplicație complet securizată în Internet este să nu o conectăm la Internet.

Unul dintre aspectele importante ale securității este confidențialitatea, care reprezintă ascunderea surselor de informații. Mecanismele folosite pentru realizarea confidențialității sunt: încriptarea, folosirea parolelor și controlul accesului adică acordarea accesului la resurse unui număr limitat de persoane.

Un alt aspect este integritatea, care înseamnă că datele sunt protejate față de modificări neautorizate. Aceasta este realizată de obicei prin autentificare. User-ul trebuie să furnizeze credențiale (username si password). În plus, sistemele de detecție trebuie să fie folosite în cazul în care sistemul de autentificare eșuează. Acest sistem este format din loguri de acces și pattern-i de analiză.

Un ultim aspect este disponibilitatea, care reprezintă abilitatea de a utiliza un sistem sau o resursă la nevoie.

Cel mai simplu mod în care un sistem este vulnerabil îl reprezintă atacurile de refuzare a serviciilor. Acestea blochează accesul la sistem al utilizatorilor sau reduce nivelul de performanță al sistemului. Sistemul ar trebui să fie atât de flexibil încât să detecteze aceste atacuri și să răspundă la ele.

Aspecte de securitate la nivelul software-urilor

Orice sistem ce conține informații confidențiale este foarte probabil o țintă a atacatorilor.

Câteva dintre conceptele fundamentale de securitate sunt:

Tipuri de amenințări de securitate

Putem să împărțim amenințările în următoarele categorii:

Injecția și incluziunea reprezintă un atac ce determină un program să interpreteze date într-un mod neașteptat. De aceea, orice date venite dintr-o sursă nesigură trebuie validate. Principalele forme de atac sunt:

Vulnerabilitățile XSS apar atunci când:

Următorul exemplu ilustrează un atac XSS:

<%@page contentType=”text/html” pageEncoding=”UTF-8”%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type”
content=”text/html; charset=UTF-8”>
<title>Login Page</title>
</head>
<body>
<h2>Bine ati venit</h2>
<p>Va rog sa va logati</p>
<form method=”GET”
action=”/XssExample/ProcessForm”>
<b>Login Name: </b>
<input type=”text” size=”12”
maxlength=”12” name=”userName” />
<br/>
<b>Password: </b>
<input type=”text” size=”12”
maxlength=”12” name=”password” />
<br/>
<b>Locatia: </b>
<input type=”text” size=”12”
name=”location” /><br/>
<input type=”submit” value=”Submit” />
<input type=”reset” value=”Reset” />
</form>
<p><a href=”http://localhost:8080/XSS/ProcessForm?userName=Bob&password=Smith&location=</p>%3CScript%20Language%3D%22Javascript%22%3Ealert(%22Ai%20fost%20atacat!%22)%3B%3C%2FScript%3E”>Hacked URL</a></p>
<p>URL Script text: %3CScript%20Language%3D%22Javascript%22%3Ealert(%22vei%20fi%20atacat!%22)%3B%3C%2FScript%3E</p>
</body>
</html>

Respectiv servletul:

@WebServlet("/ProcessForm")
public class ProcessForm extends HttpServlet {
private static final long
serialVersionUID = -5014955266331211217L;

protected void processRequest(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println(
"<title>Servlet de procesare</title>");
out.println("</head>");
out.println("<body>");
out.println("<h2>Prima pagina</h2>");
out.println("<p>sunteti logat ca: " +
request.getParameter("userName") + "</p>");
out.println("<p>si sunteti in: " +
request.getParameter("location") + "</p>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}

@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
public String getServletInfo() {
return "Servlet-ul meu";
}
}

SQL Injection se bazează pe date nefiltrate pentru a modifica rezultatele SQL. Fie următorul cod:

ResultSet rs = stmt.executeQuery ("SELECT * FROM DEMO.Table1 WHERE NAME='" + nameParam + "' AND AGE ='" + ageParam + "'");

Dacă atacatorul trimite: 'valori' OR 'a' = 'a', acesta va face predicatul de selecție adevărat, ceea ce este echivalent cu:

ResultSet rs = stmt.executeQuery ("SELECT * FROM DEMO.Table1");

Prin aceasta atacatorul poate accesa informații confidențiale sau chiar modifica date din baza de date. De aceea orice input trebuie filtrat înainte de utilizare.

OS command injection se bazează pe date nefiltrate ce modifică o comandă a sistemului de operare.

Fie următorul exemplu:

public class ListHomeDir {
  public static void main(String[] args) {
    String userName = "Silviu";
    String curLine = "";
      try {
    Process p = Runtime.getRuntime().exec(
      "cmd /c dir C:\\Users\\" + userName);
    BufferedReader stdInput = new 
          BufferedReader(new InputStreamReader(
          p.getInputStream()));

        BufferedReader stdError = new 
           BufferedReader(new InputStreamReader(
           p.getErrorStream()));

 System.out.println("Home directory este:");
 while ((curLine = stdInput.readLine()) != null) {
   System.out.println(curLine);
 }
 if (stdError.ready()) {
  System.out.println("eroare:");
 }
 while ((curLine = stdError.readLine()) != null) {
   System.out.println(curLine);
}
 System.exit(0);
} catch (IOException e) {
  System.out.println("exceptie: ");
  System.out.println(e.getMessage());
  System.exit(-1);
   }
 }
}

În exemplu dorim să obținem un listing al unui director. Atacatorul poate trimite: username;&&del *.*;, ceea ce va determina pierderea de date.

Fie următorul exemplu de format necontrolat de string-uri:

public class Main {
static Calendar c = new GregorianCalendar(1995, GregorianCalendar.MAY, 23);

public static void main(String[] args) {String param = "%1$tY";
        System.out.printf(param + " nu se potriveste! A fost emis in ziua %1$te \n", c);
    }
}

În acest cod programatorul încearcă să printeze rezultatele atunci când două valori nu se potrivesc. Problema poate apare atunci când este trimis un string format în loc de lună. Atacatorul își poate da seama de an, spre exemplu, atunci când un card expiră.

Din punct de vedere al managementului de resurse avem:

Fie următorul exemplu:

public class FileException {
    Properties appProps = new Properties();
    public static void main(String[] args) {
      FileException app = new FileException();
          app.readProps("AppConfig.properties");
      app.printProps();
    }

    public void readProps(String fileName) {
    try {
     appProps.load(new FileInputStream(fileName));
     } catch (IOException e) {
    System.out.println("Nu putem gasi fisierul "+ 
      "de configurare: " + e.getMessage());
    e.printStackTrace();
    System.exit(-1);
    }
     } 
  public void printProps() {
    appProps.list(System.out);
  }
}

Sistemul nu ar trebui să furnizeze potențialilor atacatori locația exactă a fișierului de configurare al aplicației.

Informațiile confidențiale ar trebui să fie disponibile spre citire doar într-un context limitat, să nu fie disponibile pentru manipulare, să se furnizeze utilizatorilor doar informațiile de care au nevoie, informațiile să nu fie hard cod-ate în surse.

Datele confidențiale nu ar trebui incluse în excepții sau fișiere de log. De asemenea, nu ar trebui să hard cod-ăm username-ul și parola în codul sursă. Ar trebui folosit un fișier de proprietăți pentru a stoca acest tip de informații.

Dăm mai jos un exemplu de creare și folosire a unui fișier de log.

public class BasicLogging {
    Logger logger = Logger.getLogger("com.example.BasicLogging");

    public void logMessages(){     
        logger.severe("A aparut o problema severa");
        logger.warning("Avertisment");
        logger.log(Level.INFO,"Informatie utila");
        logger.config("Informatii despre CONFIG");
    }

    public static void main(String[] args) {
        BasicLogging bl = new BasicLogging();
        bl.logger = Logger.getLogger("com.example"+
    ".BasicLogging");

        try {
         bl.logger.addHandler(new FileHandler(
          "Basic.log"));
            bl.logger.setLevel(Level.INFO);
            bl.logMessages();
        } catch (IOException e){
            e.getMessage();
        }
    }
}

Vă dorim lectură plăcută și așteptăm cu interes întrebările voastre!

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects