diff --git a/src/de/superx/sec/HttpGetAccessGuard.java b/src/de/superx/sec/HttpGetAccessGuard.java new file mode 100644 index 0000000..4050557 --- /dev/null +++ b/src/de/superx/sec/HttpGetAccessGuard.java @@ -0,0 +1,38 @@ +package de.superx.sec; + +import java.util.Set; + +public class HttpGetAccessGuard { + + private Set whitelist = null; + private Set blacklist = null; + private Set blacklist_custom = null; + + public boolean isHttpGetAllowed(Integer masken_tid) { + if (this.whitelist != null) { + if (this.whitelist.contains(masken_tid) ) { + return true; + } + } else { + if (this.blacklist_custom != null && this.blacklist_custom.contains(masken_tid)) { + return false; + } + if (this.blacklist != null) { + return !this.blacklist.contains(masken_tid); + } + } + return false; + } + + public void setWhitelist(Set whitelist) { + this.whitelist = whitelist; + } + + public void setBlacklist(Set blacklist) { + this.blacklist = blacklist; + } + + public void setBlacklist_custom(Set blacklist_custom) { + this.blacklist_custom = blacklist_custom; + } +} diff --git a/src/de/superx/sec/HttpGetAccessListParser.java b/src/de/superx/sec/HttpGetAccessListParser.java new file mode 100644 index 0000000..a25abc3 --- /dev/null +++ b/src/de/superx/sec/HttpGetAccessListParser.java @@ -0,0 +1,20 @@ +package de.superx.sec; + +import java.util.Set; +import java.util.TreeSet; + +public class HttpGetAccessListParser { + + public static Set parseList(String input) { + String[] lines = input.split("\n|\r"); + Set result = new TreeSet(); + for (String line : lines) { + if (line.trim().length() == 0 || line.charAt(0) == '#') { + continue; + } + Integer tid = Integer.valueOf(line.trim()); + result.add(tid); + } + return result; + } +} diff --git a/src/de/superx/servlet/RequestParameter.java b/src/de/superx/servlet/RequestParameter.java index 3d47297..9c61fa5 100644 --- a/src/de/superx/servlet/RequestParameter.java +++ b/src/de/superx/servlet/RequestParameter.java @@ -423,6 +423,7 @@ public enum RequestParameter{ this.parameterString = name; } + @Override public String toString() { if (parameterString == null) { return super.toString(); @@ -431,4 +432,4 @@ public enum RequestParameter{ } -} \ No newline at end of file +} diff --git a/src/de/superx/servlet/ServletBasics.java b/src/de/superx/servlet/ServletBasics.java index accb4ec..42b5f1e 100644 --- a/src/de/superx/servlet/ServletBasics.java +++ b/src/de/superx/servlet/ServletBasics.java @@ -16,6 +16,16 @@ import de.memtext.util.TimeUtils; import de.superx.util.SqlStringUtils; public class ServletBasics { + /** + * returns parameter from request + * @param request + * @param name + * @throws IllegalArgumentException if contains tags + */ + public static String getParameter(HttpServletRequest request, RequestParameter name) { + return getParameterString(request, name.toString()); + } + /** * returns parameter from request * @param request diff --git a/src/de/superx/servlet/SuperXManager.java b/src/de/superx/servlet/SuperXManager.java index 9b54658..e14f6fc 100644 --- a/src/de/superx/servlet/SuperXManager.java +++ b/src/de/superx/servlet/SuperXManager.java @@ -10,6 +10,7 @@ import java.sql.SQLException; import java.text.ParseException; import java.util.Date; import java.util.Enumeration; +import java.util.Set; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -39,6 +40,8 @@ import de.memtext.util.XMLUtils; import de.superx.common.DBServletException; import de.superx.common.SxUser; import de.superx.common.TransletCache; +import de.superx.sec.HttpGetAccessGuard; +import de.superx.sec.HttpGetAccessListParser; import de.superx.sec.InputCheckRegistry; import de.superx.util.SqlStringUtils; @@ -64,7 +67,7 @@ public class SuperXManager extends HttpServlet { public static boolean isSichtenCachingWanted = true; public static String sxversion="@version@"; public static String builddatum="@sxtimestamp@"; - + public static HttpGetAccessGuard httpGetAccessGuard; private static final String ADMIN_ONLY = de.superx.servlet.SuperXManager.htmlPageHead("Admin-Bereich")+"

Hier ist ein Login nur für Administratoren möglich.

(Cookies müssen aktiviert sein)" + "

Kennung:

Passwort:
" @@ -561,6 +564,7 @@ public class SuperXManager extends HttpServlet { } private void doInit() throws ServletException { + initHttpGetAccessGuard(); InputCheckRegistry.registerDefaultChecks(); his1_refapp=System.getProperty(QIS_CONTEXT); if(his1_refapp==null) @@ -803,4 +807,31 @@ public class SuperXManager extends HttpServlet { public static boolean isStandaloneLdapActive() { return isStandaloneLdapActive; } + private void initHttpGetAccessGuard() { + httpGetAccessGuard = new HttpGetAccessGuard(); + String blacklist_filename = SuperXManager.getWEB_INFPfad() + File.separator + + "http_get_masken_blacklist.txt"; + String blacklist_custom_filename = SuperXManager.getWEB_INFPfad() + File.separator + + "http_get_masken_blacklist_custom.txt"; + String whitelist_filename = SuperXManager.getWEB_INFPfad() + File.separator + + "http_get_masken_whitelist.txt"; + httpGetAccessGuard.setBlacklist(parseWhiteBlacklistFile(blacklist_filename)); + httpGetAccessGuard.setBlacklist_custom(parseWhiteBlacklistFile(blacklist_custom_filename)); + httpGetAccessGuard.setWhitelist(parseWhiteBlacklistFile(whitelist_filename)); + } + + private Set parseWhiteBlacklistFile(String list_filename) { + File list_file = new File(list_filename); + if (list_file.exists()) { + try { + String content = de.memtext.util.StringUtils.readFile(list_file); + return HttpGetAccessListParser.parseList(content); + } catch (IOException e) { + logger.error("could not read file '" + list_file.getAbsolutePath()); + } catch (NumberFormatException e) { + logger.error("could not parse file '" + list_file.getAbsolutePath(), e); + } + } + return null; + } } diff --git a/src/de/superx/servlet/SuperXmlTabelle.java b/src/de/superx/servlet/SuperXmlTabelle.java index fb07d41..c7afb9f 100644 --- a/src/de/superx/servlet/SuperXmlTabelle.java +++ b/src/de/superx/servlet/SuperXmlTabelle.java @@ -116,6 +116,14 @@ import net.sf.jasperreports.engine.JRException; */ public class SuperXmlTabelle extends AbstractSuperXServlet { + private static final String PARAM_IS_SENT_SUFFIX = "-isSent"; + + private static final String PARAM_TRUE = "true"; + + private static final String PARAM_XML_ = "/xml"; + + private static final String PARAM_CLASS = "class"; + private static final long serialVersionUID = 1L; TimeUtils tutil = new TimeUtils(); @@ -282,20 +290,30 @@ public class SuperXmlTabelle extends AbstractSuperXServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (request.getParameter("bigexcel") != null && request.getParameter("bigexcel").equals("true")) { - BigExcelCreator b = new BigExcelCreator(request, response); - - b.run(true); - - } else if (request.getParameter("getKidRows") != null) { - throw new ServletException("HTTP-Get not allowed for Ajax requests"); - } else if (request.getParameter("checkFor") != null) { - checkFor(request, response); - + Integer tid = Integer.valueOf(getTid(request)); + if (SuperXManager.httpGetAccessGuard.isHttpGetAllowed(tid)) { + if (request.getParameter(RequestParameter.bigexcel.toString()) != null && request.getParameter(RequestParameter.bigexcel.toString()).equals(PARAM_TRUE)) { + BigExcelCreator b = new BigExcelCreator(request, response); + + b.run(true); + } else if (request.getParameter(RequestParameter.checkFor.toString()) != null) { + checkFor(request, response); + } else { + doPost(request, response); + } + } else if (ServletBasics.getParameter(request, RequestParameter.getKidRows) != null) { + // dieser Ausführungszweig sorgt dafür, dass XHR-Requests für die Aufklappfunktion in hierarchischen/drilldown + // Berichten auch dann noch funktioniert, wenn der betroffene Bericht generell für HTTP GET + // gesperrt/-blacklisted ist + KidRowsResponder kr = new KidRowsResponder(request, response); + kr.run(true); } else { - doPost(request, response); + // es dürfen nicht alle Masken über HTTP GET genutzt werden - siehe HISzilla Anfrage #283628 + System.out.println("GET-Aufruf von Maske " + tid.toString() + " wurde aufgrund von black-/whitelisting-policy abgewiesen"); + response.setStatus(java.net.HttpURLConnection.HTTP_FORBIDDEN); } } + /** * Prüft ob für Maske schon etwas zurückgeschickt wurde, Rückmeldung, wenn diff --git a/src/de/superx/servlet/UserInitializer.java b/src/de/superx/servlet/UserInitializer.java index 0eaa7c7..745f784 100644 --- a/src/de/superx/servlet/UserInitializer.java +++ b/src/de/superx/servlet/UserInitializer.java @@ -206,6 +206,7 @@ public class UserInitializer { System.out.println("LDAP aktiv aber Passwortkontrolle für "+username+" aus SuperX-Datenbank wegen Parameter login=superx"); } if (SuperXManager.isStandaloneLdapActive()&&!"superx".equals(login)) isRemotePasswordCheck=true; + // MB Provisorium für kern4.9 alte LDAP-Technik via RemoteUser deaktiviert /* * if (username == null) { username = request.getRemoteUser(); // LDAP if @@ -530,9 +531,7 @@ public class UserInitializer { if (kennwortSpalte != null) kennwortSpalte = kennwortSpalte.trim().toLowerCase(); if (kennwortSpalte != null && (kennwortSpalte.equals("ändern") || kennwortSpalte.equals("aendern")) - // && request.getRemoteUser() == null) // nur ohne LDAP - // MB LDAP Provisorium für kern4.9 - && !isRemotePasswortCheck) + && !isRemotePasswortCheck) isPasswordChangeDemanded = true; adminUser = new Short(rs.getShort(3)); password_sha = (String) rs.getString(2); @@ -566,10 +565,11 @@ public class UserInitializer { } if (passwort == null) passwort = "dummy"; // bei LDAP oder so - // MB LDAP Provisorium für kern4.9 + boolean isPasswordOK = false; if (isRemotePasswortCheck) { - isPasswordOK = new LdapPasswordChecker().isLdapPasswordOK(false, mandantenID, user, passwort); + isPasswordOK = new LdapPasswordChecker().isLdapPasswordOK(false, mandantenID, user, passwort); + } else { String encoded_sha = CryptUtils.encodeSHA(passwort); String encoded_sha2 = CryptUtils.encodeSHA(passwort + CryptUtils.geheimnis1); diff --git a/superx/WEB-INF/http_get_masken_blacklist.txt b/superx/WEB-INF/http_get_masken_blacklist.txt new file mode 100644 index 0000000..5b190e6 --- /dev/null +++ b/superx/WEB-INF/http_get_masken_blacklist.txt @@ -0,0 +1,63 @@ +# Hier stehen die tid's von Masken, die nicht über HTTP GET aufgerufen werden können, +# weil sie hier für "Cross Site Request Forgery" anfällig sind. +# Format der Datei: +# Kommentare beginnen mit "#" als erstes Zeichen in der Zeile +# eine Masken-tid pro Zeile. +# Um die Blacklist um eigene Einträge zu erweitern, bitte eine Datei 'http_get_masken_blacklist_custom.txt' +# parallel anlegen - nicht die Originaldatei ändern, da diese bei Releaseupdates überschrieben wird. +# Wenn im selben Verzeichnis von 'http_get_masken_blacklist.txt' eine Datei +# 'http_get_masken_whitelist.txt' in demselben Format hinterlegt ist, dann ändert +# sich die Logik: +# Statt Sperrens der Masken aus 'http_get_masken_blacklist.txt' werden dann _alle_ +# Masken außer denen aus 'http_get_masken_whitelist.txt' für HTTP GET Aufrufe gesperrt. + +# Maske: Feld kopieren +70630 +# Maske: Feld löschen +70620 +# Maske: Maske kopieren +70350 +# Maske: Maske löschen +70370 +# Maske: Tabelle hochladen (CSV) +71240 +# Maske: Datensieb erstellen +71520 +# Maske: Gastzugang einrichten +71770 +# Maske: Ladejob ausführen +71540 +# Maske: Organigrammquelle bearbeiten +71480 +# Maske: User einrichten +70970 +# Maske: User löschen +70990 +# Maske: Kamerale Rechte Massenimport +23160 +# Maske: Flächendaten anzeigen/einfrieren +10300 +# Maske: Dokument hochladen +32320 +# Maske: Grunddaten und Kennzahlen hinzufügen (Datei) +32200 +# Maske: Grunddaten und Kennzahlen hinzufügen (csv) +18240 +# Maske: Primärbuchungen laden +17200 +# Maske: Daten hinzufügen (CSV) +888880210 +# Maske: Managementbericht kopieren +888880560 +# Maske: Personalmodul für SAP-HR vorbereiten +19910 +# Maske: CNW erzeugen +25160 +# Maske: LDS Tabelle hochladen +25600 +# Maske: Studiengangs-Merkmale übertragen +25520 +# Maske: Prüfungen Gewichtungsvorschau +160240 +# Maske: Studierende Gewichtungsvorschau +160200 \ No newline at end of file diff --git a/superx/WEB-INF/http_get_masken_whitelist_vorlage.txt b/superx/WEB-INF/http_get_masken_whitelist_vorlage.txt new file mode 100644 index 0000000..c799f81 --- /dev/null +++ b/superx/WEB-INF/http_get_masken_whitelist_vorlage.txt @@ -0,0 +1,497 @@ +# Diese Datei dient als Konfigurationsvorlage, um den Zugriff auf Masken über HTTP GET mittels einer Freigabeliste zu steuern. +# Sie enthält die IDs aller in den Quelldateien der Version 2023.06 zur Entwicklungszeit vorhandenen Masken, für die HTTP GET +# per default erlaubt ist. +950 +10010 +10250 +10260 +10270 +10280 +10320 +10340 +10360 +10380 +10400 +10420 +10440 +11300 +11310 +11320 +11420 +11430 +11460 +11690 +11910 +11980 +11990 +12000 +16000 +16020 +16040 +16060 +16080 +16100 +16120 +16140 +16160 +16180 +16200 +16220 +16240 +16260 +16280 +16300 +16320 +16340 +16360 +16380 +16400 +16420 +16430 +16450 +16470 +16490 +16510 +16530 +16550 +16570 +16590 +16610 +16630 +16650 +16670 +16690 +16710 +16730 +16770 +16790 +16830 +16850 +16890 +16910 +17000 +17010 +17020 +17030 +17050 +17070 +17090 +17110 +17130 +17140 +17160 +17180 +17220 +17240 +18000 +18020 +18040 +18060 +18080 +18100 +18120 +18140 +18160 +18180 +18200 +18220 +18260 +18280 +18320 +18340 +18350 +18360 +18380 +18400 +18420 +18440 +18460 +18480 +18500 +18520 +18540 +18560 +18580 +18600 +18620 +18640 +18660 +18680 +18700 +18720 +18740 +18760 +18780 +18800 +18820 +18840 +18860 +18880 +18900 +18920 +18940 +18960 +18980 +19000 +19020 +19040 +19060 +19100 +19120 +19140 +19160 +19180 +19200 +19220 +19240 +19260 +19280 +19300 +19320 +19340 +19360 +19380 +19400 +19420 +19440 +19460 +19480 +19500 +19530 +19550 +19570 +19580 +19620 +19660 +19680 +19720 +19750 +19770 +19790 +19810 +19830 +19850 +19870 +19890 +21000 +21100 +21500 +21600 +21900 +22500 +22600 +22700 +23000 +23030 +23050 +23070 +23090 +23100 +23110 +23120 +23140 +23150 +23170 +23190 +23210 +23230 +23250 +23270 +23290 +23300 +23310 +23330 +23350 +23370 +23390 +23410 +23430 +23450 +23470 +23490 +23510 +23530 +23550 +23570 +23590 +23610 +23630 +23650 +23670 +23690 +23710 +23730 +23750 +23850 +23880 +23900 +23920 +23940 +23960 +24000 +24010 +24020 +24030 +24040 +24050 +24060 +24070 +24080 +24100 +24110 +24120 +24130 +24200 +25000 +25020 +25040 +25060 +25080 +25100 +25120 +25140 +25180 +25200 +25220 +25240 +25260 +25280 +25300 +25320 +25340 +25360 +25380 +25400 +25420 +25440 +25460 +25480 +25500 +25540 +25560 +25620 +25640 +26000 +26020 +26040 +26060 +26100 +27000 +27030 +27050 +27110 +29000 +29020 +29040 +29060 +30000 +30020 +30060 +30080 +30110 +30140 +30160 +30190 +32000 +32020 +32040 +32060 +32080 +32100 +32120 +32140 +32160 +32180 +32220 +32240 +32260 +32280 +32300 +32340 +32360 +32380 +32400 +32420 +32440 +32460 +32480 +32500 +32520 +32540 +32560 +33000 +33040 +33060 +33080 +33100 +33120 +33140 +33160 +33180 +33200 +33220 +33230 +34000 +34020 +39020 +39040 +39100 +39120 +39140 +39160 +39180 +39240 +39320 +39360 +39380 +41000 +41020 +41040 +41060 +41080 +41100 +41130 +42000 +44410 +70060 +70160 +70170 +70510 +70570 +70600 +71000 +71010 +71030 +71040 +71050 +71080 +71090 +71100 +71120 +71160 +71180 +71190 +71200 +71220 +71260 +71280 +71300 +71320 +71340 +71360 +71380 +71400 +71410 +71420 +71440 +71460 +71500 +71560 +71580 +71600 +71620 +71640 +71660 +71680 +71800 +71820 +160320 +160340 +160360 +160400 +160440 +160480 +160500 +160520 +160580 +160600 +160620 +160640 +600000 +600020 +600040 +600080 +610040 +5770000 +8110060 +10400000 +12410220 +12410240 +15800010 +15800030 +15800090 +15800190 +15800210 +15801400 +67510260 +68500000 +109001370 +109001390 +109001870 +109001910 +109001930 +109001990 +109002010 +109002030 +124080000 +124080020 +124080040 +124080060 +124080080 +124080100 +124080120 +124080140 +124080160 +124080220 +124080240 +124080260 +124080320 +124080360 +124080460 +124080480 +124080500 +124080520 +124080540 +124080560 +124080580 +124080600 +124080620 +124080640 +124080660 +124080680 +124080700 +124080720 +124080740 +124081120 +124081140 +124081160 +124081170 +124081180 +124081200 +675116160 +888880190 +888880230 +888880239 +888880250 +888880270 +888880290 +888880310 +888880330 +888880350 +888880390 +888880410 +888880520 +888880540 +888880580 +888881190 +888881230 +888881250 +888881270 +888881290 +888881310 +888881330 +888881350 +888881390 +888881410 +888881430 +888881450 diff --git a/superx/WEB-INF/lib/superx5.0.jar b/superx/WEB-INF/lib/superx5.0.jar index 209a442..cd25f08 100644 Binary files a/superx/WEB-INF/lib/superx5.0.jar and b/superx/WEB-INF/lib/superx5.0.jar differ