Browse Source

HTTPGET und LDAP Sicherheitspatch #283628

userinfo_gueltigkeit
Daniel Quathamer 2 years ago
parent
commit
15214edc33
  1. 38
      src/de/superx/sec/HttpGetAccessGuard.java
  2. 20
      src/de/superx/sec/HttpGetAccessListParser.java
  3. 1
      src/de/superx/servlet/RequestParameter.java
  4. 10
      src/de/superx/servlet/ServletBasics.java
  5. 33
      src/de/superx/servlet/SuperXManager.java
  6. 30
      src/de/superx/servlet/SuperXmlTabelle.java
  7. 6
      src/de/superx/servlet/UserInitializer.java
  8. 63
      superx/WEB-INF/http_get_masken_blacklist.txt
  9. 497
      superx/WEB-INF/http_get_masken_whitelist_vorlage.txt
  10. BIN
      superx/WEB-INF/lib/superx5.0.jar

38
src/de/superx/sec/HttpGetAccessGuard.java

@ -0,0 +1,38 @@
package de.superx.sec;
import java.util.Set;
public class HttpGetAccessGuard {
private Set<Integer> whitelist = null;
private Set<Integer> blacklist = null;
private Set<Integer> 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<Integer> whitelist) {
this.whitelist = whitelist;
}
public void setBlacklist(Set<Integer> blacklist) {
this.blacklist = blacklist;
}
public void setBlacklist_custom(Set<Integer> blacklist_custom) {
this.blacklist_custom = blacklist_custom;
}
}

20
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<Integer> parseList(String input) {
String[] lines = input.split("\n|\r");
Set<Integer> result = new TreeSet<Integer>();
for (String line : lines) {
if (line.trim().length() == 0 || line.charAt(0) == '#') {
continue;
}
Integer tid = Integer.valueOf(line.trim());
result.add(tid);
}
return result;
}
}

1
src/de/superx/servlet/RequestParameter.java

