Germany/Projekte/Top 10 fuer Entwickler-2013/A4-Unsichere direkte Objektreferenzen

A4 Unsichere direkte Objektreferenzen
Denken Sie an verschiedene Typen von Nutzern, die auf Ihr System zugreifen. Gibt es Nutzer, die nur eingeschränkten Zugriff auf bestimmte Daten Ihres Systems haben sollen? Der Angreifer ist autorisiert, auf ein Systemobjekt zuzugreifen. Durch einfache Änderung eines Parameters kann er auf Objekte zugreifen, für die er nicht autorisiert ist. Webanwendungen nutzen oft den internen Namen oder die Kennung eines Objektes, um auf dieses zu verweisen. Anwendungen prüfen dabei nicht immer, ob der Nutzer für den Zugriff auf diese autorisiert ist. Dies führt zu unsicheren direkten Objektreferenzen. Tester können Parameter ändern, um diese Schwachstellen zu entdecken. Code-Analysen zeigen schnell, ob die Autorisierung in geeigneter Weise geprüft wird. Diese Schwachstelle gefährdet alle Daten, die via Parameter referenziert werden können. Angreifer können auf alle verfügbaren Daten dieser Art zugreifen, außer der Namensraum ist dünn besetzt. Prüfen Sie sorgfältig den geschäftlichen Wert ungeschützt verfügbarer Daten. Berücksichtigen Sie auch die geschäftlichen Auswirkungen, die mit der Veröffentlichung der Schwachstelle verbunden sein können.

Die Anwendung nutzt ungeprüfte Daten in einem SQL-Aufruf, der Account-Informationen abfragt: String query = "SELECT * FROM accts WHERE account = ?";   PreparedStatement pstmt = connection.prepareStatement(query, ... ); pstmt.setString( 1, request.getParameter("acct"));  ResultSet results = pstmt.executeQuery; Ein Angreifer ändert den Parameter ‘acct’ im Browser, um beliebige Zugangsnummern abzufragen. Wenn keine Prüfung erfolgt, können Angreifer nicht nur auf ihren eigenen, sondern auf jeden gewünschten Account Zugriff erhalten. http://example.com/app/accountInfo?acct=notmyacct

Um unsichere direkte Objektreferenzen zu verhindern, muss der Schutz eines jeden Objektes (z.B. Objektnummer, Dateiname), das für Nutzer erreichbar ist, gewährleistet werden:
 * 1) Indirekte Objektreferenzen verwenden! Dies verhindert den direkten Angriff auf nicht autorisierte Ressourcen. So sollte eine Auswahlbox mit sechs für den Nutzer verfügbaren Objekten die Ziffern 1 bis 6 als Referenzen enthalten, statt deren echte Datenbankschlüssel. Die Anwendung muss dann diese indirekten Objektreferenzen den echten Datenbankschlüsseln zuordnen. Die OWASP ESAPI enthält Referenzzuordnungen für sequentiellen wie wahlfreien Zugriff, die von Entwicklern zur Vermeidung direkter Referenzen genutzt werden können.
 * 2) Zugriffe prüfen! Jeder Abruf direkter Objektreferenzen aus nicht vertrauenswürdigen Quellen muss eine Prüfung der Zugriffsberechtigung beinhalten, um die Autorisierung für das angefragte Objekt sicherzustellen.

= JAVA =

Zugriffe prüfen!
InjectionChecker für Parameter Prüfung public class InjectionChecker { public static void check(String value) throws InjectionCheckException { // see Topic A1      ... if(checkFailed){ throw new InjectionCheckException("..."); }   } } PermissionChecker für Prüfungung der Zugriffsrechte public class PermissionChecker { public void check(String username, Action action,          Class<? extends Object> objectType, String objectId) throws PermissionCheckException{ ...      if(checkFailed){ throw new PermissionCheckException("..."); }   } } Pseudo Code für Zugriffsprüfung bei direkten Objektreferenzen // Parameter Wert aus dem Request abfragen String acct = request.getParameter("acct"); InjectionChecker.check(acct); // Informationen für die Zugriffsprüfung zustammenstellen String username = getUsername(request); Action action = Action.READ; // (e.g. READ, WRITE, DELETE) Class<? extends Object> objectType = ObjectBean.class; String objectId = acct; // Zufriffsprüfung durchführen PermissionChecker permissionChecker = getPermissionChecker; check(username, action, objectType, objectId); // nach erfolgreicher Prüfung kann der Parameterwert // verwendet werden String query = "SELECT * FROM accts WHERE account_id = ?"; PreparedStatement pstmt = connection.prepareStatement(query, ... ); pstmt.setString( 1, acct); ResultSet results = pstmt.executeQuery;

ESAPI
(Beispiel bisher fast unbearbeitet aus ESAPI übernimmen) => tbd

Set fileSet = new HashSet; fileSet.addAll(...); // add direct references (e.g. File objects) AccessReferenceMap map = new AccessReferenceMap( fileSet ); // store the map somewhere safe - like the session! String indRef = map.getIndirectReference( file1 ); String secureHref = "http://www.your-URL.yourTLD/esapi?file=" + indRef ); ... // if the indirect reference doesn't exist, it's likely an attack // getDirectReference throws an AccessControlException // you should handle as appropriate String indref = request.getParameter( "file" ); File file = (File)map.getDirectReference( indref ); Quelle: ESAPI


 * OWASP SQL Injection Prevention Cheat Sheet
 * OWASP Injection Flaws Article
 * ESAPI Encoder API
 * ESAPI Input Validation API
 * ASVS: Output Encoding/Escaping Requirements (V6)
 * OWASP Testing Guide: Chapter on SQL Injection Testing
 * OWASP Code Review Guide: Chapter on SQL Injection
 * OWASP Code Review Guide: Command Injection


 * CWE Entry 77 on Command Injection
 * CWE Entry 89 on SQL Injection

= Test =

tbd Text

tbd Text

tbd Text

(ganze Breite) Text