You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2019/12/16 18:45:57 UTC

[lucene-solr] branch branch_8x updated: LUCENE-9094: Ban ObjectInputStream and ObjectOutputStream in forbidden-apis

This is an automated email from the ASF dual-hosted git repository.

rmuir pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/branch_8x by this push:
     new cfccbe5  LUCENE-9094: Ban ObjectInputStream and ObjectOutputStream in forbidden-apis
cfccbe5 is described below

commit cfccbe5af3526f20016872bf011e13cf519140c1
Author: Robert Muir <rm...@apache.org>
AuthorDate: Mon Dec 16 13:31:11 2019 -0500

    LUCENE-9094: Ban ObjectInputStream and ObjectOutputStream in forbidden-apis
---
 .../org/apache/lucene/analysis/cn/smart/hhmm/BigramDictionary.java   | 3 +++
 .../org/apache/lucene/analysis/cn/smart/hhmm/WordDictionary.java     | 3 +++
 .../org/apache/lucene/facet/taxonomy/writercache/CharBlockArray.java | 4 ++++
 .../src/java/org/apache/lucene/replicator/http/HttpClientBase.java   | 2 ++
 .../java/org/apache/lucene/replicator/http/ReplicationService.java   | 2 ++
 lucene/tools/forbiddenApis/base.txt                                  | 4 ++++
 .../apache/solr/analytics/stream/AnalyticsShardResponseParser.java   | 2 ++
 .../java/org/apache/solr/response/AnalyticsShardResponseWriter.java  | 2 ++
 solr/core/src/test/org/apache/solr/rest/TestManagedResource.java     | 5 +++++
 solr/solrj/src/java/org/apache/solr/client/solrj/SolrResponse.java   | 3 +++
 solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java  | 3 +++
 11 files changed, 33 insertions(+)

diff --git a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BigramDictionary.java b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BigramDictionary.java
index 11ce03b..d1140620 100644
--- a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BigramDictionary.java
+++ b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BigramDictionary.java
@@ -28,6 +28,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 
 import org.apache.lucene.analysis.cn.smart.AnalyzerProfile;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * SmartChineseAnalyzer Bigram dictionary.
@@ -85,6 +86,7 @@ class BigramDictionary extends AbstractDictionary {
     }
   }
 