@ -423,6 +423,7 @@ public enum RequestParameter{
this.parameterString = name; this.parameterString = name;
} }
@Override
public String toString() { public String toString() {
if (parameterString == null) { if (parameterString == null) {
return super.toString(); return super.toString();

10
src/de/superx/servlet/ServletBasics.java

@ -16,6 +16,16 @@ import de.memtext.util.TimeUtils;
import de.superx.util.SqlStringUtils; import de.superx.util.SqlStringUtils;
public class ServletBasics { 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 * returns parameter from request
* @param request * @param request

33
src/de/superx/servlet/SuperXManager.java

@ -10,6 +10,7 @@ import java.sql.SQLException;
import java.text.ParseException; import java.text.ParseException;
import java.util.Date; import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Set;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -39,6 +40,8 @@ import de.memtext.util.XMLUtils;
import de.superx.common.DBServletException; import de.superx.common.DBServletException;
import de.superx.common.SxUser; import de.superx.common.SxUser;
import de.superx.common.TransletCache; import de.superx.common.TransletCache;
import de.superx.sec.HttpGetAccessGuard;
import de.superx.sec.HttpGetAccessListParser;
import de.superx.sec.InputCheckRegistry; import de.superx.sec.InputCheckRegistry;
import de.superx.util.SqlStringUtils; import de.superx.util.SqlStringUtils;
@ -64,7 +67,7 @@ public class SuperXManager extends HttpServlet {
public static boolean isSichtenCachingWanted = true; public static boolean isSichtenCachingWanted = true;
public static String sxversion="@version@"; public static String sxversion="@version@";
public static String builddatum="@sxtimestamp@"; public static String builddatum="@sxtimestamp@";
public static HttpGetAccessGuard httpGetAccessGuard;
private static final String ADMIN_ONLY = de.superx.servlet.SuperXManager.htmlPageHead("Admin-Bereich")+"<center><h3>Hier ist ein Login nur für Administratoren m&ouml;glich.</h3>(Cookies m&uuml;ssen aktiviert sein)" private static final String ADMIN_ONLY = de.superx.servlet.SuperXManager.htmlPageHead("Admin-Bereich")+"<center><h3>Hier ist ein Login nur für Administratoren m&ouml;glich.</h3>(Cookies m&uuml;ssen aktiviert sein)"
+ "<FORM ACTION=\"SuperXManager\" METHOD=\"post\"><p><p>Kennung: <br /><INPUT TYPE=\"Text\" NAME=\"kennung\" VALUE=\"superx\"></p><p><p>Passwort: <br /><INPUT TYPE=\"Password\" NAME=\"passwort\" value=\"\">" + "<FORM ACTION=\"SuperXManager\" METHOD=\"post\"><p><p>Kennung: <br /><INPUT TYPE=\"Text\" NAME=\"kennung\" VALUE=\"superx\"></p><p><p>Passwort: <br /><INPUT TYPE=\"Password\" NAME=\"passwort\" value=\"\">"
@ -561,6 +564,7 @@ public class SuperXManager extends HttpServlet {
} }
private void doInit() throws ServletException { private void doInit() throws ServletException {
initHttpGetAccessGuard();
InputCheckRegistry.registerDefaultChecks(); InputCheckRegistry.registerDefaultChecks();
his1_refapp=System.getProperty(QIS_CONTEXT); his1_refapp=System.getProperty(QIS_CONTEXT);
if(his1_refapp==null) if(his1_refapp==null)
@ -803,4 +807,31 @@ public class SuperXManager extends HttpServlet {
public static boolean isStandaloneLdapActive() { public static boolean isStandaloneLdapActive() {
return 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<Integer> 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;
}
} }

30
src/de/superx/servlet/SuperXmlTabelle.java

@ -116,6 +116,14 @@ import net.sf.jasperreports.engine.JRException;
*/ */
public class SuperXmlTabelle extends AbstractSuperXServlet { 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; private static final long serialVersionUID = 1L;
TimeUtils tutil = new TimeUtils(); TimeUtils tutil = new TimeUtils();
@ -282,20 +290,30 @@ public class SuperXmlTabelle extends AbstractSuperXServlet {
@Override @Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getParameter("bigexcel") != null && request.getParameter("bigexcel").equals("true")) { 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); BigExcelCreator b = new BigExcelCreator(request, response);
b.run(true); b.run(true);
} else if (request.getParameter(RequestParameter.checkFor.toString()) != null) {
} 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); checkFor(request, response);
} else { } else {
doPost(request, response); 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 {
// 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 * Prüft ob für Maske schon etwas zurückgeschickt wurde, Rückmeldung, wenn

6
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"); 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; if (SuperXManager.isStandaloneLdapActive()&&!"superx".equals(login)) isRemotePasswordCheck=true;
// MB Provisorium für kern4.9 alte LDAP-Technik via RemoteUser deaktiviert // MB Provisorium für kern4.9 alte LDAP-Technik via RemoteUser deaktiviert
/* /*
* if (username == null) { username = request.getRemoteUser(); // LDAP if * if (username == null) { username = request.getRemoteUser(); // LDAP if
@ -530,8 +531,6 @@ public class UserInitializer {
if (kennwortSpalte != null) if (kennwortSpalte != null)
kennwortSpalte = kennwortSpalte.trim().toLowerCase(); kennwortSpalte = kennwortSpalte.trim().toLowerCase();
if (kennwortSpalte != null && (kennwortSpalte.equals("ändern") || kennwortSpalte.equals("aendern")) 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; isPasswordChangeDemanded = true;
adminUser = new Short(rs.getShort(3)); adminUser = new Short(rs.getShort(3));
@ -566,10 +565,11 @@ public class UserInitializer {
} }
if (passwort == null) if (passwort == null)
passwort = "dummy"; // bei LDAP oder so passwort = "dummy"; // bei LDAP oder so
// MB LDAP Provisorium für kern4.9
boolean isPasswordOK = false; boolean isPasswordOK = false;
if (isRemotePasswortCheck) { if (isRemotePasswortCheck) {
isPasswordOK = new LdapPasswordChecker().isLdapPasswordOK(false, mandantenID, user, passwort); isPasswordOK = new LdapPasswordChecker().isLdapPasswordOK(false, mandantenID, user, passwort);
} else { } else {
String encoded_sha = CryptUtils.encodeSHA(passwort); String encoded_sha = CryptUtils.encodeSHA(passwort);
String encoded_sha2 = CryptUtils.encodeSHA(passwort + CryptUtils.geheimnis1); String encoded_sha2 = CryptUtils.encodeSHA(passwort + CryptUtils.geheimnis1);

63
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

497
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

BIN
superx/WEB-INF/lib/superx5.0.jar

Binary file not shown.
Loading…
Cancel
Save