Merge pull request #85 from jenkinsci-cert/security-371-staplerproxy

[SECURITY-371] Secure all administrative monitors

@@ -34,8 +34,12 @@
 import java.io.IOException;

 import jenkins.model.Jenkins;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.NoExternalUse;
+import org.kohsuke.stapler.StaplerProxy;
 import org.kohsuke.stapler.StaplerRequest;
 import org.kohsuke.stapler.StaplerResponse;
+import org.kohsuke.stapler.interceptor.RequirePOST;

 /**
  * Checks the health of a subsystem of Jenkins and if there's something
@@ -75,7 +79,7 @@
  * @see Jenkins#administrativeMonitors
  */
 @LegacyInstancesAreScopedToHudson
-public abstract class AdministrativeMonitor extends AbstractModelObject implements ExtensionPoint {
+public abstract class AdministrativeMonitor extends AbstractModelObject implements ExtensionPoint, StaplerProxy {
     /**
      * Human-readable ID of this monitor, which needs to be unique within the system.
      *
@@ -143,12 +147,21 @@ public boolean isEnabled() {
     /**
      * URL binding to disable this monitor.
      */
+    @RequirePOST
     public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOException {
-        Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
         disable(true);
         rsp.sendRedirect2(req.getContextPath()+"/manage");
     }

+    /**
+     * Requires ADMINISTER permission for any operation in here.
+     */
+    @Restricted(NoExternalUse.class)
+    public Object getTarget() {
+        Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
+        return this;
+    }
+
     /**
      * All registered {@link AdministrativeMonitor} instances.
      */


Merge pull request #95 from jenkinsci-cert/SECURITY-353

[SECURITY-353] Persisted XSS in parameter definition names and value descriptions

@@ -31,11 +31,16 @@
 import hudson.tasks.BuildWrapper;
 import hudson.tasks.Builder;
 import hudson.util.VariableResolver;
+import java.io.IOException;

 import java.io.Serializable;
 import java.util.Map;
+import java.util.logging.Logger;
+import jenkins.model.Jenkins;

 import net.sf.json.JSONObject;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.DoNotUse;

 import org.kohsuke.stapler.StaplerRequest;
 import org.kohsuke.stapler.export.Exported;
@@ -70,6 +75,9 @@
  */
 @ExportedBean(defaultVisibility=3)
 public abstract class ParameterValue implements Serializable {
+
+    private static final Logger LOGGER = Logger.getLogger(ParameterValue.class.getName());
+
     protected final String name;

     private String description;
@@ -91,6 +99,16 @@ public void setDescription(String description) {
         this.description = description;
     }

+    @Restricted(DoNotUse.class) // for value.jelly
+    public String getFormattedDescription() {
+        try {
+            return Jenkins.getInstance().getMarkupFormatter().translate(description);
+        } catch (IOException e) {
+            LOGGER.warning("failed to translate description using configured markup formatter");
+            return "";
+        }
+    }
+
     /**
      * Name of the parameter.
      *


BJA-694 minor tweak to avoid method signature change

@@ -157,8 +157,6 @@ public AsymmetricCipherKeyPair generateKeyPair()
      */
     protected BigInteger chooseRandomPrime(int bitlength, BigInteger e, BigInteger sqrdBound)
     {
-        int iterations = getNumberOfIterations(bitlength, param.getCertainty());
-
         for (int i = 0; i != 5 * bitlength; i++)
         {
             BigInteger p = new BigInteger(bitlength, 1, param.getRandom());
@@ -173,7 +171,7 @@ protected BigInteger chooseRandomPrime(int bitlength, BigInteger e, BigInteger s
                 continue;
             }

-            if (!isProbablePrime(p, iterations))
+            if (!isProbablePrime(p))
             {
                 continue;
             }
@@ -189,8 +187,10 @@ protected BigInteger chooseRandomPrime(int bitlength, BigInteger e, BigInteger s
         throw new IllegalStateException("unable to generate prime number for RSA key");
     }

-    protected boolean isProbablePrime(BigInteger x, int iterations)
+    protected boolean isProbablePrime(BigInteger x)
     {
+        int iterations = getNumberOfIterations(x.bitLength(), param.getCertainty());
+
         /*
          * Primes class for FIPS 186-4 C.3 primality checking
          */


modified IESEngine so that MAC check is the primary one
added general BadBlockException class for asymmetric ciphers.

@@ -32,6 +32,7 @@
 import org.bouncycastle.crypto.engines.RSABlindedEngine;
 import org.bouncycastle.crypto.params.ParametersWithRandom;
 import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
+import org.bouncycastle.jcajce.provider.util.BadBlockException;
 import org.bouncycastle.jcajce.provider.util.DigestFactory;
 import org.bouncycastle.jcajce.util.BCJcaJceHelper;
 import org.bouncycastle.jcajce.util.JcaJceHelper;
@@ -528,15 +529,9 @@ private byte[] getOutput()

             return cipher.processBlock(bytes, 0, bytes.length);
         }
-        catch (final InvalidCipherTextException e)
+        catch (InvalidCipherTextException e)
         {
-            throw new BadPaddingException("unable to decrypt block")
-            {
-                public synchronized Throwable getCause()
-                {
-                    return e;
-                }
-            };
+            throw new BadBlockException("unable to decrypt block", e);
         }
         finally
         {


removed support for non-cbc mode ciphers in IES/ECIES

@@ -33,24 +33,6 @@ public IESParameterSpec(
         this(derivation, encoding, macKeySize, -1, null, false);
     }

-
-    /**
-     * Set the IES engine parameters.
-     *
-     * @param derivation    the optional derivation vector for the KDF.
-     * @param encoding      the optional encoding vector for the KDF.
-     * @param macKeySize    the key size (in bits) for the MAC.
-     * @param cipherKeySize the key size (in bits) for the block cipher.
-     */
-    public IESParameterSpec(
-        byte[] derivation,
-        byte[] encoding,
-        int macKeySize,
-        int cipherKeySize)
-    {
-        this(derivation, encoding, macKeySize, cipherKeySize, null, false);
-    }
-
     /**
      * Set the IES engine parameters.
      *


added better support for DH domain parameters
added s box allocation to AESEngine
reduced use of AESFastEngine.

@@ -5,6 +5,7 @@
 import org.bouncycastle.crypto.DataLengthException;
 import org.bouncycastle.crypto.OutputLengthException;
 import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.util.Arrays;
 import org.bouncycastle.util.Pack;

 /**

@@ -415,6 +416,8 @@ private int[][] generateWorkingKey(byte[] key, boolean forEncryption)
     private int         C0, C1, C2, C3;
     private boolean     forEncryption;

+    private byte[]      s;
+
     private static final int BLOCK_SIZE = 16;

     /**

@@ -440,6 +443,14 @@ public void init(
         {
             WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
             this.forEncryption = forEncryption;
+            if (forEncryption)
+            {
+                s = Arrays.clone(S);
+            }
+            else
+            {
+                s = Arrays.clone(Si);
+            }
             return;
         }


Fix carry propagation bug in Nat???.square methods

@@ -713,8 +713,8 @@ public static void square(int[] x, int xOff, int[] zz, int zzOff)
         }

         long x_3 = x[xOff + 3] & M;
-        long zz_5 = zz[zzOff + 5] & M;
-        long zz_6 = zz[zzOff + 6] & M;
+        long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+        long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
         {
             zz_3 += x_3 * x_0;
             w = (int)zz_3;


Added header validation for INTEGER/ENUMERATED
Added additional validations for DSA/ECDSA signature parsing.

@@ -29,6 +29,7 @@
 import org.bouncycastle.crypto.digests.SHA512Digest;
 import org.bouncycastle.crypto.params.ParametersWithRandom;
 import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
+import org.bouncycastle.util.Arrays;

 public class DSASigner
     extends SignatureSpi
@@ -180,6 +181,10 @@ private BigInteger[] derDecode(
         {
             throw new IOException("malformed signature");
         }
+        if (!Arrays.areEqual(encoding, s.getEncoded(ASN1Encoding.DER)))
+        {
+            throw new IOException("malformed signature");
+        }

         return new BigInteger[]{
             ((ASN1Integer)s.getObjectAt(0)).getValue(),


fixing CTS failure issue in master branch

@@ -565,7 +565,7 @@ private String getLocalePrefix(FacesContext context) {

         localePrefix = context.getExternalContext().getRequestParameterMap().get("loc");

-        if(localePrefix != null){
+        if(localePrefix != null && !nameContainsForbiddenSequence(localePrefix)){
             return localePrefix;
         }


@@ -8,6 +8,8 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
+import java.util.HashSet;
+import java.util.Set;

 import org.bouncycastle.crypto.Digest;
 import org.bouncycastle.util.Arrays;
@@ -382,6 +384,24 @@ public static boolean isNewAuthenticationPathNeeded(long globalIndex, int xmssHe
     private static class CheckingStream
        extends ObjectInputStream
     {
+        private static final Set<String> components = new HashSet<>();
+
+        static
+        {
+            components.add("java.util.TreeMap");
+            components.add("java.lang.Integer");
+            components.add("java.lang.Number");
+            components.add("org.bouncycastle.pqc.crypto.xmss.BDS");
+            components.add("java.util.ArrayList");
+            components.add("org.bouncycastle.pqc.crypto.xmss.XMSSNode");
+            components.add("[B");
+            components.add("java.util.LinkedList");
+            components.add("java.util.Stack");
+            components.add("java.util.Vector");
+            components.add("[Ljava.lang.Object;");
+            components.add("org.bouncycastle.pqc.crypto.xmss.BDSTreeHash");
+        }
+
         private final Class mainClass;
         private boolean found = false;

@@ -409,6 +429,14 @@ protected Class<?> resolveClass(ObjectStreamClass desc)
                     found = true;
                 }
             }
+            else
+            {
+                if (!components.contains(desc.getName()))
+                {
+                    throw new InvalidClassException(
+                          "unexpected class: ", desc.getName());
+                }
+            }
             return super.resolveClass(desc);
         }
     }


Prevent deserialization of random objects

Summary:
Fixed security issue with buck parser-cache command.
This diff prevent deserialization of random objects.

Reviewed By: jtorkkola

fbshipit-source-id: 24e8221

@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.facebook.buck.parser;
+
+import com.facebook.buck.parser.thrift.RemoteDaemonicParserState;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.util.HashSet;
+import java.util.Set;
+
+/** A ObjectInputStream that will deserialize only RemoteDaemonicParserState. */
+public class ParserStateObjectInputStream extends ObjectInputStream {
+
+  private Set<String> whitelist;
+
+  public ParserStateObjectInputStream(InputStream inputStream) throws IOException {
+    super(inputStream);
+
+    whitelist = new HashSet<>();
+    whitelist.add(RemoteDaemonicParserState.class.getName());
+  }
+
+  @Override
+  protected Class<?> resolveClass(ObjectStreamClass desc)
+      throws IOException, ClassNotFoundException {
+    if (!whitelist.contains(desc.getName())) {
+      throw new InvalidClassException(desc.getName(), "Can't deserialize this class");
+    }
+    return super.resolveClass(desc);
+  }
+}


CVE-2019-3557: Fix OOB read in readRecord on BZ2Files/OutputFiles

Summary:
These File subclasses return -1 on read errors which is not what is
expected for readImpl--this made File::readRecord behave unusually if the read
fails, causing it to read (size_t)(-1) bytes from its stream buffer; which,
unsurprisingly produces a out-of-bounds heap read.

Reviewed By: leikahing, jjgriego

Differential Revision: D13659395

fbshipit-source-id: 359ed6e3ff9f9cf49b752b666f51c4e0b3ce4b8a

@@ -95,7 +95,7 @@ int64_t BZ2File::readImpl(char * buf, int64_t length) {
   if (len <= 0) {
     setEof(true);
     if (len < 0) {
-      return -1;
+      return 0;
     }
   }
   return len;


@@ -68,6 +68,12 @@ public class BeanDeserializerFactory
         s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
         s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");

+        // [databind#2097]: some 3rd party, one JDK-bundled
+        s.add("org.slf4j.ext.EventData");
+        s.add("flex.messaging.util.concurrent.AsynchBeansWorkManagerExecutor");
+        s.add("com.sun.deploy.security.ruleset.DRSHelper");
+        s.add("org.apache.axis2.jaxws.spi.handler.HandlerResolverImpl");
+
         DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
     }


Bug-406: DNS interaction is not blocked by Robocode's security manager + test(s) to verify the fix

@@ -12,7 +12,9 @@
 import net.sf.robocode.host.IThreadManager;
 import net.sf.robocode.io.RobocodeProperties;

+import java.net.SocketPermission;
 import java.security.AccessControlException;
+import java.security.Permission;

 /**
@@ -49,7 +51,6 @@ public void checkAccess(Thread t) {
 		}

 		Thread c = Thread.currentThread();
-
 		if (isSafeThread(c)) {
 			return;
 		}
@@ -84,7 +85,7 @@ public void checkAccess(Thread t) {
 			if (robotProxy != null) {
 				robotProxy.punishSecurityViolation(message);
 			}
-			throw new AccessControlException(message);
+			throw new SecurityException(message);
 		}
 	}

@@ -94,7 +95,6 @@ public void checkAccess(ThreadGroup g) {
 			return;
 		}
 		Thread c = Thread.currentThread();
-
 		if (isSafeThread(c)) {
 			return;
 		}
@@ -123,9 +123,27 @@ public void checkAccess(ThreadGroup g) {
 			String message = "Robots are only allowed to create up to 5 threads!";

 			robotProxy.punishSecurityViolation(message);
-			throw new AccessControlException(message);
+			throw new SecurityException(message);
 		}
 	}
+
+    public void checkPermission(Permission perm) {
+		if (RobocodeProperties.isSecurityOff()) {
+			return;
+		}
+		Thread c = Thread.currentThread();
+		if (isSafeThread(c)) {
+			return;
+		}
+        super.checkPermission(perm);
+
+        if (perm instanceof SocketPermission) {
+    		IHostedThread robotProxy = threadManager.getLoadedOrLoadingRobotProxy(c);
+        	String message = "Using socket is not allowed";
+        	robotProxy.punishSecurityViolation(message);
+            throw new SecurityException(message);
+        }
+    }

 	private boolean isSafeThread(Thread c) {
 		return threadManager.isSafeThread(c);


@@ -57,6 +57,13 @@ public class SubTypeValidator
         // [databind#2032]: more 3rd party; data exfiltration via xml parsed ext entities
         s.add("org.apache.ibatis.parsing.XPathParser");

+        // [databind#2052]: Jodd-db, with jndi/ldap lookup
+        s.add("jodd.db.connection.DataSourceConnectionProvider");
+
+        // [databind#2058]: Oracle JDBC driver, with jndi/ldap lookup
+        s.add("oracle.jdbc.connector.OracleManagedConnectionFactory");
+        s.add("oracle.jdbc.rowset.OracleJDBCRowSet");
+
         DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
     }


feat(hawtio-system): ENTESB-10081 - Add config parameter to disable local address probing for proxy whitelist

@@ -19,6 +19,8 @@ public class ConfigManager {

     private static final transient Logger LOG = LoggerFactory.getLogger(ConfigManager.class);

+    public static final String CONFIG_MANAGER = "ConfigManager";
+
     private Context envContext = null;

     private Function<String, String> propertyResolver;
@@ -82,6 +84,10 @@ public String get(String name, String defaultValue) {
         return answer;
     }

+    public boolean getBoolean(String name, boolean defaultValue) {
+        return Boolean.parseBoolean(get(name, Boolean.toString(defaultValue)));
+    }
+
     private static String getHawtioSystemProperty(String name) {
         return System.getProperty("hawtio." + name);
     }


Merge remote-tracking branch 'origin/GT-3198_dev747368_fix_XMLDecoder_github_1090' into Ghidra_9.1

@@ -56,7 +56,7 @@ public void addRegAndValueToFilter(String contextRegister, BigInteger value) {
 	public boolean allows(List<ContextRegisterInfo> contextRegisterInfos) {
 		for (ContextRegisterInfo cInfo : contextRegisterInfos) {
 			if (contextRegisters.contains(cInfo.getContextRegister())) {
-				if (!values.get(cInfo.getContextRegister()).equals(cInfo.getValueAsBigInteger())) {
+				if (!values.get(cInfo.getContextRegister()).equals(cInfo.getValue())) {
 					return false;
 				}
 			}


@@ -156,7 +156,7 @@ private void newRequest(ChannelHandlerContext ctx, HttpRequest nettyRequest) thr
       channel.attr(CLIENT_CERT_KEY).get()
     );

-    HttpHeaders nettyHeaders = new DefaultHttpHeaders(false);
+    HttpHeaders nettyHeaders = new DefaultHttpHeaders();
     MutableHeaders responseHeaders = new NettyHeadersBackedMutableHeaders(nettyHeaders);
     AtomicBoolean transmitted = new AtomicBoolean(false);


Merge pull request from GHSA-35fr-h7jr-hh86

Motivation:

An `HttpService` can produce a malformed HTTP response when a user
specified a malformed HTTP header values, such as:

    ResponseHeaders.of(HttpStatus.OK
                       "my-header", "foo\r\nbad-header: bar");

Modification:

- Add strict header value validation to `HttpHeadersBase`
- Add strict header name validation to `HttpHeaderNames.of()`, which is
  used by `HttpHeadersBase`.

Result:

- It is not possible anymore to send a bad header value which can be
  misused for sending additional headers or injecting arbitrary content.

@@ -673,7 +673,7 @@ private static CharSequenceMap toLowercaseMap(Iterator<? extends CharSequence> v
         final CharSequenceMap result = new CharSequenceMap(arraySizeHint);

         while (valuesIter.hasNext()) {
-            final AsciiString lowerCased = HttpHeaderNames.of(valuesIter.next()).toLowerCase();
+            final AsciiString lowerCased = AsciiString.of(valuesIter.next()).toLowerCase();
             try {
                 int index = lowerCased.forEachByte(FIND_COMMA);
                 if (index != -1) {


KEYCLOAK-11245 Use transcription object for LDAP bindCredential

@@ -19,6 +19,7 @@

 import org.jboss.logging.Logger;
 import org.keycloak.common.util.Base64;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.LDAPConstants;
 import org.keycloak.models.ModelException;
 import org.keycloak.storage.ldap.LDAPConfig;
@@ -75,14 +76,9 @@ public class LDAPIdentityStore implements IdentityStore {
     private final LDAPConfig config;
     private final LDAPOperationManager operationManager;

-    public LDAPIdentityStore(LDAPConfig config) {
+    public LDAPIdentityStore(KeycloakSession session, LDAPConfig config) {
         this.config = config;
-
-        try {
-            this.operationManager = new LDAPOperationManager(config);
-        } catch (NamingException e) {
-            throw new ModelException("Couldn't init operation manager", e);
-        }
+        this.operationManager = new LDAPOperationManager(session, config);
     }

     @Override


KEYCLOAK-10780 Stop creating placeholder e-mails for service accounts (#228)

@@ -231,6 +231,8 @@ public void serviceAccount() {
         response.close();
         UserRepresentation userRep = realm.clients().get(id).getServiceAccountUser();
         assertEquals("service-account-serviceclient", userRep.getUsername());
+        // KEYCLOAK-11197 service accounts are no longer created with a placeholder e-mail.
+        assertNull(userRep.getEmail());
     }

     // KEYCLOAK-3421


Escape EL expressions in ViolationCollector (#3157)

Fixes #3153

@@ -1,12 +1,16 @@
 package io.dropwizard.validation.selfvalidating;

+import javax.annotation.Nullable;
 import javax.validation.ConstraintValidatorContext;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;

 /**
  * This class is a simple wrapper around the ConstraintValidatorContext of hibernate validation.
  * It collects all the violations of the SelfValidation methods of an object.
  */
 public class ViolationCollector {
+    private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\$\\{");

     private boolean violationOccurred = false;
     private ConstraintValidatorContext context;
@@ -17,14 +21,80 @@ public ViolationCollector(ConstraintValidatorContext context) {
     }

     /**
-     * Adds a new violation to this collector. This also sets violationOccurred to true.
+     * Adds a new violation to this collector. This also sets {@code violationOccurred} to {@code true}.
      *
-     * @param msg the message of the violation
+     * @param message the message of the violation (any EL expression will be escaped and not parsed)
      */
-    public void addViolation(String msg) {
+    public void addViolation(String message) {
         violationOccurred = true;
-        context.buildConstraintViolationWithTemplate(msg)
-            .addConstraintViolation();
+        String messageTemplate = escapeEl(message);
+        context.buildConstraintViolationWithTemplate(messageTemplate)
+                .addConstraintViolation();
+    }
+
+    /**
+     * Adds a new violation to this collector. This also sets {@code violationOccurred} to {@code true}.
+     *
+     * @param propertyName the name of the property
+     * @param message      the message of the violation (any EL expression will be escaped and not parsed)
+     * @since 2.0.2
+     */
+    public void addViolation(String propertyName, String message) {
+        violationOccurred = true;
+        String messageTemplate = escapeEl(message);
+        context.buildConstraintViolationWithTemplate(messageTemplate)
+                .addPropertyNode(propertyName)
+                .addConstraintViolation();
+    }
+
+    /**
+     * Adds a new violation to this collector. This also sets {@code violationOccurred} to {@code true}.
+     *
+     * @param propertyName the name of the property with the violation
+     * @param index        the index of the element with the violation
+     * @param message      the message of the violation (any EL expression will be escaped and not parsed)
+     * @since 2.0.2
+     */
+    public void addViolation(String propertyName, Integer index, String message) {
+        violationOccurred = true;
+        String messageTemplate = escapeEl(message);
+        context.buildConstraintViolationWithTemplate(messageTemplate)
+                .addPropertyNode(propertyName)
+                .addBeanNode().inIterable().atIndex(index)
+                .addConstraintViolation();
+    }
+
+    /**
+     * Adds a new violation to this collector. This also sets {@code violationOccurred} to {@code true}.
+     *
+     * @param propertyName the name of the property with the violation
+     * @param key          the key of the element with the violation
+     * @param message      the message of the violation (any EL expression will be escaped and not parsed)
+     * @since 2.0.2
+     */
+    public void addViolation(String propertyName, String key, String message) {
+        violationOccurred = true;
+        String messageTemplate = escapeEl(message);
+        context.buildConstraintViolationWithTemplate(messageTemplate)
+                .addPropertyNode(propertyName)
+                .addBeanNode().inIterable().atKey(key)
+                .addConstraintViolation();
+    }
+
+    @Nullable
+    private String escapeEl(@Nullable String s) {
+        if (s == null || s.isEmpty()) {
+            return s;
+        }
+
+        final Matcher m = ESCAPE_PATTERN.matcher(s);
+        final StringBuffer sb = new StringBuffer(s.length() + 16);
+        while (m.find()) {
+            m.appendReplacement(sb, "\\\\\\${");
+        }
+        m.appendTail(sb);
+
+        return sb.toString();
     }

     /**


Replace MD5 with bcrypt for password hashing

User passwords are stored in the database using the rather outdated and
cryptographically insecure MD5 hash algorithm. Furthermore, the hashes
are salted using the username instead of a random salt, causing hashes
for users with the same username and password to collide which is
problematic especially for popular users like the default admin user.

This essentially means that for an attacker, it might be feasible to
reconstruct a user's password given access to these hashes.

Note that attackers needing access to the hashes means that they must
gain access to the database in which these are stored first to be able
to start cracking the passwords.
Patches

The patch makes Opencast now uses the modern and much stronger bcrypt
password hashing algorithm for storing passwords.  Note, that old hashes
remain MD5 until the password is updated.

For a list of users whose password hashes are stored using MD5, the REST endpoint `/user-utils/users/md5.json` is added.

@@ -29,6 +29,7 @@
 import static org.opencastproject.util.data.Collections.set;
 import static org.opencastproject.util.persistence.PersistenceUtil.newTestEntityManagerFactory;

+import org.opencastproject.kernel.security.CustomPasswordEncoder;
 import org.opencastproject.security.api.Role;
 import org.opencastproject.security.api.SecurityConstants;
 import org.opencastproject.security.api.SecurityService;
@@ -38,7 +39,6 @@
 import org.opencastproject.security.impl.jpa.JpaRole;
 import org.opencastproject.security.impl.jpa.JpaUser;
 import org.opencastproject.util.NotFoundException;
-import org.opencastproject.util.PasswordEncoder;
 import org.opencastproject.util.data.Collections;

 import org.apache.commons.collections4.IteratorUtils;
@@ -56,6 +56,7 @@ public class JpaUserProviderTest {
   private JpaUserAndRoleProvider provider = null;
   private JpaOrganization org1 = null;
   private JpaOrganization org2 = null;
+  private CustomPasswordEncoder passwordEncoder = new CustomPasswordEncoder();

   @Before
   public void setUp() throws Exception {
@@ -83,7 +84,7 @@ public void testAddAndGetUser() throws Exception {
     assertNotNull(loadUser);

     assertEquals(user.getUsername(), loadUser.getUsername());
-    assertEquals(PasswordEncoder.encode(user.getPassword(), user.getUsername()), loadUser.getPassword());
+    assertTrue(passwordEncoder.isPasswordValid(loadUser.getPassword(), user.getPassword(), null));
     assertEquals(user.getOrganization(), loadUser.getOrganization());
     assertEquals(user.getRoles(), loadUser.getRoles());

@@ -94,7 +95,7 @@ public void testAddAndGetUser() throws Exception {
     assertNotNull(loadUser);

     assertEquals(user.getUsername(), loadUser.getUsername());
-    assertEquals(PasswordEncoder.encode(user.getPassword(), user.getUsername()), loadUser.getPassword());
+    assertTrue(passwordEncoder.isPasswordValid(loadUser.getPassword(), user.getPassword(), null));
     assertEquals(user.getOrganization(), loadUser.getOrganization());
     assertEquals(user.getRoles(), loadUser.getRoles());
   }
@@ -227,7 +228,7 @@ public void testUpdateUser() throws Exception {

     assertNotNull(loadUpdatedUser);
     assertEquals(user.getUsername(), loadUpdatedUser.getUsername());
-    assertEquals(PasswordEncoder.encode(newPassword, user.getUsername()), loadUpdatedUser.getPassword());
+    assertTrue(passwordEncoder.isPasswordValid(loadUpdatedUser.getPassword(), newPassword, null));
     assertEquals(authorities.size(), loadUpdatedUser.getRoles().size());

     updateUser = new JpaUser("unknown", newPassword, org1, provider.getName(), true, authorities);


Merge pull request #14 from Accenture/security/xml-xxe-1-2020

v1.12.28 with rest-automation improvements and XXE patch

@@ -1,3 +1,21 @@
+/*
+
+    Copyright 2018-2020 Accenture Technology
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+ */
+
 package org.platformlambda.automation.servlets;

 import com.google.api.client.http.*;
@@ -39,6 +57,7 @@ public class HttpRelay implements LambdaFunction {
     private static final SimpleXmlWriter xmlWriter = new SimpleXmlWriter();
     private static final ConcurrentMap<String, HttpRequestFactory> httpFactory = new ConcurrentHashMap<>();

+    private static final String X_TRACE_ID = ServiceGateway.X_TRACE_ID;
     private static final String REGULAR_FACTORY = "regular.";
     private static final String TRUST_ALL_FACTORY = "trust_all.";
     private static final String COOKIE = "cookie";
@@ -208,6 +227,12 @@ public Object handleEvent(Map<String, String> headers, Object body, int instance
                     update = true;
                 }
             }
+            // propagate X-Trace-Id when forwarding the HTTP request
+            String traceId = po.getTraceId();
+            if (traceId != null) {
+                httpHeaders.set(X_TRACE_ID, traceId);
+                update = true;
+            }
             // set cookies if any
             Map<String, String> cookies  = request.getCookies();
             StringBuilder sb = new StringBuilder();


@@ -1,7 +1,7 @@
 /*
  * ***** BEGIN LICENSE BLOCK *****
  * Zimbra Collaboration Suite Server
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016, 2020 Synacor, Inc.
  *
  * This program is free software: you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free Software Foundation,
@@ -57,8 +57,14 @@ public Element handle(Element request, Map<String, Object> context) throws Servi
         params.setLimit(account.getContactAutoCompleteMaxResults());
         params.setNeedCanExpand(needCanExpand);
         params.setResponseName(AccountConstants.AUTO_COMPLETE_GAL_RESPONSE);
-        if (galAcctId != null)
-            params.setGalSyncAccount(Provisioning.getInstance().getAccountById(galAcctId));
+        if (galAcctId != null) {
+            Account galAccount = Provisioning.getInstance().getAccountById(galAcctId);
+            if (galAccount != null && (!account.getDomainId().equals(galAccount.getDomainId()))) {
+                throw ServiceException
+                    .PERM_DENIED("can not access galsync account of different domain");
+            }
+            params.setGalSyncAccount(galAccount);
+        }
         GalSearchControl gal = new GalSearchControl(params);
         gal.autocomplete();
         return params.getResultCallback().getResponse();


Disable message interpolation in ConstraintViolations by default (#3208)

Disable message interpolation in ConstraintViolations by default but allow enabling it explicitly with `SelfValidating#escapeExpressions()`.

Additionally, `ConstraintViolations` now provides a set of methods which take a map of message parameters for interpolation.
The message parameters will be escaped by default.

Refs #3153
Refs #3157

@@ -31,15 +31,17 @@ public class SelfValidatingValidator implements ConstraintValidator<SelfValidati
     private final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED);
     private final TypeResolver typeResolver = new TypeResolver();
     private final MemberResolver memberResolver = new MemberResolver(typeResolver);
+    private boolean escapeExpressions = true;

     @Override
     public void initialize(SelfValidating constraintAnnotation) {
+        escapeExpressions = constraintAnnotation.escapeExpressions();
     }

     @SuppressWarnings({"unchecked", "rawtypes"})
     @Override
     public boolean isValid(Object value, ConstraintValidatorContext context) {
-        final ViolationCollector collector = new ViolationCollector(context);
+        final ViolationCollector collector = new ViolationCollector(context, escapeExpressions);
         context.disableDefaultConstraintViolation();
         for (ValidationCaller caller : methodMap.computeIfAbsent(value.getClass(), this::findMethods)) {
             caller.setValidationObject(value);


@@ -1636,6 +1636,7 @@ class AssetDefinition extends Definition {
     public AssetDefinition(final String method, final String pattern,
         final Route.Filter handler, boolean caseSensitiveRouting) {
       super(method, pattern, handler, caseSensitiveRouting);
+      filter().setRoute(this);
     }

     @Nonnull


Merge pull request #1 from darranl/CVE-2020-1732

[CVE-2020-1732] Adjust JASPIC integration to create a new ServerAuthModule for each request.

@@ -17,6 +17,7 @@
 package org.glassfish.soteria.mechanisms.jaspic;

 import java.util.Collections;
+import java.util.function.Supplier;

 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
@@ -34,15 +35,15 @@
  * <p>
  * Since this simple example only has a single SAM, we delegate directly to that one. Note that this {@link ServerAuthContext}
  * and the {@link ServerAuthModule} (SAM) share a common base interface: {@link ServerAuth}.
- *
+ *
  * @author Arjan Tijms
  */
 public class DefaultServerAuthContext implements ServerAuthContext {

     private final ServerAuthModule serverAuthModule;

-    public DefaultServerAuthContext(CallbackHandler handler, ServerAuthModule serverAuthModule) throws AuthException {
-        this.serverAuthModule = serverAuthModule;
+    public DefaultServerAuthContext(CallbackHandler handler, Supplier<ServerAuthModule> serverAuthModuleSupplier) throws AuthException {
+        this.serverAuthModule = serverAuthModuleSupplier.get();
         serverAuthModule.initialize(null, null, handler, Collections.<String, String> emptyMap());
     }


Merge pull request from GHSA-37xm-4h3m-5w3v

* refactor: Clean up whitespace in existing PgSQLXMLTest

* fix: Fix XXE vulnerability in PgSQLXML by disabling external access and doctypes

Fixes XXE vulnerability by defaulting to disabling external access and doc types. The
legacy insecure behavior can be restored via the new connection property xmlFactoryFactory
with a value of LEGACY_INSECURE. Alternatively, a custom class name can be specified that
implements org.postgresql.xml.PGXmlFactoryFactory and takes a no argument constructor.

* fix: Add missing getter and setter for XML_FACTORY_FACTORY to BasicDataSource

@@ -37,6 +37,9 @@
 import org.postgresql.util.PGobject;
 import org.postgresql.util.PSQLException;
 import org.postgresql.util.PSQLState;
+import org.postgresql.xml.DefaultPGXmlFactoryFactory;
+import org.postgresql.xml.LegacyInsecurePGXmlFactoryFactory;
+import org.postgresql.xml.PGXmlFactoryFactory;

 import java.io.IOException;
 import java.sql.Array;
@@ -156,6 +159,9 @@ private enum ReadOnlyBehavior {

   private final LruCache<FieldMetadata.Key, FieldMetadata> fieldMetadataCache;

+  private final String xmlFactoryFactoryClass;
+  private PGXmlFactoryFactory xmlFactoryFactory;
+
   final CachedQuery borrowQuery(String sql) throws SQLException {
     return queryExecutor.borrowQuery(sql);
   }
@@ -311,6 +317,8 @@ public TimeZone get() {
         false);

     replicationConnection = PGProperty.REPLICATION.get(info) != null;
+
+    xmlFactoryFactoryClass = PGProperty.XML_FACTORY_FACTORY.get(info);
   }

   private static ReadOnlyBehavior getReadOnlyBehavior(String property) {
@@ -1823,4 +1831,36 @@ public final String getParameterStatus(String parameterName) {
     return queryExecutor.getParameterStatus(parameterName);
   }

+  @Override
+  public PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException {
+    if (xmlFactoryFactory == null) {
+      if (xmlFactoryFactoryClass == null || xmlFactoryFactoryClass.equals("")) {
+        xmlFactoryFactory = DefaultPGXmlFactoryFactory.INSTANCE;
+      } else if (xmlFactoryFactoryClass.equals("LEGACY_INSECURE")) {
+        xmlFactoryFactory = LegacyInsecurePGXmlFactoryFactory.INSTANCE;
+      } else {
+        Class<?> clazz;
+        try {
+          clazz = Class.forName(xmlFactoryFactoryClass);
+        } catch (ClassNotFoundException ex) {
+          throw new PSQLException(
+              GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass),
+              PSQLState.INVALID_PARAMETER_VALUE, ex);
+        }
+        if (!clazz.isAssignableFrom(PGXmlFactoryFactory.class)) {
+          throw new PSQLException(
+              GT.tr("Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: {0}", xmlFactoryFactoryClass),
+              PSQLState.INVALID_PARAMETER_VALUE);
+        }
+        try {
+          xmlFactoryFactory = (PGXmlFactoryFactory) clazz.newInstance();
+        } catch (Exception ex) {
+          throw new PSQLException(
+              GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass),
+              PSQLState.INVALID_PARAMETER_VALUE, ex);
+        }
+      }
+    }
+    return xmlFactoryFactory;
+  }
 }


Improve array bounds checks in CipherState implementations

Thanks to Pietro Oliva for identifying these issues.

@@ -214,10 +214,11 @@ private void encrypt(byte[] plaintext, int plaintextOffset,
 	public int encryptWithAd(byte[] ad, byte[] plaintext, int plaintextOffset,
 			byte[] ciphertext, int ciphertextOffset, int length) throws ShortBufferException {
 		int space;
-		if (ciphertextOffset > ciphertext.length)
-			space = 0;
-		else
-			space = ciphertext.length - ciphertextOffset;
+		if (ciphertextOffset < 0 || ciphertextOffset > ciphertext.length)
+			throw new IllegalArgumentException();
+		if (length < 0 || plaintextOffset < 0 || plaintextOffset > plaintext.length)
+			throw new IllegalArgumentException();
+		space = ciphertext.length - ciphertextOffset;
 		if (!haskey) {
 			// The key is not set yet - return the plaintext as-is.
 			if (length > space)
@@ -241,16 +242,15 @@ public int decryptWithAd(byte[] ad, byte[] ciphertext,
 			int ciphertextOffset, byte[] plaintext, int plaintextOffset,
 			int length) throws ShortBufferException, BadPaddingException {
 		int space;
-		if (ciphertextOffset > ciphertext.length)
-			space = 0;
+		if (ciphertextOffset < 0 || ciphertextOffset > ciphertext.length)
+			throw new IllegalArgumentException();
 		else
 			space = ciphertext.length - ciphertextOffset;
 		if (length > space)
 			throw new ShortBufferException();
-		if (plaintextOffset > plaintext.length)
-			space = 0;
-		else
-			space = plaintext.length - plaintextOffset;
+		if (length < 0 || plaintextOffset < 0 || plaintextOffset > plaintext.length)
+			throw new IllegalArgumentException();
+		space = plaintext.length - plaintextOffset;
 		if (!haskey) {
 			// The key is not set yet - return the ciphertext as-is.
 			if (length > space)


Fix #48 forget remove token from ThreadLocal

@@ -1,8 +1,7 @@
-package com.zrlog.service;
+package com.zrlog.web.util;

-import com.jfinal.core.JFinal;
 import com.zrlog.common.vo.AdminTokenVO;
-import com.zrlog.model.User;
+import com.zrlog.util.BlogBuildInfoUtil;
 import com.zrlog.util.I18nUtil;
 import com.zrlog.util.ZrLogUtil;

@@ -12,17 +11,14 @@

 public class PluginHelper {

-    public static Map<String, String> genHeaderMapByRequest(HttpServletRequest request) {
+    public static Map<String, String> genHeaderMapByRequest(HttpServletRequest request, AdminTokenVO adminTokenVO) {
         Map<String, String> map = new HashMap<>();
-        AdminTokenVO adminTokenVO = AdminTokenThreadLocal.getUser();
         if (adminTokenVO != null) {
-            User user = User.dao.findById(adminTokenVO.getUserId());
-            map.put("LoginUserName", user.get("userName").toString());
             map.put("LoginUserId", adminTokenVO.getUserId() + "");
         }
         map.put("IsLogin", (adminTokenVO != null) + "");
         map.put("Current-Locale", I18nUtil.getCurrentLocale());
-        map.put("Blog-Version", ((Map) JFinal.me().getServletContext().getAttribute("zrlog")).get("version").toString());
+        map.put("Blog-Version", BlogBuildInfoUtil.getVersion());
         if (request != null) {
             String fullUrl = ZrLogUtil.getFullUrl(request);
             if (request.getQueryString() != null) {


further work to improve constant time in OAEP and RSA core.

@@ -1,12 +1,13 @@
 package org.bouncycastle.crypto.engines;

+import java.math.BigInteger;
+
 import org.bouncycastle.crypto.CipherParameters;
 import org.bouncycastle.crypto.DataLengthException;
 import org.bouncycastle.crypto.params.ParametersWithRandom;
 import org.bouncycastle.crypto.params.RSAKeyParameters;
 import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
-
-import java.math.BigInteger;
+import org.bouncycastle.util.Arrays;

 /**
  * this does your basic RSA algorithm.
@@ -142,20 +143,29 @@ public byte[] convertOutput(

                 return tmp;
             }
+
+            return output;
         }
         else
         {
+            byte[]  rv;
             if (output[0] == 0)        // have ended up with an extra zero byte, copy down.
             {
-                byte[]  tmp = new byte[output.length - 1];
+                rv = new byte[output.length - 1];

-                System.arraycopy(output, 1, tmp, 0, tmp.length);
+                System.arraycopy(output, 1, rv, 0, rv.length);
+            }
+            else        // maintain decryption time
+            {
+                rv = new byte[output.length];

-                return tmp;
+                System.arraycopy(output, 0, rv, 0, rv.length);
             }
-        }

-        return output;
+            Arrays.fill(output, (byte)0);
+
+            return rv;
+        }
     }

     public BigInteger processBlock(BigInteger input)


Added sort validation

This commit now validates that the value passed via a PageRequest to
sort the results by is a valid value.

Resolves #739

Fixed to allow for all letter cases

Polish

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2019 the original author or authors.
+ * Copyright 2015-2020 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -58,6 +59,7 @@
  * @author Gunnar Hillert
  * @author David Turanski
  * @author Ilayaperumal Gopinathan
+ * @author Michael Minella
  */
 public class JdbcTaskExecutionDao implements TaskExecutionDao {

@@ -161,6 +163,21 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {

 	private DataFieldMaxValueIncrementer taskIncrementer;

+	private static final Set<String> validSortColumns = new HashSet<>(10);
+
+	static {
+		validSortColumns.add("TASK_EXECUTION_ID");
+		validSortColumns.add("START_TIME");
+		validSortColumns.add("END_TIME");
+		validSortColumns.add("TASK_NAME");
+		validSortColumns.add("EXIT_CODE");
+		validSortColumns.add("EXIT_MESSAGE");
+		validSortColumns.add("ERROR_MESSAGE");
+		validSortColumns.add("LAST_UPDATED");
+		validSortColumns.add("EXTERNAL_EXECUTION_ID");
+		validSortColumns.add("PARENT_EXECUTION_ID");
+	}
+
 	/**
 	 * Initializes the JdbcTaskExecutionDao.
 	 * @param dataSource used by the dao to execute queries and update the tables.
@@ -511,8 +528,14 @@ private Page<TaskExecution> queryForPageableResults(Pageable pageable,

 		if (sort != null) {
 			for (Sort.Order sortOrder : sort) {
-				sortOrderMap.put(sortOrder.getProperty(),
-						sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING);
+				if (validSortColumns.contains(sortOrder.getProperty().toUpperCase())) {
+					sortOrderMap.put(sortOrder.getProperty(),
+							sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING);
+				}
+				else {
+					throw new IllegalArgumentException(String.format(
+							"Invalid sort option selected: %s", sortOrder.getProperty()));
+				}
 			}
 		}


Do not use deserialized AttachmentSupport from client side to avoid security vulnerabilities

@@ -272,7 +272,6 @@
 import io.onedev.server.web.avatar.AvatarManager;
 import io.onedev.server.web.avatar.DefaultAvatarManager;
 import io.onedev.server.web.component.diff.DiffRenderer;
-import io.onedev.server.web.component.markdown.AttachmentUploadServlet;
 import io.onedev.server.web.component.markdown.SourcePositionTrackExtension;
 import io.onedev.server.web.component.markdown.emoji.EmojiExtension;
 import io.onedev.server.web.component.taskbutton.TaskButton;
@@ -557,8 +556,6 @@ private void configureWeb() {
 		bind(EditSupportRegistry.class).to(DefaultEditSupportRegistry.class);
 		bind(WebSocketManager.class).to(DefaultWebSocketManager.class);

-		bind(AttachmentUploadServlet.class);
-
 		contributeFromPackage(EditSupport.class, EditSupport.class);

 		bind(org.apache.wicket.protocol.http.WebApplication.class).to(WebApplication.class);


Do not deserialize data from job nodes in Kubernetes resource to avoid
security vulnerability

@@ -25,6 +25,7 @@

 import org.apache.commons.lang.SerializationUtils;

+import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;

 import io.onedev.commons.utils.TarUtils;
@@ -73,20 +74,19 @@ public byte[] getJobContext() {
 	@Consumes(MediaType.APPLICATION_OCTET_STREAM)
 	@Produces(MediaType.APPLICATION_OCTET_STREAM)
     @POST
-    public byte[] allocateJobCaches(byte[] cacheAllocationRequestBytes) {
-		CacheAllocationRequest allocationRequest = (CacheAllocationRequest) SerializationUtils
-				.deserialize(cacheAllocationRequestBytes);
+    public byte[] allocateJobCaches(String cacheAllocationRequestString) {
+		CacheAllocationRequest cacheAllocationRequest = CacheAllocationRequest.fromString(cacheAllocationRequestString);
 		return SerializationUtils.serialize((Serializable) jobManager.allocateJobCaches(
-				getJobToken(), allocationRequest.getCurrentTime(), allocationRequest.getInstances()));
+				getJobToken(), cacheAllocationRequest.getCurrentTime(), cacheAllocationRequest.getInstances()));
     }

 	@Path("/report-job-caches")
 	@Consumes(MediaType.APPLICATION_OCTET_STREAM)
 	@POST
-	public void reportJobCaches(byte[] cacheInstanceBytes) {
-		@SuppressWarnings("unchecked")
-		Collection<CacheInstance> cacheInstances = (Collection<CacheInstance>) SerializationUtils
-				.deserialize(cacheInstanceBytes);
+	public void reportJobCaches(String cacheInstancesString) {
+		Collection<CacheInstance> cacheInstances = new ArrayList<>();
+		for (String field: Splitter.on(';').omitEmptyStrings().split(cacheInstancesString))
+			cacheInstances.add(CacheInstance.fromString(field));
 		jobManager.reportJobCaches(getJobToken(), cacheInstances);
 	}


Fix the issue provider can be wrong when requesting slice permission

SlicePermissionActivity reads provider_pkg from intent, which can be
modified at will. As a result user might see incorrect package name in
the dialog granting slice permission.

Bug: 159145361
Test: manual
Merged-In: I8b66c02786df4096dad74b7e76255d5ddd1d609d
Change-Id: I8b66c02786df4096dad74b7e76255d5ddd1d609d
(cherry picked from commit 4344e632953b103910b48d43f4eb226b38ed5048)

@@ -153,6 +153,7 @@ public abstract class SliceProvider extends ContentProvider {
      */
     public static final String EXTRA_PKG = "pkg";
     /**
+     * @Deprecated provider pkg is now being extracted in SlicePermissionActivity
      * @hide
      */
     public static final String EXTRA_PROVIDER_PKG = "provider_pkg";


Fix request verification (#3969)

* Add tests reproducing the issue.

* Strip `'` from path for route search.

* Add information on contributing, community support and commercial support to project site.

* Add checking for "#". Add logging.

* Add test.

* Revert "Add test."

This reverts commit 81875849

* Revert "Add checking for "#". Add logging."

This reverts commit 0232945a

* Verify for urls.

* Verify for encoded and double-encoded Strings.

* Verify insecure paths with `..\` and '..//'. Add more tests.

@@ -213,6 +213,10 @@ protected boolean matchesIgnoredPatterns(String path) {
 	private String adjustPath(final String path) {
 		String adjustedPath = path;

+		if (path.startsWith("'")) {
+			adjustedPath = path.substring(1);
+		}
+
 		if (RequestUtils.isDispatcherServletRequest()
 				&& StringUtils.hasText(this.dispatcherServletPath)) {
 			if (!this.dispatcherServletPath.equals("/")


@@ -63,6 +63,10 @@ private Feature(boolean defaultState) {
     private final static double MATH_POW_2_10 = Math.pow(2, 10);
     private final static double MATH_POW_2_NEG14 = Math.pow(2, -14);

+    // 2.11.4: [dataformats-binary#186] Avoid OOME/DoS for bigger binary;
+    //  read only up to 250k
+    protected final static int LONGEST_NON_CHUNKED_BINARY = 250_000;
+
     /*
     /**********************************************************
     /* Configuration
@@ -1706,13 +1710,15 @@ public int readBinaryValue(Base64Variant b64variant, OutputStream out) throws IO
         }
     }

-    private int _readAndWriteBytes(OutputStream out, int total) throws IOException
+    private int _readAndWriteBytes(OutputStream out, final int total) throws IOException
     {
         int left = total;
         while (left > 0) {
             int avail = _inputEnd - _inputPtr;
             if (_inputPtr >= _inputEnd) {
-                loadMoreGuaranteed();
+                if (!loadMore()) {
+                    _reportIncompleteBinaryRead(total, total-left);
+                }
                 avail = _inputEnd - _inputPtr;
             }
             int count = Math.min(avail, left);
@@ -2425,33 +2431,55 @@ private final int _nextChunkedByte2() throws IOException
         // either way, got it now
         return _inputBuffer[_inputPtr++];
     }
-
+
+    /**
+     * Helper called to complete reading of binary data ("byte string") in
+     * case contents are needed.
+     */
     @SuppressWarnings("resource")
     protected byte[] _finishBytes(int len) throws IOException
     {
+        // Chunked?
         // First, simple: non-chunked
-        if (len >= 0) {
+        if (len <= 0) {
             if (len == 0) {
                 return NO_BYTES;
             }
-            byte[] b = new byte[len];
-            if (_inputPtr >= _inputEnd) {
-                loadMoreGuaranteed();
+            return _finishChunkedBytes();
+        }
+        // Non-chunked, contiguous
+        if (len > LONGEST_NON_CHUNKED_BINARY) {
+            // [dataformats-binary#186]: avoid immediate allocation for longest
+            return _finishLongContiguousBytes(len);
+        }
+
+        final byte[] b = new byte[len];
+        final int expLen = len;
+        if (_inputPtr >= _inputEnd) {
+            if (!loadMore()) {
+                _reportIncompleteBinaryRead(expLen, 0);
             }
-            int ptr = 0;
-            while (true) {
-                int toAdd = Math.min(len, _inputEnd - _inputPtr);
-                System.arraycopy(_inputBuffer, _inputPtr, b, ptr, toAdd);
-                _inputPtr += toAdd;
-                ptr += toAdd;
-                len -= toAdd;
-                if (len <= 0) {
-                    return b;
-                }
-                loadMoreGuaranteed();
+        }
+
+        int ptr = 0;
+        while (true) {
+            int toAdd = Math.min(len, _inputEnd - _inputPtr);
+            System.arraycopy(_inputBuffer, _inputPtr, b, ptr, toAdd);
+            _inputPtr += toAdd;
+            ptr += toAdd;
+            len -= toAdd;
+            if (len <= 0) {
+                return b;
+            }
+            if (!loadMore()) {
+                _reportIncompleteBinaryRead(expLen, ptr);
             }
         }
+    }

+    // @since 2.12
+    protected byte[] _finishChunkedBytes() throws IOException
+    {
         // or, if not, chunked...
         ByteArrayBuilder bb = _getByteArrayBuilder();
         while (true) {
@@ -2468,14 +2496,17 @@ protected byte[] _finishBytes(int len) throws IOException
                 throw _constructError("Mismatched chunk in chunked content: expected "+CBORConstants.MAJOR_TYPE_BYTES
                         +" but encountered "+type);
             }
-            len = _decodeExplicitLength(ch & 0x1F);
+            int len = _decodeExplicitLength(ch & 0x1F);
             if (len < 0) {
                 throw _constructError("Illegal chunked-length indicator within chunked-length value (type "+CBORConstants.MAJOR_TYPE_BYTES+")");
             }
+            final int chunkLen = len;
             while (len > 0) {
                 int avail = _inputEnd - _inputPtr;
                 if (_inputPtr >= _inputEnd) {
-                    loadMoreGuaranteed();
+                    if (!loadMore()) {
+                        _reportIncompleteBinaryRead(chunkLen, chunkLen-len);
+                    }
                     avail = _inputEnd - _inputPtr;
                 }
                 int count = Math.min(avail, len);
@@ -2486,7 +2517,33 @@ protected byte[] _finishBytes(int len) throws IOException
         }
         return bb.toByteArray();
     }
-
+
+    // @since 2.12
+    protected byte[] _finishLongContiguousBytes(final int expLen) throws IOException
+    {
+        int left = expLen;
+
+        // 04-Dec-2020, tatu: Let's NOT use recycled instance since we have much
+        //   longer content and there is likely less benefit of trying to recycle
+        //   segments
+        try (final ByteArrayBuilder bb = new ByteArrayBuilder(LONGEST_NON_CHUNKED_BINARY >> 1)) {
+            while (left > 0) {
+                int avail = _inputEnd - _inputPtr;
+                if (avail <= 0) {
+                    if (!loadMore()) {
+                        _reportIncompleteBinaryRead(expLen, expLen-left);
+                    }
+                    avail = _inputEnd - _inputPtr;
+                }
+                int count = Math.min(avail, left);
+                bb.write(_inputBuffer, _inputPtr, count);
+                _inputPtr += count;
+                left -= count;
+            }
+            return bb.toByteArray();
+        }
+    }
+
     protected final JsonToken _decodeFieldName() throws IOException
     {
         if (_inputPtr >= _inputEnd) {
@@ -2635,9 +2692,8 @@ protected final void _decodeNonStringName(int ch) throws IOException
         } else if (type == CBORConstants.MAJOR_TYPE_INT_NEG) {
             name = _numberToName(ch, true);
         } else if (type == CBORConstants.MAJOR_TYPE_BYTES) {
-            /* 08-Sep-2014, tatu: As per [Issue#5], there are codecs
-             *   (f.ex. Perl module "CBOR::XS") that use Binary data...
-             */
+            // 08-Sep-2014, tatu: As per [Issue#5], there are codecs
+            //   (f.ex. Perl module "CBOR::XS") that use Binary data...
             final int blen = _decodeExplicitLength(ch & 0x1F);
             byte[] b = _finishBytes(blen);
             // TODO: Optimize, if this becomes commonly used & bottleneck; we have
@@ -3204,7 +3260,7 @@ private final int _decodeChunkedUTF8_4(int c) throws IOException
     /**********************************************************
      */

-    protected final boolean loadMore() throws IOException
+    protected boolean loadMore() throws IOException
     {
         if (_inputStream != null) {
             _currInputProcessed += _inputEnd;
@@ -3225,7 +3281,7 @@ protected final boolean loadMore() throws IOException
         return false;
     }

-    protected final void loadMoreGuaranteed() throws IOException {
+    protected void loadMoreGuaranteed() throws IOException {
         if (!loadMore()) { _reportInvalidEOF(); }
     }

@@ -3351,6 +3407,13 @@ protected void _reportInvalidOther(int mask, int ptr) throws JsonParseException
         _reportInvalidOther(mask);
     }

+    // @since 2.12
+    protected void _reportIncompleteBinaryRead(int expLen, int actLen) throws IOException
+    {
+        _reportInvalidEOF(String.format(" for Binary value: expected %d bytes, only found %d",
+                expLen, actLen), _currToken);
+    }
+
     /*
     /**********************************************************
     /* Internal methods, other


Use Files.createTempFile(...) to ensure the file is created with proper permissions

Motivation:

File.createTempFile(String, String)` will create a temporary file in the system temporary directory if the 'java.io.tmpdir'. The permissions on that file utilize the umask. In a majority of cases, this means that the file that java creates has the permissions: `-rw-r--r--`, thus, any other local user on that system can read the contents of that file.
This can be a security concern if any sensitive data is stored in this file.

This was reported by Jonathan Leitschuh <jonathan.leitschuh@gmail.com> as a security problem.

Modifications:

Use Files.createTempFile(...) which will use safe-defaults when running on java 7 and later. If running on java 6 there isnt much we can do, which is fair enough as java 6 shouldnt be considered "safe" anyway.

Result:

Create temporary files with sane permissions by default.

@@ -177,7 +177,7 @@ public static void load(String originalName, ClassLoader loader) {
             String prefix = libname.substring(0, index);
             String suffix = libname.substring(index);

-            tmpFile = File.createTempFile(prefix, suffix, WORKDIR);
+            tmpFile = PlatformDependent.createTempFile(prefix, suffix, WORKDIR);
             in = url.openStream();
             out = new FileOutputStream(tmpFile);


Merge pull request from GHSA-7557-4v29-rqw6

Fix directory traversal

@@ -99,6 +99,7 @@
 import org.loklak.server.*;
 import org.loklak.stream.MQTTPublisher;
 import org.loklak.tools.DateParser;
+import org.loklak.tools.IO;
 import org.loklak.tools.OS;
 import org.loklak.tools.storage.*;
 import org.slf4j.Logger;
@@ -340,7 +341,7 @@ public static void init(Map<String, String> configMap, Path dataPath) throws Exc
         // elasticsearch will probably take some time until it is started up. We do some other stuff meanwhile..

         // create and document the data dump dir
-        assets = new File(datadir, "assets");
+        assets = new File(datadir, "assets").getAbsoluteFile();
         external_data = new File(datadir, "external");
         dictionaries = new File(external_data, "dictionaries");
         dictionaries.mkdirs();
@@ -525,8 +526,8 @@ public static Map<String, String> nodeSettings() {
     public static File getAssetFile(String screen_name, String id_str, String file) {
         String letter0 = ("" + screen_name.charAt(0)).toLowerCase();
         String letter1 = ("" + screen_name.charAt(1)).toLowerCase();
-        File storage_path = new File(new File(new File(assets, letter0), letter1), screen_name);
-        return new File(storage_path, id_str + "_" + file); // all assets for one user in one file
+        Path storage_path = IO.resolvePath(assets.toPath(), letter0, letter1, screen_name);
+        return IO.resolvePath(storage_path, id_str + "_" + file).toFile(); // all assets for one user in one file
     }

     public static Collection<File> getTweetOwnDumps(int count) {


Fix XXE vulnerabilities in multiple add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>

@@ -105,6 +105,12 @@ public String getNamespaceURI(@Nullable String prefix) {
     public Client() {
         documentBuilderFactory.setNamespaceAware(true);
         try {
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            documentBuilderFactory.setXIncludeAware(false);
+            documentBuilderFactory.setExpandEntityReferences(false);
             documentBuilder = documentBuilderFactory.newDocumentBuilder();
         } catch (ParserConfigurationException e) {
             throw new IllegalStateException(e);


@@ -81,6 +81,12 @@ public static HashMap<String, String> buildHashMap(String... data) {
     public static @Nullable Document loadXMLFromString(String xml) {
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            factory.setXIncludeAware(false);
+            factory.setExpandEntityReferences(false);
             DocumentBuilder builder = factory.newDocumentBuilder();
             InputSource is = new InputSource(new StringReader(xml));
             return builder.parse(is);


Merge pull request from GHSA-f256-j965-7f32

Motivation:

We also need to ensure that all the header validation is done when a single header with the endStream flag is received

Modifications:

- Adjust code to always enforce the validation
- Add more unit tests

Result:

Always correctly validate

@@ -353,10 +353,13 @@ public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers
                 short weight, boolean exclusive, int padding, boolean endOfStream) throws Http2Exception {
             Http2Stream stream = connection.stream(streamId);
             boolean allowHalfClosedRemote = false;
+            boolean isTrailers = false;
             if (stream == null && !connection.streamMayHaveExisted(streamId)) {
                 stream = connection.remote().createStream(streamId, endOfStream);
                 // Allow the state to be HALF_CLOSE_REMOTE if we're creating it in that state.
                 allowHalfClosedRemote = stream.state() == HALF_CLOSED_REMOTE;
+            } else if (stream != null) {
+                isTrailers = stream.isHeadersReceived();
             }

             if (shouldIgnoreHeadersOrDataFrame(ctx, streamId, stream, "HEADERS")) {
@@ -394,7 +397,7 @@ public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers
                             stream.state());
             }

-            if (!stream.isHeadersReceived()) {
+            if (!isTrailers) {
                 // extract the content-length header
                 List<? extends CharSequence> contentLength = headers.getAll(HttpHeaderNames.CONTENT_LENGTH);
                 if (contentLength != null && !contentLength.isEmpty()) {


Merge pull request from GHSA-hpv8-9rq5-hq7w

security: fix CWE-378 CWE-200 CWE-732 - use java.nio.files

@@ -58,7 +58,6 @@ public Map<String, String> createOptions() {
         ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
         builder.put(CodegenConstants.IMPL_FOLDER, IMPL_FOLDER_VALUE)
             .put(JavaClientCodegen.DATE_LIBRARY, "joda") //java.lang.IllegalArgumentException: Multiple entries with same key: dateLibrary=joda and dateLibrary=joda
-            .put(JavaClientCodegen.SUPPORT_JAVA6, "false")
             .put("title", "Test title")
             .put(CodegenConstants.MODEL_PACKAGE, MODEL_PACKAGE_VALUE)
             .put(CodegenConstants.API_PACKAGE, API_PACKAGE_VALUE)


@@ -1,55 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client;
-
-
-public class StringUtil {
-  /**
-   * Check if the given array contains the given value (with case-insensitive comparison).
-   *
-   * @param array The array
-   * @param value The value to search
-   * @return true if the array contains the value
-   */
-  public static boolean containsIgnoreCase(String[] array, String value) {
-    for (String str : array) {
-      if (value == null && str == null) return true;
-      if (value != null && value.equalsIgnoreCase(str)) return true;
-    }
-    return false;
-  }
-
-  /**
-   * Join an array of strings with the given separator.
-   * <p>
-   * Note: This might be replaced by utility method from commons-lang or guava someday
-   * if one of those libraries is added as dependency.
-   * </p>
-   *
-   * @param array     The array of strings
-   * @param separator The separator
-   * @return the resulting string
-   */
-  public static String join(String[] array, String separator) {
-    int len = array.length;
-    if (len == 0) return "";
-
-    StringBuilder out = new StringBuilder();
-    out.append(array[0]);
-    for (int i = 1; i < len; i++) {
-      out.append(separator).append(array[i]);
-    }
-    return out.toString();
-  }
-}


@@ -1,39 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client.auth;
-
-import io.swagger.client.Pair;
-
-import java.util.Map;
-import java.util.List;
-
-
-public class OAuth implements Authentication {
-  private String accessToken;
-
-  public String getAccessToken() {
-    return accessToken;
-  }
-
-  public void setAccessToken(String accessToken) {
-    this.accessToken = accessToken;
-  }
-
-  @Override
-  public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
-    if (accessToken != null) {
-      headerParams.put("Authorization", "Bearer " + accessToken);
-    }
-  }
-}


@@ -1,113 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client.model;
-
-import org.apache.commons.lang3.ObjectUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
- * Category
- */
-
-public class Category {
-  @JsonProperty("id")
-  private Long id = null;
-
-  @JsonProperty("name")
-  private String name = null;
-
-  public Category id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @ApiModelProperty(value = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public Category name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @ApiModelProperty(value = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-
-  @Override
-  public boolean equals(java.lang.Object o) {
-  if (this == o) {
-    return true;
-  }
-  if (o == null || getClass() != o.getClass()) {
-    return false;
-  }
-    Category category = (Category) o;
-    return ObjectUtils.equals(this.id, category.id) &&
-    ObjectUtils.equals(this.name, category.name);
-  }
-
-  @Override
-  public int hashCode() {
-    return ObjectUtils.hashCodeMulti(id, name);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class Category {\n");
-
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(java.lang.Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
-


@@ -1,167 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client.model;
-
-import org.apache.commons.lang3.ObjectUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * MapTest
- */
-
-public class MapTest {
-  @JsonProperty("map_map_of_string")
-  private Map<String, Map<String, String>> mapMapOfString = null;
-
-  /**
-   * Gets or Sets inner
-   */
-  public enum InnerEnum {
-    UPPER("UPPER"),
-
-    LOWER("lower");
-
-    private String value;
-
-    InnerEnum(String value) {
-      this.value = value;
-    }
-
-    @JsonValue
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-
-    @JsonCreator
-    public static InnerEnum fromValue(String text) {
-      for (InnerEnum b : InnerEnum.values()) {
-        if (String.valueOf(b.value).equals(text)) {
-          return b;
-        }
-      }
-      return null;
-    }
-  }
-
-  @JsonProperty("map_of_enum_string")
-  private Map<String, InnerEnum> mapOfEnumString = null;
-
-  public MapTest mapMapOfString(Map<String, Map<String, String>> mapMapOfString) {
-    this.mapMapOfString = mapMapOfString;
-    return this;
-  }
-
-  public MapTest putMapMapOfStringItem(String key, Map<String, String> mapMapOfStringItem) {
-    if (this.mapMapOfString == null) {
-      this.mapMapOfString = new HashMap<String, Map<String, String>>();
-    }
-    this.mapMapOfString.put(key, mapMapOfStringItem);
-    return this;
-  }
-
-   /**
-   * Get mapMapOfString
-   * @return mapMapOfString
-  **/
-  @ApiModelProperty(value = "")
-  public Map<String, Map<String, String>> getMapMapOfString() {
-    return mapMapOfString;
-  }
-
-  public void setMapMapOfString(Map<String, Map<String, String>> mapMapOfString) {
-    this.mapMapOfString = mapMapOfString;
-  }
-
-  public MapTest mapOfEnumString(Map<String, InnerEnum> mapOfEnumString) {
-    this.mapOfEnumString = mapOfEnumString;
-    return this;
-  }
-
-  public MapTest putMapOfEnumStringItem(String key, InnerEnum mapOfEnumStringItem) {
-    if (this.mapOfEnumString == null) {
-      this.mapOfEnumString = new HashMap<String, InnerEnum>();
-    }
-    this.mapOfEnumString.put(key, mapOfEnumStringItem);
-    return this;
-  }
-
-   /**
-   * Get mapOfEnumString
-   * @return mapOfEnumString
-  **/
-  @ApiModelProperty(value = "")
-  public Map<String, InnerEnum> getMapOfEnumString() {
-    return mapOfEnumString;
-  }
-
-  public void setMapOfEnumString(Map<String, InnerEnum> mapOfEnumString) {
-    this.mapOfEnumString = mapOfEnumString;
-  }
-
-
-  @Override
-  public boolean equals(java.lang.Object o) {
-  if (this == o) {
-    return true;
-  }
-  if (o == null || getClass() != o.getClass()) {
-    return false;
-  }
-    MapTest mapTest = (MapTest) o;
-    return ObjectUtils.equals(this.mapMapOfString, mapTest.mapMapOfString) &&
-    ObjectUtils.equals(this.mapOfEnumString, mapTest.mapOfEnumString);
-  }
-
-  @Override
-  public int hashCode() {
-    return ObjectUtils.hashCodeMulti(mapMapOfString, mapOfEnumString);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class MapTest {\n");
-
-    sb.append("    mapMapOfString: ").append(toIndentedString(mapMapOfString)).append("\n");
-    sb.append("    mapOfEnumString: ").append(toIndentedString(mapOfEnumString)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(java.lang.Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
-


@@ -1,243 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client.model;
-
-import org.apache.commons.lang3.ObjectUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import org.threeten.bp.OffsetDateTime;
-
-/**
- * Order
- */
-
-public class Order {
-  @JsonProperty("id")
-  private Long id = null;
-
-  @JsonProperty("petId")
-  private Long petId = null;
-
-  @JsonProperty("quantity")
-  private Integer quantity = null;
-
-  @JsonProperty("shipDate")
-  private OffsetDateTime shipDate = null;
-
-  /**
-   * Order Status
-   */
-  public enum StatusEnum {
-    PLACED("placed"),
-
-    APPROVED("approved"),
-
-    DELIVERED("delivered");
-
-    private String value;
-
-    StatusEnum(String value) {
-      this.value = value;
-    }
-
-    @JsonValue
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-
-    @JsonCreator
-    public static StatusEnum fromValue(String text) {
-      for (StatusEnum b : StatusEnum.values()) {
-        if (String.valueOf(b.value).equals(text)) {
-          return b;
-        }
-      }
-      return null;
-    }
-  }
-
-  @JsonProperty("status")
-  private StatusEnum status = null;
-
-  @JsonProperty("complete")
-  private Boolean complete = false;
-
-  public Order id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @ApiModelProperty(value = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public Order petId(Long petId) {
-    this.petId = petId;
-    return this;
-  }
-
-   /**
-   * Get petId
-   * @return petId
-  **/
-  @ApiModelProperty(value = "")
-  public Long getPetId() {
-    return petId;
-  }
-
-  public void setPetId(Long petId) {
-    this.petId = petId;
-  }
-
-  public Order quantity(Integer quantity) {
-    this.quantity = quantity;
-    return this;
-  }
-
-   /**
-   * Get quantity
-   * @return quantity
-  **/
-  @ApiModelProperty(value = "")
-  public Integer getQuantity() {
-    return quantity;
-  }
-
-  public void setQuantity(Integer quantity) {
-    this.quantity = quantity;
-  }
-
-  public Order shipDate(OffsetDateTime shipDate) {
-    this.shipDate = shipDate;
-    return this;
-  }
-
-   /**
-   * Get shipDate
-   * @return shipDate
-  **/
-  @ApiModelProperty(value = "")
-  public OffsetDateTime getShipDate() {
-    return shipDate;
-  }
-
-  public void setShipDate(OffsetDateTime shipDate) {
-    this.shipDate = shipDate;
-  }
-
-  public Order status(StatusEnum status) {
-    this.status = status;
-    return this;
-  }
-
-   /**
-   * Order Status
-   * @return status
-  **/
-  @ApiModelProperty(value = "Order Status")
-  public StatusEnum getStatus() {
-    return status;
-  }
-
-  public void setStatus(StatusEnum status) {
-    this.status = status;
-  }
-
-  public Order complete(Boolean complete) {
-    this.complete = complete;
-    return this;
-  }
-
-   /**
-   * Get complete
-   * @return complete
-  **/
-  @ApiModelProperty(value = "")
-  public Boolean isComplete() {
-    return complete;
-  }
-
-  public void setComplete(Boolean complete) {
-    this.complete = complete;
-  }
-
-
-  @Override
-  public boolean equals(java.lang.Object o) {
-  if (this == o) {
-    return true;
-  }
-  if (o == null || getClass() != o.getClass()) {
-    return false;
-  }
-    Order order = (Order) o;
-    return ObjectUtils.equals(this.id, order.id) &&
-    ObjectUtils.equals(this.petId, order.petId) &&
-    ObjectUtils.equals(this.quantity, order.quantity) &&
-    ObjectUtils.equals(this.shipDate, order.shipDate) &&
-    ObjectUtils.equals(this.status, order.status) &&
-    ObjectUtils.equals(this.complete, order.complete);
-  }
-
-  @Override
-  public int hashCode() {
-    return ObjectUtils.hashCodeMulti(id, petId, quantity, shipDate, status, complete);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class Order {\n");
-
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    petId: ").append(toIndentedString(petId)).append("\n");
-    sb.append("    quantity: ").append(toIndentedString(quantity)).append("\n");
-    sb.append("    shipDate: ").append(toIndentedString(shipDate)).append("\n");
-    sb.append("    status: ").append(toIndentedString(status)).append("\n");
-    sb.append("    complete: ").append(toIndentedString(complete)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(java.lang.Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
-


@@ -1,51 +0,0 @@
-/*
- * Swagger Petstore
- * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
- *
- * OpenAPI spec version: 1.0.0
- * Contact: apiteam@swagger.io
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiException;
-import io.swagger.client.model.Client;
-import org.junit.Test;
-import org.junit.Ignore;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * API tests for FakeClassnameTags123Api
- */
-@Ignore
-public class FakeClassnameTags123ApiTest {
-
-    private final FakeClassnameTags123Api api = new FakeClassnameTags123Api();
-
-
-    /**
-     * To test class name in snake case
-     *
-     *
-     *
-     * @throws ApiException
-     *          if the Api call fails
-     */
-    @Test
-    public void testClassnameTest() throws ApiException {
-        Client body = null;
-        Client response = api.testClassname(body);
-
-        // TODO: test validations
-    }
-
-}


Merge pull request from GHSA-pc22-3g76-gm6j

 security: use java.nio.files in Generator.

@@ -15,6 +15,7 @@
 import org.slf4j.LoggerFactory;

 import java.io.File;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -173,9 +174,7 @@ public static InputOption serverOptions(@SuppressWarnings("unused") String langu

     protected static File getTmpFolder() {
         try {
-            File outputFolder = File.createTempFile("codegen-", "-tmp");
-            outputFolder.delete();
-            outputFolder.mkdir();
+            File outputFolder = Files.createTempDirectory("codegen-").toFile();
             outputFolder.deleteOnExit();
             return outputFolder;
         } catch (Exception e) {


[KEYCLOAK-16521] - Fixing secret for non-confidential clients

@@ -79,11 +79,10 @@ private void addAccountApiRoles(RealmModel realm) {

     protected void addAccountConsoleClient(RealmModel realm) {
         if (realm.getClientByClientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID) == null) {
-            ClientModel client = KeycloakModelUtils.createClient(realm, Constants.ACCOUNT_CONSOLE_CLIENT_ID);
+            ClientModel client = KeycloakModelUtils.createPublicClient(realm, Constants.ACCOUNT_CONSOLE_CLIENT_ID);
             client.setName("${client_" + Constants.ACCOUNT_CONSOLE_CLIENT_ID + "}");
             client.setEnabled(true);
             client.setFullScopeAllowed(false);
-            client.setPublicClient(true);
             client.setDirectAccessGrantsEnabled(false);

             client.setRootUrl(Constants.AUTH_BASE_URL_PROP);


@@ -106,7 +106,9 @@ private ClientRepresentation createClient() {
     public void createClientVerify() {
         String id = createClient().getId();

-        assertNotNull(realm.clients().get(id));
+        ClientResource client = realm.clients().get(id);
+        assertNotNull(client);
+        assertNull(client.toRepresentation().getSecret());
         Assert.assertNames(realm.clients().findAll(), "account", "account-console", "realm-management", "security-admin-console", "broker", "my-app", Constants.ADMIN_CLI_CLIENT_ID);
     }


fix: avoid exposing ServletContext resources via StaticFileServer (#10269)

fix: avoid exposing ServletContext resources via StaticFileServer in OSGi

fixes #10260

@@ -15,12 +15,13 @@
  */
 package com.vaadin.flow.osgi;

-import java.util.Dictionary;
-import java.util.Hashtable;
-
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;

+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -29,18 +30,39 @@
 import org.osgi.util.tracker.ServiceTracker;

 import com.vaadin.flow.server.Constants;
+import com.vaadin.flow.server.StaticFileHandler;
+import com.vaadin.flow.server.StaticFileServer;
 import com.vaadin.flow.server.VaadinServletConfiguration;
+import com.vaadin.flow.server.VaadinServletService;
 import com.vaadin.flow.uitest.servlet.Es6UrlViewTestServlet;
 import com.vaadin.flow.uitest.servlet.ProductionModeTimingDataViewTestServlet;
 import com.vaadin.flow.uitest.servlet.ProductionModeViewTestServlet;
 import com.vaadin.flow.uitest.servlet.RouterTestServlet;
 import com.vaadin.flow.uitest.servlet.ViewTestServlet;
-import com.vaadin.flow.uitest.servlet.WebJarsServlet;

 public class Activator implements BundleActivator {

     private ServiceTracker<HttpService, HttpService> httpTracker;

+    private static class ItStaticFileServer extends StaticFileServer {
+
+        private final VaadinServletService servletService;
+
+        private ItStaticFileServer(VaadinServletService servletService) {
+            super(servletService);
+            this.servletService = servletService;
+        }
+
+        @Override
+        protected URL getStaticResource(String path) {
+            if (path.endsWith(".class")) {
+                return null;
+            }
+            return servletService.getStaticResource(path);
+        }
+
+    }
+
     @VaadinServletConfiguration(productionMode = false)
     private static class FixedViewServlet extends ViewTestServlet {
         @Override
@@ -49,6 +71,12 @@ public void init(ServletConfig servletConfig) throws ServletException {

             getService().setClassLoader(getClass().getClassLoader());
         }
+
+        @Override
+        protected StaticFileHandler createStaticFileHandler(
+                VaadinServletService servletService) {
+            return new ItStaticFileServer(servletService);
+        }
     }

     @VaadinServletConfiguration(productionMode = false)
@@ -59,6 +87,12 @@ public void init(ServletConfig servletConfig) throws ServletException {

             getService().setClassLoader(getClass().getClassLoader());
         }
+
+        @Override
+        protected StaticFileHandler createStaticFileHandler(
+                VaadinServletService servletService) {
+            return new ItStaticFileServer(servletService);
+        }
     }

     @VaadinServletConfiguration(productionMode = true)
@@ -71,6 +105,12 @@ public void init(ServletConfig servletConfig) throws ServletException {

             getService().setClassLoader(getClass().getClassLoader());
         }
+
+        @Override
+        protected StaticFileHandler createStaticFileHandler(
+                VaadinServletService servletService) {
+            return new ItStaticFileServer(servletService);
+        }
     }

     @VaadinServletConfiguration(productionMode = true)
@@ -82,6 +122,12 @@ public void init(ServletConfig servletConfig) throws ServletException {

             getService().setClassLoader(getClass().getClassLoader());
         }
+
+        @Override
+        protected StaticFileHandler createStaticFileHandler(
+                VaadinServletService servletService) {
+            return new ItStaticFileServer(servletService);
+        }
     }

     @VaadinServletConfiguration(productionMode = true)
@@ -93,6 +139,12 @@ public void init(ServletConfig servletConfig) throws ServletException {
             getService().setClassLoader(getClass().getClassLoader());
         }

+        @Override
+        protected StaticFileHandler createStaticFileHandler(
+                VaadinServletService servletService) {
+            return new ItStaticFileServer(servletService);
+        }
+
     }

     @Override
@@ -128,7 +180,7 @@ public HttpService addingService(
                     httpService.registerServlet("/context/*",
                             new FixedViewServlet(), dictionary, null);
                     httpService.registerServlet("/frontend/*",
-                            new WebJarsServlet(), dictionary, null);
+                            new FixedViewServlet(), dictionary, null);
                     httpService.registerServlet("/new-router-session/*",
                             new FixedRouterServlet(), dictionary, null);
                     httpService.registerServlet("/view-production/*",


refactor: use StaticFileHandler as a service (#10229)

refactor: use StaticFileHandler as a service

Part of vaadin/osgi#50

@@ -32,6 +32,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;

@@ -42,7 +44,12 @@

 import com.vaadin.flow.di.LookupInitializer.AppShellPredicateImpl;
 import com.vaadin.flow.di.LookupInitializer.ResourceProviderImpl;
+import com.vaadin.flow.function.DeploymentConfiguration;
 import com.vaadin.flow.function.VaadinApplicationInitializationBootstrap;
+import com.vaadin.flow.server.StaticFileHandler;
+import com.vaadin.flow.server.StaticFileHandlerFactory;
+import com.vaadin.flow.server.StaticFileServer;
+import com.vaadin.flow.server.VaadinService;
 import com.vaadin.flow.server.startup.AppShellPredicate;
 import com.vaadin.flow.server.startup.ApplicationConfigurationFactory;
 import com.vaadin.flow.server.startup.DefaultApplicationConfigurationFactory;
@@ -54,7 +61,7 @@
 import elemental.json.Json;
 import elemental.json.JsonObject;

-public class LookupIntializerTest {
+public class LookupInitializerTest {

     private LookupInitializer initializer = new LookupInitializer();

@@ -89,6 +96,54 @@ public void initialize_noResourcePorvider_defaultResourceProviderIsCreated()
         assertResourceProvider(lookup.lookup(ResourceProvider.class));
     }

+    @Test
+    public void initialize_noStaticFileHandlerFactory_defaultStaticFileHandlerFactoryCreated()
+            throws ServletException {
+        AtomicReference<Lookup> capture = new AtomicReference<>();
+        initializer.initialize(null, new HashMap<>(), capture::set);
+
+        Lookup lookup = capture.get();
+        StaticFileHandlerFactory factory = lookup
+                .lookup(StaticFileHandlerFactory.class);
+
+        VaadinService service = Mockito.mock(VaadinService.class);
+        DeploymentConfiguration configuration = Mockito
+                .mock(DeploymentConfiguration.class);
+        Mockito.when(service.getDeploymentConfiguration())
+                .thenReturn(configuration);
+        ClassLoader loader = Mockito.mock(ClassLoader.class);
+        Mockito.when(service.getClassLoader()).thenReturn(loader);
+
+        StaticFileHandler handler = factory.createHandler(service);
+        Assert.assertNotNull(handler);
+        Assert.assertEquals(StaticFileServer.class, handler.getClass());
+    }
+
+    @Test
+    public void initialize_StaticFileHandlerFactoryIdDelegatedToEnsureService()
+            throws ServletException {
+        Map mock = Mockito.mock(Map.class);
+        AtomicBoolean factoryIsPassed = new AtomicBoolean();
+        initializer = new LookupInitializer() {
+
+            @Override
+            protected <T> void ensureService(
+                    Map<Class<?>, Collection<Class<?>>> services,
+                    Class<T> serviceType, Class<? extends T> serviceImpl) {
+                Assert.assertSame(mock, services);
+                if (StaticFileHandlerFactory.class.equals(serviceType)) {
+                    factoryIsPassed.set(true);
+                }
+            }
+        };
+
+        AtomicReference<Lookup> capture = new AtomicReference<>();
+
+        initializer.initialize(null, mock, capture::set);
+
+        Assert.assertTrue(factoryIsPassed.get());
+    }
+
     @Test
     public void initialize_hasOneTimeInitializerPredicate_predicateReturnsTrue()
             throws ServletException, IOException {
@@ -246,6 +301,36 @@ public void initialize_callEnsureMethodsAndBootstrap()
         Mockito.verify(bootstrap).bootstrap(Mockito.any());
     }

+    @Test
+    public void ensureService_noServiceProvided_defaultIsUsed() {
+        Map<Class<?>, Collection<Class<?>>> services = new HashMap<>();
+        initializer.ensureService(services, List.class, ArrayList.class);
+
+        Assert.assertEquals(1, services.size());
+        Collection<Class<?>> collection = services.get(List.class);
+        Assert.assertEquals(1, collection.size());
+        Assert.assertEquals(ArrayList.class, collection.iterator().next());
+    }
+
+    @Test
+    public void ensureService_defaultServiceProvided_defaultIsUsed() {
+        Map<Class<?>, Collection<Class<?>>> services = new HashMap<>();
+        services.put(List.class, Collections.singleton(ArrayList.class));
+        initializer.ensureService(services, List.class, ArrayList.class);
+
+        Assert.assertEquals(1, services.size());
+        Collection<Class<?>> collection = services.get(List.class);
+        Assert.assertEquals(1, collection.size());
+        Assert.assertEquals(ArrayList.class, collection.iterator().next());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void ensureService_severalServicesProvided_throws() {
+        Map<Class<?>, Collection<Class<?>>> services = new HashMap<>();
+        services.put(List.class, Arrays.asList(Vector.class, LinkedList.class));
+        initializer.ensureService(services, List.class, ArrayList.class);
+    }
+
     private void assertResourceProvider(ResourceProvider resourceProvider)
             throws IOException {
         Assert.assertEquals(ResourceProviderImpl.class,


[Security Fix]Use Vaadin's own ObjectMapper instead of the one from Spring (#8016)

@@ -19,15 +19,24 @@
 import java.lang.reflect.Method;

 import com.vaadin.flow.server.frontend.FrontendUtils;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
 import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.vaadin.flow.server.connect.auth.VaadinConnectAccessChecker;

+import static com.vaadin.flow.server.connect.VaadinConnectController.VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER;
+
 /**
  * A configuration class for customizing the {@link VaadinConnectController}
  * class.
@@ -137,4 +146,24 @@ public VaadinConnectAccessChecker accessChecker() {
     public ExplicitNullableTypeChecker typeChecker() {
         return new ExplicitNullableTypeChecker();
     }
+
+    /**
+     * Registers a {@link ObjectMapper} bean instance.
+     *
+     * @param context
+     *            Spring application context
+     * @return the object mapper for endpoint.
+     */
+    @Bean
+    @Qualifier(VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER)
+    public ObjectMapper vaadinEndpointMapper(ApplicationContext context) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        JacksonProperties jacksonProperties = context
+                .getBean(JacksonProperties.class);
+        if (jacksonProperties.getVisibility().isEmpty()) {
+            objectMapper.setVisibility(PropertyAccessor.ALL,
+                    JsonAutoDetect.Visibility.ANY);
+        }
+        return objectMapper;
+    }
 }


@@ -24,10 +24,7 @@
 import com.manydesigns.elements.reflection.JavaClassAccessor;
 import com.manydesigns.portofino.code.CodeBase;
 import com.manydesigns.portofino.security.SecurityLogic;
-import io.jsonwebtoken.Jwt;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.*;
 import io.jsonwebtoken.io.Decoders;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.shiro.authc.AuthenticationException;
@@ -100,9 +97,9 @@ public boolean supports(AuthenticationToken token) {

     public AuthenticationInfo loadAuthenticationInfo(JSONWebToken token) {
         Key key = getJWTKey();
-        Jwt jwt;
+        Jws<Claims> jwt;
         try {
-            jwt = Jwts.parser().setSigningKey(key).parse(token.getPrincipal());
+            jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(token.getPrincipal());
         } catch (JwtException e) {
             throw new AuthenticationException(e);
         }
@@ -111,8 +108,8 @@ public AuthenticationInfo loadAuthenticationInfo(JSONWebToken token) {
         return new SimpleAuthenticationInfo(principal, credentials, getName());
     }

-    protected Object extractPrincipalFromWebToken(Jwt jwt) {
-        Map body = (Map) jwt.getBody();
+    protected Object extractPrincipalFromWebToken(Jws<Claims> jwt) {
+        Map<String, Object> body = jwt.getBody();
         String base64Principal = (String) body.get("serialized-principal");
         byte[] serializedPrincipal = Base64.decode(base64Principal);
         Object principal;


@@ -78,7 +78,7 @@ public TilesViewResolver tilesViewResolver() {
   }

-/*  @Bean
+  @Bean
   public FilterRegistrationBean<XssFilter> croseSiteFilter(){
       FilterRegistrationBean<XssFilter> registrationBean
         = new FilterRegistrationBean<>();
@@ -87,7 +87,7 @@ public FilterRegistrationBean<XssFilter> croseSiteFilter(){
       registrationBean.addUrlPatterns("/*");

       return registrationBean;
-  }*/
+  }

   @Override
   public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {