Browse Source

fix #1009 add referer check

Shinsuke Sugaya 7 years ago
parent
commit
f59290f336

+ 0 - 1
src/main/java/org/codelibs/fess/api/BaseApiManager.java

@@ -93,5 +93,4 @@ public abstract class BaseApiManager implements WebApiManager {
             throw new IORuntimeException(e);
             throw new IORuntimeException(e);
         }
         }
     }
     }
-
 }
 }

+ 7 - 1
src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java

@@ -72,9 +72,15 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
 
 
     @Override
     @Override
     public boolean matches(final HttpServletRequest request) {
     public boolean matches(final HttpServletRequest request) {
-        if (!ComponentUtil.getFessConfig().isWebApiGsa()) {
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        if (!fessConfig.isWebApiGsa()) {
             return false;
             return false;
         }
         }
+
+        if (!fessConfig.isAcceptedSearchReferer(request)) {
+            return false;
+        }
+
         final String servletPath = request.getServletPath();
         final String servletPath = request.getServletPath();
         return servletPath.startsWith(gsaPathPrefix);
         return servletPath.startsWith(gsaPathPrefix);
     }
     }

+ 14 - 1
src/main/java/org/codelibs/fess/api/json/JsonApiManager.java

@@ -71,7 +71,20 @@ public class JsonApiManager extends BaseJsonApiManager {
 
 
     @Override
     @Override
     public boolean matches(final HttpServletRequest request) {
     public boolean matches(final HttpServletRequest request) {
-        if (!ComponentUtil.getFessConfig().isWebApiJson()) {
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        if (!fessConfig.isWebApiJson()) {
+            final String formatType = request.getParameter("type");
+            switch (getFormatType(formatType)) {
+            case SEARCH:
+            case LABEL:
+            case POPULARWORD:
+                return false;
+            default:
+                break;
+            }
+        }
+
+        if (!fessConfig.isAcceptedSearchReferer(request)) {
             return false;
             return false;
         }
         }
 
 

+ 5 - 0
src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java

@@ -38,6 +38,7 @@ import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
 import org.codelibs.fess.exception.InvalidAccessTokenException;
 import org.codelibs.fess.exception.InvalidAccessTokenException;
 import org.codelibs.fess.helper.RoleQueryHelper;
 import org.codelibs.fess.helper.RoleQueryHelper;
 import org.codelibs.fess.helper.SuggestHelper;
 import org.codelibs.fess.helper.SuggestHelper;
+import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.suggest.entity.SuggestItem;
 import org.codelibs.fess.suggest.entity.SuggestItem;
 import org.codelibs.fess.suggest.request.suggest.SuggestRequestBuilder;
 import org.codelibs.fess.suggest.request.suggest.SuggestRequestBuilder;
 import org.codelibs.fess.suggest.request.suggest.SuggestResponse;
 import org.codelibs.fess.suggest.request.suggest.SuggestResponse;
@@ -54,6 +55,10 @@ public class SuggestApiManager extends BaseJsonApiManager {
 
 
     @Override
     @Override
     public boolean matches(final HttpServletRequest request) {
     public boolean matches(final HttpServletRequest request) {
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        if (!fessConfig.isAcceptedSearchReferer(request)) {
+            return false;
+        }
         final String servletPath = request.getServletPath();
         final String servletPath = request.getServletPath();
         return servletPath.startsWith(pathPrefix);
         return servletPath.startsWith(pathPrefix);
     }
     }

+ 1 - 1
src/main/java/org/codelibs/fess/helper/QueryHelper.java

@@ -15,8 +15,8 @@
  */
  */
 package org.codelibs.fess.helper;
 package org.codelibs.fess.helper;
 
 
-import static org.codelibs.core.stream.StreamUtil.stream;
 import static org.codelibs.core.stream.StreamUtil.split;
 import static org.codelibs.core.stream.StreamUtil.split;
+import static org.codelibs.core.stream.StreamUtil.stream;
 
 
 import java.lang.Character.UnicodeBlock;
 import java.lang.Character.UnicodeBlock;
 import java.util.ArrayList;
 import java.util.ArrayList;

+ 27 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -157,6 +157,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. Radmin-api */
     /** The key of the configuration. e.g. Radmin-api */
     String API_ADMIN_ACCESS_PERMISSIONS = "api.admin.access.permissions";
     String API_ADMIN_ACCESS_PERMISSIONS = "api.admin.access.permissions";
 
 
+    /** The key of the configuration. e.g.  */
+    String API_SEARCH_ACCEPT_REFERERS = "api.search.accept.referers";
+
     /** The key of the configuration. e.g.  */
     /** The key of the configuration. e.g.  */
     String VIRTUAL_HOST_HEADERS = "virtual.host.headers";
     String VIRTUAL_HOST_HEADERS = "virtual.host.headers";
 
 
@@ -1630,6 +1633,21 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
      */
     String getApiAdminAccessPermissions();
     String getApiAdminAccessPermissions();
 
 
+    /**
+     * Get the value for the key 'api.search.accept.referers'. <br>
+     * The value is, e.g.  <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getApiSearchAcceptReferers();
+
+    /**
+     * Get the value for the key 'api.search.accept.referers' as {@link Integer}. <br>
+     * The value is, e.g.  <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     * @throws NumberFormatException When the property is not integer.
+     */
+    Integer getApiSearchAcceptReferersAsInteger();
+
     /**
     /**
      * Get the value for the key 'virtual.host.headers'. <br>
      * Get the value for the key 'virtual.host.headers'. <br>
      * The value is, e.g.  <br>
      * The value is, e.g.  <br>
@@ -5662,6 +5680,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return get(FessConfig.API_ADMIN_ACCESS_PERMISSIONS);
             return get(FessConfig.API_ADMIN_ACCESS_PERMISSIONS);
         }
         }
 
 
+        public String getApiSearchAcceptReferers() {
+            return get(FessConfig.API_SEARCH_ACCEPT_REFERERS);
+        }
+
+        public Integer getApiSearchAcceptReferersAsInteger() {
+            return getAsInteger(FessConfig.API_SEARCH_ACCEPT_REFERERS);
+        }
+
         public String getVirtualHostHeaders() {
         public String getVirtualHostHeaders() {
             return get(FessConfig.VIRTUAL_HOST_HEADERS);
             return get(FessConfig.VIRTUAL_HOST_HEADERS);
         }
         }
@@ -7786,6 +7812,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             defaultMap.put(FessConfig.API_ACCESS_TOKEN_REQUIRED, "false");
             defaultMap.put(FessConfig.API_ACCESS_TOKEN_REQUIRED, "false");
             defaultMap.put(FessConfig.API_ACCESS_TOKEN_REQUEST_PARAMETER, "");
             defaultMap.put(FessConfig.API_ACCESS_TOKEN_REQUEST_PARAMETER, "");
             defaultMap.put(FessConfig.API_ADMIN_ACCESS_PERMISSIONS, "Radmin-api");
             defaultMap.put(FessConfig.API_ADMIN_ACCESS_PERMISSIONS, "Radmin-api");
+            defaultMap.put(FessConfig.API_SEARCH_ACCEPT_REFERERS, "");
             defaultMap.put(FessConfig.VIRTUAL_HOST_HEADERS, "");
             defaultMap.put(FessConfig.VIRTUAL_HOST_HEADERS, "");
             defaultMap.put(FessConfig.HTTP_PROXY_HOST, "");
             defaultMap.put(FessConfig.HTTP_PROXY_HOST, "");
             defaultMap.put(FessConfig.HTTP_PROXY_PORT, "8080");
             defaultMap.put(FessConfig.HTTP_PROXY_PORT, "8080");

+ 29 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java

@@ -43,6 +43,7 @@ import java.util.stream.Stream;
 
 
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttribute;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSession;
 
 
 import org.codelibs.core.exception.ClassNotFoundRuntimeException;
 import org.codelibs.core.exception.ClassNotFoundRuntimeException;
@@ -72,6 +73,8 @@ import org.lastaflute.web.validation.theme.typed.LongTypeValidator;
 
 
 public interface FessProp {
 public interface FessProp {
 
 
+    public static final String API_SEARCH_ACCEPT_REFERERS = "apiSearchAcceptReferers";
+
     public static final String QUERY_GSA_RESPONSE_FIELDS = "queryGsaResponseFields";
     public static final String QUERY_GSA_RESPONSE_FIELDS = "queryGsaResponseFields";
 
 
     public static final String THUMBNAIL_HTML_IMAGE_EXCLUDE_EXTENSIONS = "ThumbnailHtmlImageExcludeExtensions";
     public static final String THUMBNAIL_HTML_IMAGE_EXCLUDE_EXTENSIONS = "ThumbnailHtmlImageExcludeExtensions";
@@ -1762,4 +1765,30 @@ public interface FessProp {
         return gsaResponseFieldSet.contains(name.toLowerCase(Locale.ROOT));
         return gsaResponseFieldSet.contains(name.toLowerCase(Locale.ROOT));
     }
     }
 
 
+    String getApiSearchAcceptReferers();
+
+    public default boolean isAcceptedSearchReferer(final HttpServletRequest request) {
+        Pattern[] patterns = (Pattern[]) propMap.get(API_SEARCH_ACCEPT_REFERERS);
+        if (patterns == null) {
+            final String refs = getApiSearchAcceptReferers();
+            if (StringUtil.isBlank(refs)) {
+                patterns = new Pattern[0];
+            } else {
+                patterns =
+                        split(refs, "\n").get(
+                                stream -> stream.filter(StringUtil::isNotBlank).map(s -> Pattern.compile(s.trim()))
+                                        .toArray(n -> new Pattern[n]));
+            }
+            propMap.put(API_SEARCH_ACCEPT_REFERERS, patterns);
+        }
+        if (patterns.length == 0) {
+            return true;
+        }
+
+        final String referer = request.getHeader("referer");
+        if (referer == null) {
+            return false;
+        }
+        return Arrays.stream(patterns).anyMatch(p -> p.matcher(referer).matches());
+    }
 }
 }

+ 1 - 0
src/main/resources/fess_config.properties

@@ -98,6 +98,7 @@ api.access.token.length=60
 api.access.token.required=false
 api.access.token.required=false
 api.access.token.request.parameter=
 api.access.token.request.parameter=
 api.admin.access.permissions=Radmin-api
 api.admin.access.permissions=Radmin-api
+api.search.accept.referers=
 
 
 # Virtual Host: Host:fess.codelibs.org=fess
 # Virtual Host: Host:fess.codelibs.org=fess
 virtual.host.headers=
 virtual.host.headers=