+  @SuppressForbidden(reason = "TODO: fix code to serialize its own dictionary vs. a binary blob in the codebase")
   private void loadFromInputStream(InputStream serialObjectInputStream)
       throws IOException, ClassNotFoundException {
     try (ObjectInputStream input = new ObjectInputStream(serialObjectInputStream)) {
@@ -94,6 +96,7 @@ class BigramDictionary extends AbstractDictionary {
     }
   }
 
+  @SuppressForbidden(reason = "TODO: fix code to serialize its own dictionary vs. a binary blob in the codebase")
   private void saveToObj(Path serialObj) throws IOException {
     try (ObjectOutputStream output = new ObjectOutputStream(Files.newOutputStream(
         serialObj))) {
diff --git a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/WordDictionary.java b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/WordDictionary.java
index c6ba30f..deb8c81 100644
--- a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/WordDictionary.java
+++ b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/WordDictionary.java
@@ -29,6 +29,7 @@ import java.nio.file.Paths;
 
 import org.apache.lucene.analysis.cn.smart.AnalyzerProfile;
 import org.apache.lucene.analysis.cn.smart.Utility;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * SmartChineseAnalyzer Word Dictionary
@@ -146,6 +147,7 @@ class WordDictionary extends AbstractDictionary {
     }
   }
 
+  @SuppressForbidden(reason = "TODO: fix code to serialize its own dictionary vs. a binary blob in the codebase")
   private void loadFromObjectInputStream(InputStream serialObjectInputStream)
       throws IOException, ClassNotFoundException {
     try (ObjectInputStream input = new ObjectInputStream(serialObjectInputStream)) {
@@ -157,6 +159,7 @@ class WordDictionary extends AbstractDictionary {
     }
   }
 
+  @SuppressForbidden(reason = "TODO: fix code to serialize its own dictionary vs. a binary blob in the codebase")
   private void saveToObj(Path serialObj) {
     try (ObjectOutputStream output = new ObjectOutputStream(Files.newOutputStream(serialObj))) {
       output.writeObject(wordIndexTable);
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CharBlockArray.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CharBlockArray.java
index 84a0652..a2b575d 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CharBlockArray.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CharBlockArray.java
@@ -25,6 +25,8 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.lucene.util.SuppressForbidden;
+
 /**
  * Similar to {@link StringBuilder}, but with a more efficient growing strategy.
  * This class uses char array blocks to grow.
@@ -185,6 +187,7 @@ class CharBlockArray implements Appendable, Serializable, CharSequence {
     return sb.toString();
   }
 
+  @SuppressForbidden(reason = "TODO: don't use java serialization here, inefficient and unnecessary")
   void flush(OutputStream out) throws IOException {
     ObjectOutputStream oos = null;
     try {
@@ -198,6 +201,7 @@ class CharBlockArray implements Appendable, Serializable, CharSequence {
     }
   }
 
+  @SuppressForbidden(reason = "TODO: don't use java serialization here, inefficient and unnecessary")
   public static CharBlockArray open(InputStream in) throws IOException, ClassNotFoundException {
     ObjectInputStream ois = null;
     try {
diff --git a/lucene/replicator/src/java/org/apache/lucene/replicator/http/HttpClientBase.java b/lucene/replicator/src/java/org/apache/lucene/replicator/http/HttpClientBase.java
index cbce590..9a5713b 100644
--- a/lucene/replicator/src/java/org/apache/lucene/replicator/http/HttpClientBase.java
+++ b/lucene/replicator/src/java/org/apache/lucene/replicator/http/HttpClientBase.java
@@ -37,6 +37,7 @@ import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.util.EntityUtils;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * Base class for Http clients.
@@ -115,6 +116,7 @@ public abstract class HttpClientBase implements Closeable {
     }
   }
   
+  @SuppressForbidden(reason = "XXX: security hole")
   protected void throwKnownError(HttpResponse response, StatusLine statusLine) throws IOException {
     ObjectInputStream in = null;
     try {
diff --git a/lucene/replicator/src/java/org/apache/lucene/replicator/http/ReplicationService.java b/lucene/replicator/src/java/org/apache/lucene/replicator/http/ReplicationService.java
index 39cd994..880a18e 100644
--- a/lucene/replicator/src/java/org/apache/lucene/replicator/http/ReplicationService.java
+++ b/lucene/replicator/src/java/org/apache/lucene/replicator/http/ReplicationService.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.http.HttpStatus;
 import org.apache.lucene.replicator.Replicator;
 import org.apache.lucene.replicator.SessionToken;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * A server-side service for handling replication requests. The service assumes
@@ -129,6 +130,7 @@ public class ReplicationService {
   }
   
   /** Executes the replication task. */
+  @SuppressForbidden(reason = "XXX: security hole")
   public void perform(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     String[] pathElements = getPathElements(req);
     
diff --git a/lucene/tools/forbiddenApis/base.txt b/lucene/tools/forbiddenApis/base.txt
index 0a81d03..1e9a706 100644
--- a/lucene/tools/forbiddenApis/base.txt
+++ b/lucene/tools/forbiddenApis/base.txt
@@ -58,3 +58,7 @@ java.lang.Float#<init>(double)
 java.lang.Float#<init>(java.lang.String)
 java.lang.Double#<init>(double)
 java.lang.Double#<init>(java.lang.String)
+
+@defaultMessage Java deserialization is unsafe when the data is untrusted. The java developer is powerless: no checks or casts help, exploitation can happen in places such as clinit or finalize!
+java.io.ObjectInputStream
+java.io.ObjectOutputStream
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardResponseParser.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardResponseParser.java
index 2378fa7..98cabef 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardResponseParser.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardResponseParser.java
@@ -16,6 +16,7 @@
  */
 package org.apache.solr.analytics.stream;
 
+import org.apache.lucene.util.SuppressForbidden;
 import org.apache.solr.analytics.AnalyticsRequestManager;
 import org.apache.solr.client.solrj.ResponseParser;
 import org.apache.solr.common.SolrException;
@@ -54,6 +55,7 @@ public class AnalyticsShardResponseParser extends ResponseParser {
   }
 
   @Override
+  @SuppressForbidden(reason = "XXX: security hole")
   public NamedList<Object> processResponse(InputStream body, String encoding) {
     DataInputStream input = new DataInputStream(body);
     //check to see if the response is an exception
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/response/AnalyticsShardResponseWriter.java b/solr/contrib/analytics/src/java/org/apache/solr/response/AnalyticsShardResponseWriter.java
index 04d571a..67a71d0 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/response/AnalyticsShardResponseWriter.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/response/AnalyticsShardResponseWriter.java
@@ -22,6 +22,7 @@ import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.Writer;
 
+import org.apache.lucene.util.SuppressForbidden;
 import org.apache.solr.analytics.AnalyticsRequestManager;
 import org.apache.solr.analytics.stream.AnalyticsShardResponseParser;
 import org.apache.solr.client.solrj.impl.BinaryResponseParser;
@@ -78,6 +79,7 @@ public class AnalyticsShardResponseWriter implements BinaryQueryResponseWriter {
       this.requestSuccessful = false;
     }
 
+    @SuppressForbidden(reason = "XXX: security hole")
     public void write(DataOutputStream output) throws IOException {
       output.writeBoolean(requestSuccessful);
       if (requestSuccessful) {
diff --git a/solr/core/src/test/org/apache/solr/rest/TestManagedResource.java b/solr/core/src/test/org/apache/solr/rest/TestManagedResource.java
index 61cbf8b..2c2aeb6 100644
--- a/solr/core/src/test/org/apache/solr/rest/TestManagedResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/TestManagedResource.java
@@ -31,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.SuppressForbidden;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
@@ -120,12 +121,14 @@ public class TestManagedResource extends SolrTestCaseJ4 {
   /**
    * Implements a Java serialization based storage format.
    */
+  @SuppressForbidden(reason = "XXX: security hole")
   private static class SerializableStorage extends ManagedResourceStorage {
     
     SerializableStorage(StorageIO storageIO, SolrResourceLoader loader) {
       super(storageIO, loader);
     }
 
+    @SuppressForbidden(reason = "XXX: security hole")
     @Override
     public Object load(String resourceId) throws IOException {
       String storedId = getStoredResourceId(resourceId);
@@ -151,6 +154,7 @@ public class TestManagedResource extends SolrTestCaseJ4 {
       return serialized;      
     }
 
+    @SuppressForbidden(reason = "XXX: security hole")
     @Override
     public void store(String resourceId, Object toStore) throws IOException {
       if (!(toStore instanceof Serializable))
@@ -305,6 +309,7 @@ public class TestManagedResource extends SolrTestCaseJ4 {
   /**
    * Converts the given Serializable object to bytes
    */
+  @SuppressForbidden(reason = "XXX: security hole")
   private BytesRef ser2bytes(Serializable ser) throws Exception {
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     ObjectOutputStream oos = null;
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrResponse.java b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrResponse.java
index 73eb863..f267755 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrResponse.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrResponse.java
@@ -27,6 +27,7 @@ import org.apache.solr.common.MapWriter;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SuppressForbidden;
 
 
 /**
@@ -60,6 +61,7 @@ public abstract class SolrResponse implements Serializable, MapWriter {
     return new SolrException(errorCode, (String)exp.get("msg"));
   }
   
+  @SuppressForbidden(reason = "XXX: security hole")
   public static byte[] serializable(SolrResponse response) {
     try {
       ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
@@ -71,6 +73,7 @@ public abstract class SolrResponse implements Serializable, MapWriter {
     }
   }
   
+  @SuppressForbidden(reason = "XXX: security hole")
   public static SolrResponse deserialize(byte[] bytes) {
     try {
       ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java
index 365f2c8..6a92199 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java
@@ -26,6 +26,8 @@ import java.util.Locale;
 import java.util.TimeZone;
 
 import junit.framework.Assert;
+
+import org.apache.lucene.util.SuppressForbidden;
 import org.apache.solr.SolrTestCase;
 import org.apache.solr.client.solrj.SolrQuery.SortClause;
 import org.apache.solr.common.params.CommonParams;
@@ -180,6 +182,7 @@ public class SolrQueryTest extends SolrTestCase {
   /*
    * Verifies the symbolic sort operations
    */
+  @SuppressForbidden(reason = "XXX: security hole")
   public void testSort() throws IOException {
 
     SolrQuery q = new SolrQuery("dog");