Dieser Artikel wurde von Uncle_Tom aus der Huawei Cloud Community „ Application Security Protection ESAPI “ geteilt.
1. Einführung in ESAPI
OWASP Enterprise Security API (ESAPI) ist eine kostenlose Open-Source-Bibliothek mit Sicherheitskontrollen für Webanwendungen, die es Programmierern erleichtert, Anwendungen mit geringerem Risiko zu schreiben. Die ESAPI-Bibliothek soll es Programmierern erleichtern, bestehende Anwendungen hinsichtlich der Sicherheit nachzurüsten. Auch für Neuentwicklungen ist die ESAPI-Bibliothek eine solide Grundlage.
Unter Berücksichtigung sprachspezifischer Unterschiede haben alle OWASP ESAPI-Versionen das gleiche Grunddesign:
- Es gibt eine Reihe von Sicherheitskontrollschnittstellen. Definiert beispielsweise die Parametertypen, die an Sicherheitskontrolltypen übergeben werden.
- Jede Sicherheitskontrolle verfügt über eine Referenzimplementierung. Beispiel: stringbasierte Eingabevalidierung. Zum Beispiel Javas ESAPI org.owasp.ESAPI.reference.FileBasedAuthenticator, während andere Referenzimplementierungen ausgereifte Referenzimplementierungen auf Unternehmensebene sind, wie z. B. org.oasp.ESAPI.reference.DefaultEncoder oder org.owasp.ESAPI.reference.DefaultValidator .
- Jede Sicherheitskontrolle verfügt über eine eigene Implementierung (optional). Diese Klassen können Anwendungslogik enthalten, die von oder für Ihre Organisation entwickelt werden kann. Beispiel: Unternehmensauthentifizierung.
- Um die Verbreitung dieses Projekts so einfach wie möglich zu gestalten und mehr Menschen die freie Nutzung zu ermöglichen, verwendet der Quellcode dieses Projekts die BSD-Lizenz. Die Dokumentation für dieses Projekt ist unter einer Creative Commons Attribution License lizenziert. Es steht Ihnen frei, ESAPI zu verwenden, zu ändern und sogar in kommerzielle Produkte einzubinden.
2. ESAPI-Framework
OWASP ESAPI hat die folgenden Sicherheitskontrollen implementiert
- Authentifizierung
- Zugangskontrolle
- Eingabevalidierung
- Ausgabekodierung/Escape
- Passwort
- Fehlerbehandlung und Protokollierung
- Kommunikationssicherheit
- HTTP-Sicherheit
- Sicherheitskonfiguration
ESAPI-Framework
OWASP Top 10 von ESAPI abgedeckt
3. Verwendung von ESAPI
3.1. ESAPI-Konfiguration in pom.xml
Die neueste Version ist: 2.5.3.1, die direkt im Maven-Repository zu finden ist.
<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi --> <dependency> <groupId>org.owasp.esapi</groupId> <artifactId>esapi</artifactId> <version> 2.5.3.1</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <!-- https ://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1 .0</version> <scope>bereitgestellt</scope> </dependency>
3.2. Schutz vor Injektionsproblemen
Ein großer Teil der Netzwerksicherheitsprobleme wird durch Injektionsprobleme verursacht. Diese Art von Problem wird hauptsächlich durch unsachgemäße Transkodierung bei der Verwendung externer Eingaben wie SQL-Injection, Command-Injection, Cross-Site-Scripting usw. verursacht.
Encode (Encoder-Schnittstelle) enthält viele Methoden zum Dekodieren von Eingaben und Kodieren von Ausgaben, sodass die verarbeiteten Zeichen für verschiedene Interpreter sicher sind.
3.2.1. Schutz: XSS-Cross-Site-Scripting-Angriff
HTML-Encoder (encodeForHTML)
@Test void testEncodeForHTML() { String input = "<a href='sdfs'></a> < script > warning('xss'); </ script >"; String encodedString = ESAPI.encoder().encodeForHTML(input); LOG.info("EncodeForHTML: {}", encodedString); }
Ausgabe:
EncodeForHTML: <a href='xss'></a> < Skript > Warnung('xss'); </ Skript >
URL-Encoder (encodeForURL)
@Test void testEncodeForURL() { String input = "/?callback=<script>alert('xss')</script>"; String encodedString; Versuchen Sie es mit { encodedString = ESAPI.encoder().encodeForURL(input); LOG.info("EncodeForURL: {}", encodedString); } Catch (EncodingException e) { fail("Sollte keine Ausnahme erhalten:" + e.getMessage()); } }
Ausgabe:
EncodeForURL: %2F%3Fcallback%3D%3Cscript%3Ealert%28%27xss%27%29%3C%2Fscript%3E
3.2.2. Schutz: SQL-Injection
@Test void testEncodeForSQL() { String userId = "tom' or '1=1'"; String sql = "select * from user where user='" + ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), userId) + "'"; LOG.info("sql = {}", sql); }
Ausgabe:
sql = select * from user where user='tom\' or \'1\=1\''
3.2.3. Schutz: Befehlsinjektion
@Test void testEncodeForOS() { String input = "dir & dir /s"; String cmd = ESAPI.encoder().encodeForOS(new WindowsCodec(), input); LOG.info("cmd = {}", cmd); }
Ausgabe:
cmd = dir^ ^&^ dir^ ^/s
3.3. Schutz vor Eingabevalidierungsproblemen
Die größte Bedrohung für die Netzwerksicherheit sind externe Eingaben. Daher spielt die Überprüfung externer Eingaben die größte Schutzfunktion für die Anwendungssicherheit.
3.3.1. Überprüfung der ESAPI-Eingabe
ESAPI verfügt über eine Eingabevalidierungskonfiguration: validation.properties bietet häufig verwendete Validierungen.
validation.properties
Validator.SafeString=^[.\\p{Alnum}\\p{Leerzeichen}]{0,1024}$ Validator.Email=^[A-Za-z0-9._%'-]+@[A- Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][ 0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]| [01]?[0-9][0-9]?)$ Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z] ([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\ .\\?\\,\\:\\'\\/\\\\\\+=&;%\\$#_]*)?$ Validator.CreditCard=^(\\d{4}[ - ]?){3}\\d{4}$ Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[ 012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
Verifizierungsschnittstelle
/** * Eingabeüberprüfung * * @param Kontextüberprüfung Inhalt * @param Eingabeüberprüfung Eingabe * @param Typüberprüfungstyp, entsprechend dem Typ in validation.properties * @param maxLength Überprüfung der maximalen Länge des Eingabezeichens * @paramallowNull Eingabezeichen Null Wertüberprüfung, false – nicht zulässig; true – zulässig * @return Gibt false zurück, wenn die Überprüfung fehlschlägt, gibt true zurück, wenn die Überprüfung erfolgreich ist */ boolean ESAPI.validator().getValidInput(String context, String input, String type , int maxLength, booleanallowNull );
@Test void testValidatorEmail() { String input = "xxxx.com"; if (!ESAPI.validator().isValidInput("", input, "Email", 11, false)) { LOG.error("E-Mail-Validierung fehlgeschlagen!"); } else { LOG.info("E-Mail ist validiert."); } }
Ausgabe:
E-Mail-Validierung fehlgeschlagen!
4. Häufige Probleme, die bei der Verwendung und Aktualisierung von ESAPI auftreten
4.1. org.owasp.esapi.reference.DefaultEncoder CTOR hat eine Ausnahme ausgelöst, die durch ExceptionInInitializerError verursacht wurde
org.owasp.esapi.errors.ConfigurationException: java.lang.reflect.InvocationTargetException Encoder-Klasse (org.owasp.esapi.reference.DefaultEncoder) CTOR hat eine Ausnahme ausgelöst. unter org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:129) unter org.owasp.esapi.ESAPI.encoder(ESAPI.java:101) unter com.test.esapi.EsapiTest.testUpdateJulietInfo_good(EsapiTest.java :19) bei java.base/java.util.ArrayList.forEach(ArrayList.java:1511) bei java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Verursacht durch: java.lang.reflect. InvocationTargetException bei org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:86) ... 71 weitere Verursacht durch: java.lang.ExceptionInInitializerError bei java.base/java.lang.Class.forName0(Native Method) bei java.base/java.lang.Class.forName(Class.java:375) bei org.owasp.esapi.util.ObjFactory.loadClassByStringName(ObjFactory.java:158) bei org.owasp.esapi.util.ObjFactory.make( ObjFactory.java:81) unter org.owasp.esapi.ESAPI.logFactory(ESAPI.java:139) unter org.owasp.esapi.ESAPI.getLogger(ESAPI.java:155) unter org.owasp.esapi.reference.DefaultEncoder .(DefaultEncoder.java:85) bei org.owasp.esapi.reference.DefaultEncoder.(DefaultEncoder.java:109) bei org.owasp.esapi.reference.DefaultEncoder.getInstance(DefaultEncoder.java:68) ... 76 weitere Verursacht durch: org.owasp.esapi.errors.ConfigurationException: Ressource: esapi-java-logging.properties bei org.owasp.esapi.logging.java.JavaLogFactory.readLoggerConfiguration(JavaLogFactory.java:128) bei org.owasp konnte nicht gefunden werden .esapi.logging.java.JavaLogFactory.(JavaLogFactory.java:96) ... 85 weitere
Dies ist das häufigste Problem, das beim Upgrade von ESAPI auf Versionen nach 2.5.0.0 auftritt.
2.5.0.0 ist eine wichtige geänderte Version von ESAPI. Aus den Informationen zur Versionsänderung können wir Folgendes ersehen:
- Diese Version von ESAPI verzichtet vollständig auf die Unterstützung von Log4J, das unter den ständigen Schwachstellen von Log4J leidet, und verwendet stattdessen SLF4J. Wenn Ihre ESAPI.Logger-Eigenschaft auf die Verwendung von Log4J eingestellt ist, werden obskure Ausnahmen oder Fehler ausgelöst, normalerweise ExceptionInInitializerError, wenn Sie sie nicht ändern.
- AntiSamy wurde auf 1.7.0 aktualisiert und die angepasste Datei AntiSamy-sapi.xml von AntiSamy wird unterstützt.
- Ab der Vorgängerversion unterstützt diese Version nur Java 8 oder höher.
Hier können Sie erkennen, dass ExceptionInInitializerError durch die Änderungsprotokollkomponente verursacht werden sollte. Vertraute Freunde werden sofort an die Konfigurationsdatei von ESAPI, ESAPI.properties, denken, die die Konfiguration aller Komponenten enthält.
Wie Sie in den Zeilen 69 bis 72 der Abbildung sehen können, Zeile 69:
ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory
Es verweist immer noch auf org.owasp.esapi.logging.java.JavaLogFactory. Die folgenden Kommentare erinnern uns auch daran, dass wir es in Zeile 71 ändern müssen:
ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
Das Problem ist nach der Änderung behoben.
4.2. java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest bei java.base/java.lang.Class.getDeclaredMethods0(Native Method) bei java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) bei java .base/java.lang.Class.getMethodsRecursive(Class.java:3543) bei java.base/java.lang.Class.getMethod0(Class.java:3529) bei java.base/java.lang.Class.getMethod(Class .java:2225) bei org.owasp.esapi.util.ObjFactory.loadMethodByStringName(ObjFactory.java:196) bei org.owasp.esapi.util.ObjFactory.findSingletonCreateMethod(ObjFactory.java:173) bei org.owasp.esapi. util.ObjFactory.make(ObjFactory.java:84) bei org.owasp.esapi.ESAPI.validator(ESAPI.java:192) bei com.huawei.hwe.esapi.EsapiTest.testEsapi_encodeForURL(EsapiTest.java:23) bei Java .base/java.util.ArrayList.forEach(ArrayList.java:1511) unter java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Verursacht durch: java.lang.ClassNotFoundException: javax.servlet.http .HttpServletRequest bei java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) bei java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) bei java.base /java.lang.ClassLoader.loadClass(ClassLoader.java:525) ... 79 weitere
Dieses Problem besteht offensichtlich darin, dass abhängige Bibliotheken fehlen. Wir können die Definitions- und Abhängigkeitsinformationen der Maven-Bibliothek zu ESAPI anzeigen.
https://mvnrepository.com/artifact/org.owasp.esapi/esapi/2.5.3.1
Kompilierungsabhängigkeiten
Laufzeitabhängigkeiten

In den laufenden Abhängigkeiten können Sie die Anforderungen sehen: javax.servlet » javax.servlet-api.
Klicken Sie auf die Versionsnummer: 3.1.0, um die MVN-Abhängigkeitskonfiguration von javax.servlet-api 3.1.0 zu erhalten. Fügen Sie diese Konfiguration hinzu die Projektdatei pom.xml darauf.
Nach dem Hinzufügen der javax.servlet-api-Konfiguration in pom.xml ist das Problem gelöst.
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId > <version>3.1.0</version> <scope>bereitgestellt</scope> </dependency>