From d0c59a890be350ff1c39901e7fa94bf68c048065 Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 28 Jan 2014 16:05:21 +0100 Subject: URL Whitelist + Basic Design --- .../gv/egiz/pdfas/web/config/WebConfiguration.java | 60 +++++++++++++++- .../web/exception/PdfAsSecurityLayerException.java | 14 ++++ .../at/gv/egiz/pdfas/web/helper/PdfAsHelper.java | 1 - .../gv/egiz/pdfas/web/helper/RemotePDFFetcher.java | 26 ++++--- .../gv/egiz/pdfas/web/servlets/DataURLServlet.java | 22 ++++-- .../at/gv/egiz/pdfas/web/servlets/ErrorPage.java | 14 ++-- .../egiz/pdfas/web/servlets/ProvidePDFServlet.java | 14 +++- .../webapp/WEB-INF/decorators/default_layout.jsp | 43 +++++------ pdf-as-web/src/main/webapp/index.jsp | 84 +++++++++++----------- 9 files changed, 190 insertions(+), 88 deletions(-) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java (limited to 'pdf-as-web') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java index 6609e51d..c7520347 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java @@ -2,6 +2,9 @@ package at.gv.egiz.pdfas.web.config; import java.io.File; import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Properties; import org.slf4j.Logger; @@ -24,12 +27,21 @@ public class WebConfiguration { public static final String KEYSTORE_ALIAS = "ks.key.alias"; public static final String KEYSTORE_KEY_PASS = "ks.key.pass"; + public static final String WHITELIST_ENABLED = "whitelist.enabled"; + public static final String WHITELIST_VALUE_PRE = "whitelist.url."; + private static Properties properties = new Properties(); private static final Logger logger = LoggerFactory .getLogger(WebConfiguration.class); + private static List whiteListregEx = new ArrayList(); + public static void configure(String config) { + + properties.clear(); + whiteListregEx.clear(); + try { properties.load(new FileInputStream(config)); } catch(Exception e) { @@ -37,6 +49,23 @@ public class WebConfiguration { throw new RuntimeException(e); } + if(isWhiteListEnabled()) { + Iterator keyIt = properties.keySet().iterator(); + while(keyIt.hasNext()) { + Object keyObj = keyIt.next(); + if(keyObj != null) { + String key = keyObj.toString(); + if(key.startsWith(WHITELIST_VALUE_PRE)) { + String whitelist_expr = properties.getProperty(key); + if(whitelist_expr != null) { + whiteListregEx.add(whitelist_expr); + logger.debug("URL Whitelist: " + whitelist_expr); + } + } + } + } + } + String pdfASDir = getPdfASDir(); if(pdfASDir == null) { logger.error("Please configure pdf as working directory in the web configuration"); @@ -107,9 +136,34 @@ public class WebConfiguration { } return false; } - - public static boolean isProvidePdfURLinWhitelist(String url) { - //TODO implement whitelisting for pdfURLS + + public static boolean isWhiteListEnabled() { + String value = properties.getProperty(WHITELIST_ENABLED); + if(value != null) { + if(value.equals("true")) { + return true; + } + } return false; } + + public static synchronized boolean isProvidePdfURLinWhitelist(String url) { + if(isWhiteListEnabled()) { + + Iterator patterns = whiteListregEx.iterator(); + while(patterns.hasNext()) { + String pattern = patterns.next(); + try { + if(url.matches(pattern)) { + return true; + } + } catch(Throwable e) { + logger.error("Error in matching regex: " + pattern, e); + } + } + + return false; + } + return true; + } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java new file mode 100644 index 00000000..e499302d --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java @@ -0,0 +1,14 @@ +package at.gv.egiz.pdfas.web.exception; + +public class PdfAsSecurityLayerException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -4632774270754873043L; + + public PdfAsSecurityLayerException(String info, int errorcode) { + super("SecurityLayer Error: [" + errorcode + "] " + info); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java index 2f62269b..1059738e 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java @@ -76,7 +76,6 @@ public class PdfAsHelper { private static ObjectFactory of = new ObjectFactory(); static { - // TODO: read from config file logger.debug("Creating PDF-AS"); pdfAs = PdfAsFactory.createPdfAs(new File(WebConfiguration.getPdfASDir())); logger.debug("Creating PDF-AS done"); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java index 9532e074..cb404b66 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java @@ -5,6 +5,7 @@ import java.net.MalformedURLException; import java.net.URL; import at.gv.egiz.pdfas.common.utils.StreamUtils; +import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.exception.PdfAsWebException; public class RemotePDFFetcher { @@ -16,16 +17,25 @@ public class RemotePDFFetcher { } catch (MalformedURLException e) { throw new PdfAsWebException("Not a valid URL!", e); } - if(url.getProtocol().equals("http") || url.getProtocol().equals("https")) { - - try { - InputStream is = url.openStream(); - return StreamUtils.inputStreamToByteArray(is); - } catch (Exception e) { - throw new PdfAsWebException("Failed to fetch pdf document!", e); + if (WebConfiguration.isProvidePdfURLinWhitelist(url.toExternalForm())) { + if (url.getProtocol().equals("http") + || url.getProtocol().equals("https")) { + + try { + InputStream is = url.openStream(); + return StreamUtils.inputStreamToByteArray(is); + } catch (Exception e) { + throw new PdfAsWebException( + "Failed to fetch pdf document!", e); + } + } else { + throw new PdfAsWebException( + "Failed to fetch pdf document protocol " + + url.getProtocol() + " is not supported"); } } else { - throw new PdfAsWebException("Failed to fetch pdf document protocol " + url.getProtocol() + " is not supported"); + throw new PdfAsWebException( + "Failed to fetch pdf document " + url.toExternalForm() + " is not allowed"); } } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java index a0fe3e80..7847d840 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java @@ -6,10 +6,12 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import javax.xml.bind.JAXBElement; -import at.gv.egiz.pdfas.lib.api.StatusRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.web.exception.PdfAsSecurityLayerException; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.sl.CreateCMSSignatureResponseType; import at.gv.egiz.sl.ErrorResponseType; @@ -22,6 +24,9 @@ import at.gv.egiz.sl.util.SLMarschaller; public class DataURLServlet extends HttpServlet { private static final long serialVersionUID = 1L; + private static final Logger logger = LoggerFactory + .getLogger(DataURLServlet.class); + /** * @see HttpServlet#HttpServlet() */ @@ -64,11 +69,18 @@ public class DataURLServlet extends HttpServlet { PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType, getServletContext()); } else if(jaxbObject.getValue() instanceof ErrorResponseType) { ErrorResponseType errorResponseType = (ErrorResponseType)jaxbObject.getValue(); - // TODO: store error and redirect user - System.out.println("ERROR: " + errorResponseType.getErrorCode() + " " + errorResponseType.getInfo()); + logger.error("SecurityLayer: " + errorResponseType.getErrorCode() + " " + errorResponseType.getInfo()); + throw new PdfAsSecurityLayerException(errorResponseType.getInfo(), + errorResponseType.getErrorCode()); + + } else { + throw new PdfAsSecurityLayerException("Unknown SL response", + 9999); } } catch (Exception e) { - e.printStackTrace(); + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java index fe436566..ef8e058f 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java @@ -8,9 +8,9 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.swing.text.html.HTML; -import org.apache.commons.lang3.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.helper.HTMLFormater; @@ -21,7 +21,10 @@ import at.gv.egiz.pdfas.web.helper.PdfAsHelper; */ public class ErrorPage extends HttpServlet { private static final long serialVersionUID = 1L; - + + private static final Logger logger = LoggerFactory + .getLogger(ErrorPage.class); + /** * @see HttpServlet#HttpServlet() */ @@ -61,7 +64,7 @@ public class ErrorPage extends HttpServlet { .getSessionException(request, response); String message = PdfAsHelper.getSessionErrMessage(request, response); - if (errorURL != null) { + if (errorURL != null && WebConfiguration.isProvidePdfURLinWhitelist(errorURL)) { String template = PdfAsHelper.getErrorRedirectTemplateSL(); template = template.replace("##ERROR_URL##", errorURL); @@ -81,6 +84,9 @@ public class ErrorPage extends HttpServlet { response.getWriter().write(template); response.getWriter().close(); } else { + if(!WebConfiguration.isProvidePdfURLinWhitelist(errorURL)) { + logger.warn(errorURL + " is not allowed by whitelist"); + } response.setContentType("text/html"); PrintWriter pw = response.getWriter(); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java index e1387fce..194a9a63 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java @@ -8,7 +8,11 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; /** @@ -17,6 +21,9 @@ import at.gv.egiz.pdfas.web.helper.PdfAsHelper; public class ProvidePDFServlet extends HttpServlet { private static final long serialVersionUID = 1L; + private static final Logger logger = LoggerFactory + .getLogger(ProvidePDFServlet.class); + /** * @see HttpServlet#HttpServlet() */ @@ -47,7 +54,12 @@ public class ProvidePDFServlet extends HttpServlet { try { String invokeURL = PdfAsHelper.getInvokeURL(request, response); - if (invokeURL == null) { + if (invokeURL == null || WebConfiguration.isProvidePdfURLinWhitelist(invokeURL)) { + + if(!WebConfiguration.isProvidePdfURLinWhitelist(invokeURL)) { + logger.warn(invokeURL + " is not allowed by whitelist"); + } + // Deliver to Browser directly! response.setContentType("text/html"); PrintWriter pw = response.getWriter(); diff --git a/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp b/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp index 1179d48c..045fd2b9 100644 --- a/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp +++ b/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp @@ -5,37 +5,28 @@ <%@page contentType="text/html; charset=UTF-8"%> - - - - - - + + + + + + - <decorator:title></decorator:title> - - - - +<decorator:title></decorator:title> + -
-
-

PDF-Signatur

-
- -
-
- -
-
+

+

PDF-Signatur

+

- +

+ +

-
- +

+

© EGIZ 2014

+

\ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/index.jsp b/pdf-as-web/src/main/webapp/index.jsp index 8aba0dff..355c7838 100644 --- a/pdf-as-web/src/main/webapp/index.jsp +++ b/pdf-as-web/src/main/webapp/index.jsp @@ -6,47 +6,51 @@
- -
has-error <% } %>"> - -

- <% if(request.getAttribute("FILEERR") != null) { %> - Bitte die zu signierende PDF Datei angeben. - <% } else { %> - Zu signierende PDF Datei - <% } %>

-
- <% if(WebConfiguration.getOnlineBKUURL() != null || - WebConfiguration.getLocalBKUURL() != null) { %> -
- - - <% if(WebConfiguration.getLocalBKUURL() != null) { %> - - <% } %> - <% if(WebConfiguration.getOnlineBKUURL() != null) { %> - - <% } %> -
- <% } %> - <% if(WebConfiguration.getHandyBKUURL() != null) { %> -
- - - -
- <% } %> - <% if(WebConfiguration.getKeystoreEnabled()) { %> -
+ + <% + if (request.getAttribute("FILEERR") != null) { + %> +

Bitte die zu signierende PDF Datei angeben.

+ <% + } + %> + + + <% + if (WebConfiguration.getLocalBKUURL() != null) { + %> + Lokale BKU + + <% + } + %> + <% + if (WebConfiguration.getOnlineBKUURL() != null) { + %> + + + <% + } + %> + <% + if (WebConfiguration.getHandyBKUURL() != null) { + %> + + + <% + } + %> + <% + if (WebConfiguration.getKeystoreEnabled()) { + %> - -
- <% } %> + id="jks">Server Keystore + <% + } + %>
\ No newline at end of file -- cgit v1.2.3