From 617cb76575cb8fbbf0eadfe9ba7b0f44b1ddfef1 Mon Sep 17 00:00:00 2001
From: chrisisbeef
Date: Mon, 25 Jul 2011 06:24:52 +0000
Subject: [PATCH 001/812] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index 9ffe42b87..aa817e883 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.owasp.esapiesapi
- 2.0.1
+ 2.0.2-SNAPSHOTjar
@@ -66,9 +66,9 @@
- scm:svn:http://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.0.1
- scm:svn:https://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.0.1
- http://code.google.com/p/owasp-esapi-java/source/checkout/tags/esapi-2.0.1
+ scm:svn:http://owasp-esapi-java.googlecode.com/svn/trunk
+ scm:svn:https://owasp-esapi-java.googlecode.com/svn/trunk
+ http://code.google.com/p/owasp-esapi-java/source/checkout
From 2d6b884786093b1c04e746c1b35bac157772d594 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sun, 24 Jun 2012 01:04:46 +0000
Subject: [PATCH 002/812] 1) Fix Google issue # 271. 2) Fix to work with q4e
Eclipse plug-in.
---
pom.xml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index aa817e883..c48a1908f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
The Enterprise Security API (ESAPI) project is an OWASP project
to create simple strong security controls for every web platform.
Security controls are not simple to build. You can read about the
- hundreds of pitfalls for unwary developers on the OWASP website. By
+ hundreds of pitfalls for unwary developers on the OWASP web site. By
providing developers with a set of strong controls, we aim to
eliminate some of the complexity of creating secure web applications.
This can result in significant cost savings across the SDLC.
@@ -194,7 +194,7 @@
xomxom
- 1.1
+ 1.2.5org.beanshell
@@ -252,6 +252,7 @@
check-for-dependency-updates
+ compiledisplay-dependency-updatesdisplay-plugin-updates
From 899e828ddceba60e48e15d440b814fa7722a5b44 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sun, 24 Jun 2012 01:08:09 +0000
Subject: [PATCH 003/812] Fix Google Issue # 257
---
src/main/java/org/owasp/esapi/User.java | 2 +-
.../org/owasp/esapi/codecs/VBScriptCodec.java | 4 +-
.../esapi/reference/DefaultRandomizer.java | 3 +-
.../owasp/esapi/reference/DefaultUser.java | 3 +-
src/test/java/org/owasp/esapi/UserTest.java | 8 ++--
.../esapi/reference/AuthenticatorTest.java | 41 ++++++++++---------
.../owasp/esapi/reference/EncoderTest.java | 13 +++---
.../esapi/reference/HTTPUtilitiesTest.java | 9 ++--
.../reference/IntrusionDetectorTest.java | 5 ++-
.../owasp/esapi/reference/RandomizerTest.java | 5 ++-
.../org/owasp/esapi/reference/UserTest.java | 25 +++++------
.../esapi/reference/crypto/EncryptorTest.java | 8 ++--
.../java/org/owasp/esapi/waf/WAFTestCase.java | 4 +-
13 files changed, 70 insertions(+), 60 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/User.java b/src/main/java/org/owasp/esapi/User.java
index c8b70adb8..f6b9fa2d4 100644
--- a/src/main/java/org/owasp/esapi/User.java
+++ b/src/main/java/org/owasp/esapi/User.java
@@ -663,7 +663,7 @@ public void removeRole(String role) throws AuthenticationException {
* {@inheritDoc}
*/
public String resetCSRFToken() throws AuthenticationException {
- csrfToken = ESAPI.randomizer().getRandomString(8, Encoder.CHAR_ALPHANUMERICS);
+ csrfToken = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
return csrfToken;
}
diff --git a/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java b/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java
index ec3ed5f74..2dccbbd81 100644
--- a/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java
+++ b/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java
@@ -15,7 +15,7 @@
*/
package org.owasp.esapi.codecs;
-import org.owasp.esapi.reference.DefaultEncoder;
+import org.owasp.esapi.EncoderConstants;
/**
@@ -44,7 +44,7 @@ public String encode(char[] immune, String input) {
char c = input.charAt(i);
// handle normal characters and surround them with quotes
- if (containsCharacter(c, DefaultEncoder.CHAR_ALPHANUMERICS) || containsCharacter(c, immune)) {
+ if (containsCharacter(c, EncoderConstants.CHAR_ALPHANUMERICS) || containsCharacter(c, immune)) {
if ( encoding && i > 0 ) sb.append( "&" );
if ( !inquotes && i > 0 ) sb.append( "\"" );
sb.append( c );
diff --git a/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java b/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java
index 65b894c67..3272a6946 100644
--- a/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java
+++ b/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java
@@ -20,6 +20,7 @@
import java.util.UUID;
import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.EncoderConstants;
import org.owasp.esapi.Logger;
import org.owasp.esapi.Randomizer;
import org.owasp.esapi.errors.EncryptionException;
@@ -109,7 +110,7 @@ public float getRandomReal(float min, float max) {
* {@inheritDoc}
*/
public String getRandomFilename(String extension) {
- String fn = getRandomString(12, DefaultEncoder.CHAR_ALPHANUMERICS) + "." + extension;
+ String fn = getRandomString(12, EncoderConstants.CHAR_ALPHANUMERICS) + "." + extension;
logger.debug(Logger.SECURITY_SUCCESS, "Generated new random filename: " + fn );
return fn;
}
diff --git a/src/main/java/org/owasp/esapi/reference/DefaultUser.java b/src/main/java/org/owasp/esapi/reference/DefaultUser.java
index 40672dd85..6b24f1aae 100644
--- a/src/main/java/org/owasp/esapi/reference/DefaultUser.java
+++ b/src/main/java/org/owasp/esapi/reference/DefaultUser.java
@@ -16,6 +16,7 @@
package org.owasp.esapi.reference;
import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.EncoderConstants;
import org.owasp.esapi.HTTPUtilities;
import org.owasp.esapi.Logger;
import org.owasp.esapi.User;
@@ -472,7 +473,7 @@ public void removeRole(String role) {
public String resetCSRFToken() {
// user.csrfToken = ESAPI.encryptor().hash( session.getId(),user.name );
// user.csrfToken = ESAPI.encryptor().encrypt( address + ":" + ESAPI.encryptor().getTimeStamp();
- csrfToken = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ csrfToken = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
return csrfToken;
}
diff --git a/src/test/java/org/owasp/esapi/UserTest.java b/src/test/java/org/owasp/esapi/UserTest.java
index e79db714c..ab31d4808 100644
--- a/src/test/java/org/owasp/esapi/UserTest.java
+++ b/src/test/java/org/owasp/esapi/UserTest.java
@@ -19,8 +19,6 @@
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.owasp.esapi.reference.DefaultEncoder;
-
/**
* @author Jeff Williams (jeff.williams@aspectsecurity.com)
*/
@@ -45,9 +43,13 @@ public static Test suite() {
public void testAllMethods() throws Exception {
// create a user to test Anonymous
- String accountName = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String accountName = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
Authenticator instance = ESAPI.authenticator();
String password = instance.generateStrongPassword();
+
+ // Probably could skip the assignment here, but maybe someone had
+ // future plans to use this. So will just suppress warning for now.
+ @SuppressWarnings("unused")
User user = instance.createUser(accountName, password, password);
// test the rest of the Anonymous user
diff --git a/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java b/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java
index e24f9e547..31699ccfb 100644
--- a/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java
+++ b/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java
@@ -24,6 +24,7 @@
import org.owasp.esapi.Authenticator;
import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.EncoderConstants;
import org.owasp.esapi.HTTPUtilities;
import org.owasp.esapi.Logger;
import org.owasp.esapi.User;
@@ -89,7 +90,7 @@ protected void tearDown() throws Exception {
*/
public void testCreateUser() throws AuthenticationException, EncryptionException {
System.out.println("createUser");
- String accountName = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String accountName = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
Authenticator instance = ESAPI.authenticator();
String password = instance.generateStrongPassword();
User user = instance.createUser(accountName, password, password);
@@ -101,13 +102,13 @@ public void testCreateUser() throws AuthenticationException, EncryptionException
// success
}
try {
- instance.createUser(ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS), "password1", "password2"); // don't match
+ instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), "password1", "password2"); // don't match
fail();
} catch (AuthenticationException e) {
// success
}
try {
- instance.createUser(ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS), "weak1", "weak1"); // weak password
+ instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), "weak1", "weak1"); // weak password
fail();
} catch (AuthenticationException e) {
// success
@@ -119,7 +120,7 @@ public void testCreateUser() throws AuthenticationException, EncryptionException
// success
}
try {
- instance.createUser(ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS), null, null); // null password
+ instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), null, null); // null password
fail();
} catch (AuthenticationException e) {
// success
@@ -173,8 +174,8 @@ public void testGenerateStrongPassword() throws AuthenticationException {
public void testGetCurrentUser() throws Exception {
System.out.println("getCurrentUser");
Authenticator instance = ESAPI.authenticator();
- String username1 = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
- String username2 = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String username1 = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
+ String username2 = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
User user1 = instance.createUser(username1, "getCurrentUser", "getCurrentUser");
User user2 = instance.createUser(username2, "getCurrentUser", "getCurrentUser");
user1.enable();
@@ -228,10 +229,10 @@ public void testGetUser() throws AuthenticationException {
System.out.println("getUser");
Authenticator instance = ESAPI.authenticator();
String password = instance.generateStrongPassword();
- String accountName=ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
instance.createUser(accountName, password, password);
assertNotNull(instance.getUser( accountName ));
- assertNull(instance.getUser( ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS) ));
+ assertNull(instance.getUser( ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS) ));
}
/**
@@ -243,7 +244,7 @@ public void testGetUserFromRememberToken() throws AuthenticationException {
Authenticator instance = ESAPI.authenticator();
instance.logout(); // in case anyone is logged in
String password = instance.generateStrongPassword();
- String accountName=ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
User user = instance.createUser(accountName, password, password);
user.enable();
MockHttpServletRequest request = new MockHttpServletRequest();
@@ -281,7 +282,7 @@ public void testGetUserFromSession() throws AuthenticationException {
System.out.println("getUserFromSession");
FileBasedAuthenticator instance = (FileBasedAuthenticator)ESAPI.authenticator();
instance.logout(); // in case anyone is logged in
- String accountName=ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
+ String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS);
String password = instance.generateStrongPassword();
User user = instance.createUser(accountName, password, password);
user.enable();
@@ -307,7 +308,7 @@ public void testGetUserNames() throws AuthenticationException {
String password = instance.generateStrongPassword();
String[] testnames = new String[10];
for(int i=0;i
Date: Sun, 22 Jul 2012 00:19:30 +0000
Subject: [PATCH 004/812] 1) Fix warnings in keySet() method. 2) Javadoc
clean-up.
---
src/main/java/org/owasp/esapi/EncryptedProperties.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/EncryptedProperties.java b/src/main/java/org/owasp/esapi/EncryptedProperties.java
index 667ee2b52..e95b1b858 100644
--- a/src/main/java/org/owasp/esapi/EncryptedProperties.java
+++ b/src/main/java/org/owasp/esapi/EncryptedProperties.java
@@ -72,14 +72,16 @@ public interface EncryptedProperties {
String setProperty(String key, String value) throws EncryptionException;
/**
- * Returns a Set view of properties. The Set is backed by a Hashtable, so changes to the
- * Hashtable are reflected in the Set, and vice-versa. The Set supports element
- * removal (which removes the corresponding entry from the Hashtable), but not element addition.
+ * Returns a {@code Set} view of properties. The {@code Set} is backed by a
+ * {@code java.util.Hashtable}, so changes to the {@code Hashtable} are
+ * reflected in the {@code Set}, and vice-versa. The {@code Set} supports element
+ * removal (which removes the corresponding entry from the {@code Hashtable),
+ * but not element addition.
*
* @return
* a set view of the properties contained in this map.
*/
- public Set keySet();
+ public Set> keySet();
/**
* Reads a property list (key and element pairs) from the input stream.
From ffd225161dd445bd6e3e573e5154e7714bafd014 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sun, 22 Jul 2012 00:22:08 +0000
Subject: [PATCH 005/812] 1) Fix warnings. 2) Minor Javadoc changes.
---
.../esapi/reference/crypto/DefaultEncryptedProperties.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java b/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java
index 5726b856f..4f6d1a381 100644
--- a/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java
+++ b/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java
@@ -46,8 +46,10 @@
*
* @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @author kevin.w.wall@gmail.com
* @since June 1, 2007
* @see org.owasp.esapi.EncryptedProperties
+ * @see org.owasp.esapi.reference.crypto.ReferenceEncryptedProperties
*/
public class DefaultEncryptedProperties implements org.owasp.esapi.EncryptedProperties {
@@ -136,7 +138,7 @@ public synchronized String setProperty(String key, String value) throws Encrypti
/**
* {@inheritDoc}
*/
- public Set keySet() {
+ public Set> keySet() {
return properties.keySet();
}
@@ -201,7 +203,7 @@ public static void main(String[] args) throws Exception {
try { if ( out != null ) out.close(); } catch( Exception e ) {}
}
- Iterator i = ep.keySet().iterator();
+ Iterator> i = ep.keySet().iterator();
while (i.hasNext()) {
String k = (String) i.next();
String value = ep.getProperty(k);
From 88cb0cf1c6ca34eaef062cf9b6bdbaab89878d4f Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sun, 22 Jul 2012 00:28:32 +0000
Subject: [PATCH 006/812] 1) Remove unneeded import (bsh.This). 2) Fix or
suppress warnings. 3) Add serialVersionUID. 4) Fix Javadoc.
---
.../crypto/ReferenceEncryptedProperties.java | 28 ++++++++++++++-----
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java b/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java
index bcbe786cf..cffc14963 100644
--- a/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java
+++ b/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java
@@ -15,7 +15,6 @@
*/
package org.owasp.esapi.reference.crypto;
-import bsh.This;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -42,17 +41,24 @@
* and decryption based on {@code Encryptor}.
*
* This implementation differs from {@code DefaultEncryptedProperties} in that
- * it actually extends from java.util.Properties for applications that need an
+ * it actually extends from {@code java.util.Properties} for applications that need an
* instance of that class. In order to do so, the {@code getProperty} and
* {@code setProperty} methods were modified to throw {@code EncryptionRuntimeException}
* instead of {@code EncryptionException}.
*
* @author August Detlefsen (augustd at codemagi dot com)
* CodeMagi, Inc.
+ * @author kevin.w.wall@gmail.com
* @since October 8, 2010
* @see org.owasp.esapi.EncryptedProperties
+ * @see org.owasp.esapi.reference.crypto.DefaultEncryptedProperties
*/
-public class ReferenceEncryptedProperties extends java.util.Properties implements org.owasp.esapi.EncryptedProperties {
+public class ReferenceEncryptedProperties extends java.util.Properties implements EncryptedProperties {
+
+ /**
+ * serverVersionUID; use format of YYYYMMDD.
+ */
+ private static final long serialVersionUID = 20120718L;
/** The logger. */
private final Logger logger = ESAPI.getLogger(this.getClass());
@@ -91,7 +97,7 @@ public ReferenceEncryptedProperties(Properties defaults) {
/**
* {@inheritDoc}
*
- * @throws This method will throw an {@code EncryptionRuntimeException} if decryption fails.
+ * @throws EncryptionRuntimeException Thrown if decryption fails.
*/
@Override
public synchronized String getProperty(String key) throws EncryptionRuntimeException {
@@ -120,7 +126,7 @@ public synchronized String getProperty(String key) throws EncryptionRuntimeExcep
/**
* {@inheritDoc}
*
- * @throws This method will throw an {@code EncryptionRuntimeException} if decryption fails.
+ * @throws EncryptionRuntimeException Thrown if decryption fails.
*/
@Override
public String getProperty(String key, String defaultValue) throws EncryptionRuntimeException {
@@ -134,7 +140,7 @@ public String getProperty(String key, String defaultValue) throws EncryptionRunt
/**
* {@inheritDoc}
*
- * @throws This method will throw an {@code EncryptionRuntimeException} if encryption fails.
+ * @throws EncryptionRuntimeException Thrown if encryption fails.
*/
@Override
public synchronized String setProperty(String key, String value) throws EncryptionRuntimeException {
@@ -164,6 +170,8 @@ public synchronized String setProperty(String key, String value) throws Encrypti
/**
* {@inheritDoc}
+ * @throws IOException Thrown if input stream invalid or does not
+ * correspond to Java properties file format.
*/
@Override
public void load(InputStream in) throws IOException {
@@ -175,7 +183,10 @@ public void load(InputStream in) throws IOException {
* {@inheritDoc}
*
* For JDK 1.5 compatibility, this method has been overridden convert the Reader
- * into an InputStream and call the superclass constructor.
+ * into an InputStream and call the superclass constructor.
+ *
+ * @throws IOException Thrown if {@code Reader} input stream invalid or does not
+ * correspond to Java properties file format.
*/
public void load(Reader in) throws IOException {
@@ -218,6 +229,7 @@ public void list(PrintWriter out) {
/**
* This method has been overridden to throw an {@code UnsupportedOperationException}
*/
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Collection values() {
throw new UnsupportedOperationException("This method has been removed for security.");
@@ -226,6 +238,7 @@ public Collection values() {
/**
* This method has been overridden to throw an {@code UnsupportedOperationException}
*/
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Set entrySet() {
throw new UnsupportedOperationException("This method has been removed for security.");
@@ -234,6 +247,7 @@ public Set entrySet() {
/**
* This method has been overridden to throw an {@code UnsupportedOperationException}
*/
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Enumeration elements() {
throw new UnsupportedOperationException("This method has been removed for security.");
From b03591e53823c3d6a7792b030bb4cbfa6b6916d8 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Wed, 28 Aug 2013 03:27:06 +0000
Subject: [PATCH 007/812] Fix Javadoc comment for encodeForJavaScript() method.
---
src/main/java/org/owasp/esapi/Encoder.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/Encoder.java b/src/main/java/org/owasp/esapi/Encoder.java
index 168fb32ca..8a0ccd94e 100644
--- a/src/main/java/org/owasp/esapi/Encoder.java
+++ b/src/main/java/org/owasp/esapi/Encoder.java
@@ -294,11 +294,11 @@ public interface Encoder {
* as input – even if the user input is encoded.
*
* For example:
- *
+ *
*
- *
+ *
* @param input
* the text to encode for JavaScript
*
From 41138fef5f63d9cf0d5e05d2bee2c7f682ffef3f Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:49:41 +0000
Subject: [PATCH 008/812] Fix for Google Issue #306 and changes to address the
side effects of the fix (i.e., the removal of the deprecated ESAPI 1.4
encrypt() / decrypt() methods from the Encryptor interface).
---
src/main/java/org/owasp/esapi/Encryptor.java | 122 +-----------------
.../org/owasp/esapi/crypto/CipherText.java | 24 ++--
.../esapi/crypto/CipherTextSerializer.java | 6 +-
.../esapi/crypto/KeyDerivationFunction.java | 7 +-
.../esapi/reference/crypto/JavaEncryptor.java | 78 +----------
5 files changed, 31 insertions(+), 206 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/Encryptor.java b/src/main/java/org/owasp/esapi/Encryptor.java
index 7d651ef31..35bf094dd 100644
--- a/src/main/java/org/owasp/esapi/Encryptor.java
+++ b/src/main/java/org/owasp/esapi/Encryptor.java
@@ -105,75 +105,12 @@ public interface Encryptor {
*/
String hash(String plaintext, String salt, int iterations) throws EncryptionException;
- /**
- * Encrypts the provided plaintext and returns a ciphertext string using the
- * master secret key and default cipher transformation.
- *
- * Compatibility with earlier ESAPI versions: The symmetric encryption
- * in ESAPI 2.0 and later is not compatible with the encryption in ESAPI 1.4
- * or earlier. Not only are the interfaces slightly different, but they format
- * of the serialized encrypted data is incompatible. Therefore, if you have
- * encrypted data with ESAPI 1.4 or earlier, you must first encrypt it and
- * then re-encrypt it with ESAPI 2.0. Backward compatibility with ESAPI 1.4
- * was proposed to both the ESAPI Developers and ESAPI Users mailing lists
- * and voted down. More details are available in the ESAPI document
- *
- * Why Is OWASP Changing ESAPI Encryption?
- *
- * Why this method is deprecated: Most cryptographers strongly suggest
- * that if you are creating crypto functionality for general-purpose use,
- * at a minimum you should ensure that it provides authenticity, integrity,
- * and confidentiality. This method only provides confidentiality, but not
- * authenticity or integrity. Therefore, you are encouraged to use
- * one of the other encryption methods referenced below. Because this
- * method provides neither authenticity nor integrity, it may be
- * removed in some future ESAPI Java release. Note: there are some cases
- * where authenticity / integrity are not that important. For instance, consider
- * a case where the encrypted data is never out of your application's control. For
- * example, if you receive data that your application is encrypting itself and then
- * storing the encrypted data in its own database for later use (and no other
- * applications can query or update that column of the database), providing
- * confidentiality alone might be sufficient. However, if there are cases
- * where your application will be sending or receiving already encrypted data
- * over an insecure, unauthenticated channel, in such cases authenticity and
- * integrity of the encrypted data likely is important and this method should
- * be avoided in favor of one of the other two.
- *
- * @param plaintext
- * the plaintext {@code String} to encrypt. Note that if you are encrypting
- * general bytes, you should encypt that byte array to a String using
- * "UTF-8" encoding.
- *
- * @return
- * the encrypted, base64-encoded String representation of 'plaintext' plus
- * the random IV used.
- *
- * @throws EncryptionException
- * if the specified encryption algorithm could not be found or another problem exists with
- * the encryption of 'plaintext'
- *
- * @see #encrypt(PlainText)
- * @see #encrypt(SecretKey, PlainText)
- *
- * @deprecated As of 1.4.2; use {@link #encrypt(PlainText)} instead, which
- * also ensures message authenticity. This method will be
- * completely removed as of the next major release or point
- * release (3.0 or 2.1, whichever comes first) as per OWASP
- * deprecation policy.
- */
- @Deprecated String encrypt(String plaintext) throws EncryptionException;
-
/**
* Encrypts the provided plaintext bytes using the cipher transformation
* specified by the property Encryptor.CipherTransformation
* and the master encryption key as specified by the property
* {@code Encryptor.MasterKey} as defined in the ESAPI.properties file.
- *
- * This method is preferred over {@link #encrypt(String)} because it also
- * allows encrypting of general byte streams rather than simply strings and
- * also because it returns a {@code CipherText} object and thus supports
- * cipher modes that require an Initialization Vector (IV), such as
- * Cipher Block Chaining (CBC).
+ *
*
* @param plaintext The {@code PlainText} to be encrypted.
* @return the {@code CipherText} object from which the raw ciphertext, the
@@ -217,68 +154,11 @@ public interface Encryptor {
CipherText encrypt(SecretKey key, PlainText plaintext)
throws EncryptionException;
- /**
- * Decrypts the provided ciphertext and returns a plaintext string using the
- * master secret key and default cipher transformation.
- *
- * Compatibility with earlier ESAPI versions: The symmetric encryption
- * in ESAPI 2.0 and later is not compatible with the encryption in ESAPI 1.4
- * or earlier. Not only are the interfaces slightly different, but they format
- * of the serialized encrypted data is incompatible. Therefore, if you have
- * encrypted data with ESAPI 1.4 or earlier, you must first encrypt it and
- * then re-encrypt it with ESAPI 2.0. Backward compatibility with ESAPI 1.4
- * was proposed to both the ESAPI Developers and ESAPI Users mailing lists
- * and voted down. More details are available in the ESAPI document
- *
- * Why Is OWASP Changing ESAPI Encryption?
- *
- * Why this method is deprecated: Most cryptographers strongly suggest
- * that if you are creating crypto functionality for general-purpose use,
- * at a minimum you should ensure that it provides authenticity, integrity,
- * and confidentiality. This method only provides confidentiality, but not
- * authenticity or integrity. Therefore, you are encouraged to use
- * one of the other encryption methods referenced below. Because this
- * method provides neither authenticity nor integrity, it may be
- * removed in some future ESAPI Java release. Note: there are some cases
- * where authenticity / integrity are not that important. For instance, consider
- * a case where the encrypted data is never out of your application's control. For
- * example, if you receive data that your application is encrypting itself and then
- * storing the encrypted data in its own database for later use (and no other
- * applications can query or update that column of the database), providing
- * confidentiality alone might be sufficient. However, if there are cases
- * where your application will be sending or receiving already encrypted data
- * over an insecure, unauthenticated channel, in such cases authenticity and
- * integrity of the encrypted data likely is important and this method should
- * be avoided in favor of one of the other two.
- *
- * @param ciphertext
- * the ciphertext (the encrypted plaintext) that resulted from
- * encrypting using the method {@link #encrypt(String)}.
- *
- * @return
- * the decrypted ciphertext (i.e., the corresponding plaintext).
- *
- * @throws EncryptionException
- * if the specified encryption algorithm could not be found or another problem exists with
- * the decryption of 'plaintext'
- *
- * @deprecated As of 1.4.2; use {@link #decrypt(CipherText)} instead, which
- * also ensures message authenticity. This method will be
- * completely removed as of the next major release or point
- * release (3.0 or 2.1, whichever comes first) as per OWASP
- * deprecation policy.
- */
- @Deprecated String decrypt(String ciphertext) throws EncryptionException;
-
/**
* Decrypts the provided {@link CipherText} using the information from it
* and the master encryption key as specified by the property
* {@code Encryptor.MasterKey} as defined in the {@code ESAPI.properties}
* file.
- *
- * This decrypt method is to be preferred over the deprecated
- * {@link #decrypt(String)} method because this method can handle plaintext
- * bytes that were encrypted with cipher modes requiring IVs, such as CBC.
*
* @param ciphertext The {@code CipherText} object to be decrypted.
* @return The {@code PlainText} object resulting from decrypting the specified
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherText.java b/src/main/java/org/owasp/esapi/crypto/CipherText.java
index 629002e08..689ef1c21 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherText.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherText.java
@@ -65,7 +65,9 @@ public final class CipherText implements Serializable {
// reflected in the class CipherTextSerializer.
// This should be *same* version as in CipherTextSerializer and KeyDerivationFunction.
// If one changes, the other should as well to accommodate any differences.
- public static final int cipherTextVersion = 20110203; // Format: YYYYMMDD, max is 99991231.
+ // Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1)
+ // 20130830 - Fix to issue #306 (release 2.1.0)
+ public static final int cipherTextVersion = 20130830; // Format: YYYYMMDD, max is 99991231.
// Required by Serializable classes.
private static final long serialVersionUID = cipherTextVersion; // Format: YYYYMMDD
@@ -435,21 +437,23 @@ void storeSeparateMAC(byte[] macValue) {
* @return True if the ciphertext has not be tampered with, and false otherwise.
*/
public boolean validateMAC(SecretKey authKey) {
- boolean usesMAC = ESAPI.securityConfiguration().useMACforCipherText();
+ boolean requiresMAC = ESAPI.securityConfiguration().useMACforCipherText();
- if ( usesMAC && macComputed() ) { // Uses MAC and it was computed
+ if ( requiresMAC && macComputed() ) { // Uses MAC and it was computed
// Calculate MAC from HMAC-SHA1(nonce, IV + plaintext) and
// compare to stored value (separate_mac_). If same, then return true,
// else return false.
byte[] mac = computeMAC(authKey);
assert mac.length == separate_mac_.length : "MACs are of differnt lengths. Should both be the same.";
return CryptoHelper.arrayCompare(mac, separate_mac_); // Safe compare!!!
- } else if ( ! usesMAC ) { // Doesn't use MAC
+ } else if ( ! requiresMAC ) { // Doesn't require a MAC
return true;
- } else { // Uses MAC but it has not been computed / stored.
- logger.warning(Logger.SECURITY_FAILURE, "Cannot validate MAC as it was never computed and stored. " +
- "Decryption result may be garbage even when decryption succeeds.");
- return true; // Need to return 'true' here because of encrypt() / decrypt() methods don't support this.
+ } else {
+ // This *used* to be the case (for versions 2.0 and 2.0.1) where we tried to
+ // accomodate the deprecated decrypt() method from ESAPI 1.4. Unfortunately,
+ // that was an EPIC FAIL. (See Google Issue # 306 for details.)
+ logger.warning(Logger.SECURITY_FAILURE, "MAC may have been tampered with (e.g., length set to 0).");
+ return false; // Deprecated decrypt() method removed, so now return false.
}
}
@@ -474,8 +478,8 @@ public byte[] asPortableSerializedByteArray() throws EncryptionException {
// If we are supposed to be using a (separate) MAC, also make sure
// that it has been computed/stored.
- boolean usesMAC = ESAPI.securityConfiguration().useMACforCipherText();
- if ( usesMAC && ! macComputed() ) {
+ boolean requiresMAC = ESAPI.securityConfiguration().useMACforCipherText();
+ if ( requiresMAC && ! macComputed() ) {
String msg = "Programming error: MAC is required for this cipher mode (" +
getCipherMode() + "), but MAC has not yet been " +
"computed and stored. Call the method " +
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
index ca4d4ac16..b00dd245c 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
@@ -32,7 +32,9 @@
public class CipherTextSerializer {
// This should be *same* version as in CipherText & KeyDerivationFunction.
// If one changes, the other should as well to accommodate any differences.
- public static final int cipherTextSerializerVersion = 20110203; // Format: YYYYMMDD, max is 99991231.
+ // Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1)
+ // 20130830 - Fix to issue #306 (release 2.1.0)
+ public static final int cipherTextSerializerVersion = 20130830; // Format: YYYYMMDD, max is 99991231.
private static final long serialVersionUID = cipherTextSerializerVersion;
private static final Logger logger = ESAPI.getLogger("CipherTextSerializer");
@@ -234,7 +236,7 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
debug("kdfPrf: " + kdfPrf);
assert kdfPrf >= 0 && kdfPrf <= 15 : "kdfPrf == " + kdfPrf + " must be between 0 and 15.";
int kdfVers = ( kdfInfo & 0x07ffffff);
- assert kdfVers > 0 && kdfVers <= 99991231 : "KDF Version (" + kdfVers + ") out of range."; // Really should be >= 20110203 (earliest).
+ assert kdfVers >= 20110203 && kdfVers <= 99991231 : "KDF Version (" + kdfVers + ") out of range."; // 20110203 (orig version).
debug("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers);
if ( kdfVers != CipherText.cipherTextVersion ) {
// NOTE: In future, support backward compatibility via this mechanism. When we do this
diff --git a/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
index 90807199f..40c095b89 100644
--- a/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
+++ b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
@@ -49,12 +49,15 @@ public class KeyDerivationFunction {
* {@link CipherTextSerializer#cipherTextSerializerVersion} to make sure
* that these classes are all kept in-sync in order to support backward
* compatibility of previously encrypted data.
- *
+ *
+ * Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1)
+ * 20130830 - Fix to issue #306 (release 2.1.0)
+ *
* @see CipherTextSerializer#asSerializedByteArray()
* @see CipherText#asPortableSerializedByteArray()
* @see CipherText#fromPortableSerializedBytes(byte[])
*/
- public static final int kdfVersion = 20110203; // Format: YYYYMMDD, max is 99991231.
+ public static final int kdfVersion = 20130830; // Format: YYYYMMDD, max is 99991231.
private static final long serialVersionUID = kdfVersion; // Format: YYYYMMDD
// Pseudo-random function algorithms suitable for NIST KDF in counter mode.
diff --git a/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
index 68a4cf644..064fa932c 100644
--- a/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
+++ b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
@@ -329,28 +329,6 @@ public String hash(String plaintext, String salt, int iterations) throws Encrypt
throw new EncryptionException("Internal error", "Can't find encoding for " + encoding, ex);
}
}
-
- /**
- * Convenience method that encrypts plaintext strings the new way (default
- * is CBC mode and PKCS5 padding). This encryption method uses the master
- * encryption key specified by the {@code Encryptor.MasterKey} property
- * in {@code ESAPI.properties}.
- *
- * @param plaintext A String to be encrypted
- * @return A base64-encoded combination of IV + raw ciphertext
- * @throws EncryptionException Thrown when something goes wrong with the
- * encryption.
- *
- * @see org.owasp.esapi.Encryptor#encrypt(PlainText)
- */
- @Deprecated public String encrypt(String plaintext) throws EncryptionException
- {
- logWarning("encrypt", "Calling deprecated encrypt() method.");
- CipherText ct = null;
- ct = encrypt(new PlainText(plaintext) );
- return ct.getEncodedIVCipherText();
- }
-
/**
* {@inheritDoc}
@@ -366,10 +344,15 @@ public CipherText encrypt(PlainText plaintext) throws EncryptionException {
public CipherText encrypt(SecretKey key, PlainText plain)
throws EncryptionException
{
+ if ( key == null ) {
+ throw new IllegalArgumentException("(Master) encryption key arg may not be null. Is Encryptor.MasterKey set?");
+ }
+ if ( plain == null ) {
+ throw new IllegalArgumentException("PlainText may arg not be null");
+ }
byte[] plaintext = plain.asBytes();
boolean overwritePlaintext = ESAPI.securityConfiguration().overwritePlainText();
- assert key != null : "(Master) encryption key may not be null";
-
+
boolean success = false; // Used in 'finally' clause.
String xform = null;
int keySize = key.getEncoded().length * 8; // Convert to # bits
@@ -569,53 +552,6 @@ public CipherText encrypt(SecretKey key, PlainText plain)
}
}
- /**
- * Convenience method that decrypts previously encrypted plaintext strings
- * that were encrypted using the new encryption mechanism (with CBC mode and
- * PKCS5 padding by default). This decryption method uses the master
- * encryption key specified by the {@code Encryptor.MasterKey} property
- * in {@code ESAPI.properties}.
- *
- * @param b64IVCiphertext A base64-encoded representation of the
- * IV + raw ciphertext string to be decrypted with
- * the default master key.
- * @return The plaintext string prior to encryption.
- * @throws EncryptionException When something fails with the decryption.
- *
- * @see org.owasp.esapi.Encryptor#decrypt(CipherText)
- */
- @Deprecated public String decrypt(String b64IVCiphertext) throws EncryptionException
- {
- logWarning("decrypt", "Calling deprecated decrypt() method.");
- CipherText ct = null;
- try {
- // We assume that the default cipher transform was used to encrypt this.
- ct = new CipherText();
-
- // Need to base64 decode the IV+ciphertext and extract the IV to set it in CipherText object.
- byte[] ivPlusRawCipherText = ESAPI.encoder().decodeFromBase64(b64IVCiphertext);
- int blockSize = ct.getBlockSize(); // Size in bytes.
- byte[] iv = new byte[ blockSize ];
- CryptoHelper.copyByteArray(ivPlusRawCipherText, iv, blockSize); // Copy the first blockSize bytes into iv array
- int cipherTextSize = ivPlusRawCipherText.length - blockSize;
- byte[] rawCipherText = new byte[ cipherTextSize ];
- System.arraycopy(ivPlusRawCipherText, blockSize, rawCipherText, 0, cipherTextSize);
- ct.setIVandCiphertext(iv, rawCipherText);
-
- // Now the CipherText object should be prepared to use it to decrypt.
- PlainText plaintext = decrypt(ct);
- return plaintext.toString(); // Convert back to a Java String
- } catch (UnsupportedEncodingException e) {
- // Should never happen; UTF-8 should be in rt.jar.
- logger.error(Logger.SECURITY_FAILURE, "UTF-8 encoding not available! Decryption failed.", e);
- return null; // CHECKME: Or re-throw or what? Could also use native encoding, but that's
- // likely to cause unexpected and undesired effects far downstream.
- } catch (IOException e) {
- logger.error(Logger.SECURITY_FAILURE, "Base64 decoding of IV+ciphertext failed. Decryption failed.", e);
- return null;
- }
- }
-
/**
* {@inheritDoc}
*/
From 71d5b77b3da12028acf4291e9438b3e3a8825414 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:51:29 +0000
Subject: [PATCH 009/812] Update ESAPI release number.
---
pom.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index c48a1908f..2de9b9a73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.owasp.esapiesapi
- 2.0.2-SNAPSHOT
+ 2.1.0jar
@@ -106,8 +106,8 @@
- Kevin Wall
- Qwest
+ Kevin W. Wall
+ Wells FargoProject ManagerArchitect
From bfed966e11fe6f860347a129d1191e8c59f483a3 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:53:43 +0000
Subject: [PATCH 010/812] Replace assertion with IllegalArgumentException when
argument to CTOR is null.
---
src/main/java/org/owasp/esapi/crypto/PlainText.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/main/java/org/owasp/esapi/crypto/PlainText.java b/src/main/java/org/owasp/esapi/crypto/PlainText.java
index fa88d1d0c..bfa9fd3a2 100644
--- a/src/main/java/org/owasp/esapi/crypto/PlainText.java
+++ b/src/main/java/org/owasp/esapi/crypto/PlainText.java
@@ -38,10 +38,14 @@ public final class PlainText implements Serializable {
* Construct a {@code PlainText} object from a {@code String}.
* @param str The {@code String} that is converted to a UTF-8 encoded
* byte array to create the {@code PlainText} object.
+ * @throws IllegalArgumentException If {@code str} argument is null.
*/
public PlainText(String str) {
try {
assert str != null : "String for plaintext cannot be null.";
+ if ( str == null ) {
+ throw new IllegalArgumentException("String for plaintext may not be null!");
+ }
rawBytes = str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// Should never happen.
From 41e8903ebb3ba4f335cc71e2d1d00b36b72862d4 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:54:52 +0000
Subject: [PATCH 011/812] Update documentation to reflect ESAPI 2.1.0 release.
---
documentation/esapi4java-2.0-readme.txt | 1 +
.../esapi4java-core-2.1-release-notes.txt | 53 +++++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 documentation/esapi4java-core-2.1-release-notes.txt
diff --git a/documentation/esapi4java-2.0-readme.txt b/documentation/esapi4java-2.0-readme.txt
index 7806c393e..de7c40dda 100644
--- a/documentation/esapi4java-2.0-readme.txt
+++ b/documentation/esapi4java-2.0-readme.txt
@@ -31,6 +31,7 @@ File / Directory Descript
| |---esapi4java-core-2.0-crypto-design-goals.doc (draft) Describes ESAPI 2.0 crypto design goals & design decisions
| |---esapi4java-core-2.0-readme-crypto-changes.html Describes why crypto was changed from what was in ESAPI 1.4
| |---esapi4java-core-2.0-symmetric-crypto-user-guide.html User guide for using symmetric encryption in ESAPI 2.0
+| |---esapi4java-core-2.1-release-notes.txt ESAPI 2.1 release notes
| `---esapi4java-waf-2.0-policy-file-spec.pdf Describes how to configure ESAPI 2.0's Web Application Firewall
|
|---libs/ ESAPI dependencies
diff --git a/documentation/esapi4java-core-2.1-release-notes.txt b/documentation/esapi4java-core-2.1-release-notes.txt
new file mode 100644
index 000000000..b5b04897f
--- /dev/null
+++ b/documentation/esapi4java-core-2.1-release-notes.txt
@@ -0,0 +1,53 @@
+ESAPI for Java - 2.1.0 Release Notes
+
+1) Fixed security issue #306, a vulnerability discovered by Phillipe Arteau.
+ This fix necessitated removing the deprecated encrypt() and decrupt() methods
+ that were intended to provide backward compatibility with ESAPI 1.4.
+ As it turns out, there was no way to fix this bug without a major rewrite
+ unless these methods were removed. However, as these two methods have been
+ deprecated more than 2 years ago and they are known to be insecure
+ (they are vulnerable to padding oracle attacks), the ESAPI team has
+ decided to remove them in accordance to their support policy.
+
+ See comments for issue #306 for further details, as well as additional
+ safety precautions that you may wish to take in the unlikely, but possible
+ event that this vulnerability resulted in an actual security breach.
+
+ Finally, since the removal of these methods constitute an interface change
+ (to the Encryptor interface), this is considered a minor release (2.1)
+ rather than simply a patch release (2.0.2).
+
+ Please note that there are further updates planned to further strengthen
+ the MAC that ESAPI crypt uses. However, because they will require some
+ design changes, they may not be out for another month. Note that these
+ fixes do not correct any *known* vulnerabilities, but will address
+ some potential weaknesses in what is not included in the MAC (such as
+ the crypto version).
+
+2) Other Google Issues fixed: 257, 271, and 292 are all fixed in this release.
+
+3) Fixed Javadoc for Encoder.encryptForJavaScript(). [Revision r1879]
+
+4) DefaultEncryptedProperties - made minor javadoc changes.
+
+5) The ESAPI 2.0 Encryptor.encrypt() methods now all throw an appropriate
+ IllegalArgumentException if any of the arguments are null. Previously,
+ if any of the arguments were null you would either get an AssertionError
+ (if you had assertions enabled) or a default NullPointerException when
+ assertions were disabled. While IllegalArgumentException is still an
+ unchecked RuntimeException, note that if you were previously catching
+ NullPointerExceptions for these cases, you may need to change your code.
+
+6) Other miscellaneous minor code clean-up, mostly to remove compiler warnings.
+
+NOTE: A follow-up patch release is scheduled within the next few months to
+ address some questionable design decisions regarding what data in
+ the serialized ciphertext should be authenticated via the MAC. For
+ instance, presently only the IV+ciphertext is MAC'd (as would be the
+ equivalent case of when you would use an authenticated combined cipher
+ mode such as GCM or CCM). A deeper analysis of the design is required
+ based on findings in Google Issue # 306. I will periodically try
+ to keep the ESAPI mailing lists updated with the progress so watch
+ there for emerging details and anticipated schedule.
+
+-Kevin W. Wall , 2013-08-30
From a8b4022f284cd67239439eb51c6d2cc18fe0a834 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:56:49 +0000
Subject: [PATCH 012/812] New JUnit test, based on Philippe Arteau's orignial
exploit, that shows Google Issue # 306 has been fixed.
---
.../crypto/ESAPICryptoMACByPassTest.java | 232 ++++++++++++++++++
1 file changed, 232 insertions(+)
create mode 100644 src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
diff --git a/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
new file mode 100644
index 000000000..34878c705
--- /dev/null
+++ b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
@@ -0,0 +1,232 @@
+/*
+ * OWASP Enterprise Security API (ESAPI) - Google issue # 306.
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2013 - The OWASP Foundation
+ * ESAPI is published by OWASP under the new BSD license. You should read
+ * and accept the LICENSE before you use, modify, and/or redistribute this
+ * software.
+ *
+ * Full credit for this JUnit to illustrate what is now Google Issue # 306
+ * goes to Philippe Arteau . Originally
+ * published 2013/08/21 to ESAPI-DEV mailing list. Shows that both
+ * ESAPI 2.0 and 2.0.1 is vulnerable. Minor tweaks by Kevin W. Wall.
+ *
+ * Original class name: SignatureByPassTest.
+ *
+ * NOTE: If this test fails, your version of ESAPI is vulnerable (or you have
+ * it configured not to require a MAC which you should NOT do).
+ */
+
+package org.owasp.esapi.crypto;
+
+import org.apache.commons.codec.binary.Hex;
+import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.crypto.CipherText;
+import org.owasp.esapi.crypto.PlainText;
+import org.owasp.esapi.errors.EncryptionException;
+import org.owasp.esapi.util.ByteConversionUtil;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Date;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class ESAPICryptoMACByPassTest {
+
+ @Before
+ public void setUp() throws NoSuchAlgorithmException, InvalidKeySpecException {
+ ; // Do any prerequisite setup here.
+ }
+
+ @Test
+ public void testMacBypass() throws EncryptionException, NoSuchFieldException, IllegalAccessException {
+
+ byte[] bkey = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xA,0x0B,0x0C,0x0D,0x0E,0x0F}; //Truly random key.
+ SecretKey sk = new SecretKeySpec(bkey,"AES");
+
+ //Encryption with MAC
+ String originalMessage = "Cryptography!?!?";
+ System.out.printf("Encrypting the message '%s'\n", originalMessage);
+ // Until there is a better way to do this. But this is much easier
+ // than having to set up a custom ESAPI.properties file just for
+ // this test.
+ //
+ // NOTE: Philippe Arteau's original exploit used "AES/OFB/NoPadding"
+ // so that one could see that the effect of the decryption would
+ // be "Craptography!?!?". However, if you wish to do that, then
+ // you must also change the ESAPI.properties file used by ESAPI
+ // JUnit tests sp that "OFB" is accepted as an allowed cipher
+ // mode. The easiest way to do that (if you are still not convinced)
+ // is to add "OFB" mode to Encryptor.cipher_modes.additional_allowed;
+ // e.g., Encryptor.cipher_modes.additional_allowed=CBC,OFB
+ //
+ String origCipherXform =
+ ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/NoPadding");
+ CipherText ct = ESAPI.encryptor().encrypt(sk,new PlainText(originalMessage));
+ ct.computeAndStoreMAC(sk);
+
+ //Serialize the ciphertext in order to send it over the wire..
+ byte[] serializedCt = ct.asPortableSerializedByteArray();
+
+ //Malicious modification
+ byte[] modifiedCt = tamperCipherText(serializedCt);
+
+ //Decrypt
+ CipherText modifierCtObj = CipherText.fromPortableSerializedBytes(modifiedCt);
+ try {
+ ESAPI.securityConfiguration().setCipherTransformation(origCipherXform);
+ // This decryption should fail by throwing an EncryptionException
+ // if ESAPI crypto is NOT vulnerable and you never get to the
+ // subsequent lines in the try block.
+ PlainText pt = ESAPI.encryptor().decrypt(sk,modifierCtObj);
+ System.out.printf("Decrypting to '%s' (probably will look like garbage!)\n", new String(pt.asBytes()));
+ System.out.println("This ESAPI version vulnerable to MAC by-pass described in Google issue # 306! Upgrade to latest version.");
+ fail("This ESAPI version is vulnerable to MAC by-pass described in Google issue # 306! Upgrade to latest version.");
+ } catch(EncryptionException eex) {
+ String errMsg = eex.getMessage();
+ // See private String DECRYPTION_FAILED in JavaEncryptor.
+ String expectedError = "Decryption failed; see logs for details.";
+ assertTrue( errMsg.equals(expectedError) );
+ System.out.println("testMacByPass(): Attempted decryption after MAC tampering failed.");
+ System.out.println("Fix of issue # 306 successful. Crypto MAC by-pass test failed; exception was: [" + eex + "]");
+ }
+ }
+
+ /**
+ * The modification of the ciphertext is done in a separate method to show that only the generate CipherText object is use.
+ * @param serializeCt
+ */
+ private byte[] tamperCipherText(byte[] serializeCt) throws EncryptionException, NoSuchFieldException, IllegalAccessException {
+ CipherText ct = CipherText.fromPortableSerializedBytes(serializeCt);
+
+ //Ciphertext metadata
+ //System.out.println(ct.toString());
+
+ byte[] cipherTextMod = ct.getRawCipherText();
+
+ System.out.printf("Original ciphertext\t'%s'\n",String.valueOf(Hex.encodeHex(cipherTextMod)));
+
+ cipherTextMod[2] ^= 'y' ^ 'a'; //Alter the 3rd character
+
+ System.out.printf("Modify ciphertext\t'%s'\n",String.valueOf(Hex.encodeHex(cipherTextMod)));
+
+ //MAC ... what MAC ?
+ Field f2 = ct.getClass().getDeclaredField("separate_mac_");
+ f2.setAccessible(true);
+ f2.set(ct,null); //mac byte array set to null
+
+ //Changing CT
+ Field f3 = ct.getClass().getDeclaredField("raw_ciphertext_");
+ f3.setAccessible(true);
+ f3.set(ct,cipherTextMod);
+
+ //return ct.asPortableSerializedByteArray(); //Will complain about missing mac
+ //return new CipherTextSerializer(ct).asSerializedByteArray(); //NPE on mac.length
+ return serialize(ct); //Modify version of CipherTextSerializer.asSerializedByteArray()
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // The following code is a modified version of CipherTextSerializer
+ /////////////////////////////////////////////////////////////////////
+
+ private byte[] serialize(CipherText cipherText_) {
+ int kdfInfo = cipherText_.getKDFInfo();
+
+ long timestamp = cipherText_.getEncryptionTimestamp();
+ String cipherXform = cipherText_.getCipherTransformation();
+
+ short keySize = (short) cipherText_.getKeySize();
+
+ short blockSize = (short)cipherText_.getBlockSize();
+ byte[] iv = cipherText_.getIV();
+
+ short ivLen = (short)iv.length;
+ byte[] rawCiphertext = cipherText_.getRawCipherText();
+ int ciphertextLen = rawCiphertext.length;
+
+ byte[] mac = cipherText_.getSeparateMAC();
+
+ short macLen = 0;//(short)mac.length; //<-------------- The only modification to the serialization
+
+ return computeSerialization(kdfInfo, timestamp, cipherXform, keySize, blockSize, ivLen, iv, ciphertextLen, rawCiphertext, macLen, mac);
+ }
+
+ private byte[] computeSerialization(int kdfInfo, long timestamp, String cipherXform, short keySize, short blockSize, short ivLen, byte[] iv, int ciphertextLen, byte[] rawCiphertext, short macLen, byte[] mac)
+ {
+ debug("computeSerialization: kdfInfo = " + kdfInfo);
+ debug("computeSerialization: timestamp = " + new Date(timestamp));
+ debug("computeSerialization: cipherXform = " + cipherXform);
+ debug("computeSerialization: keySize = " + keySize);
+ debug("computeSerialization: blockSize = " + blockSize);
+ debug("computeSerialization: ivLen = " + ivLen);
+ debug("computeSerialization: ciphertextLen = " + ciphertextLen);
+ debug("computeSerialization: macLen = " + macLen);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ writeInt(baos, kdfInfo);
+ writeLong(baos, timestamp);
+ String[] parts = cipherXform.split("/");
+ assert (parts.length == 3) : "Malformed cipher transformation";
+ writeString(baos, cipherXform);
+ writeShort(baos, keySize);
+ writeShort(baos, blockSize);
+ writeShort(baos, ivLen);
+ if (ivLen > 0) baos.write(iv, 0, iv.length);
+ writeInt(baos, ciphertextLen);
+ baos.write(rawCiphertext, 0, rawCiphertext.length);
+ writeShort(baos, macLen);
+ if (macLen > 0) baos.write(mac, 0, mac.length);
+ return baos.toByteArray();
+ }
+
+ private static void debug(String msg) {
+ // System.err.println(msg);
+ }
+
+ private void writeShort(ByteArrayOutputStream baos, short s) {
+ byte[] shortAsByteArray = ByteConversionUtil.fromShort(s);
+ assert (shortAsByteArray.length == 2);
+ baos.write(shortAsByteArray, 0, 2);
+ }
+
+ private void writeInt(ByteArrayOutputStream baos, int i) {
+ byte[] intAsByteArray = ByteConversionUtil.fromInt(i);
+ baos.write(intAsByteArray, 0, 4);
+ }
+
+ private void writeLong(ByteArrayOutputStream baos, long l) {
+ byte[] longAsByteArray = ByteConversionUtil.fromLong(l);
+ assert (longAsByteArray.length == 8);
+ baos.write(longAsByteArray, 0, 8);
+ }
+
+ private void writeString(ByteArrayOutputStream baos, String str)
+ {
+ try
+ {
+ assert ((str != null) && (str.length() > 0));
+ byte[] bytes = str.getBytes("UTF8");
+ assert (bytes.length < 32767) : "writeString: String exceeds max length";
+ writeShort(baos, (short)bytes.length);
+ baos.write(bytes, 0, bytes.length);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ System.err.println("writeString: " + e.getMessage());
+ }
+ }
+
+}
\ No newline at end of file
From fc4e6375ec7b8830440372f6470b6028fc3ebea4 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 00:58:32 +0000
Subject: [PATCH 013/812] Added comment about why ECB is there as an allowed
cipher mode. (Hint: It's for testing!)
---
src/test/resources/esapi/ESAPI.properties | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/test/resources/esapi/ESAPI.properties b/src/test/resources/esapi/ESAPI.properties
index d6f93f1da..1435b7c6d 100644
--- a/src/test/resources/esapi/ESAPI.properties
+++ b/src/test/resources/esapi/ESAPI.properties
@@ -239,6 +239,7 @@ Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC
# since the logic is somewhat different (i.e., ECB mode does
# not use an IV).
# DISCUSS: Better name?
+# NOTE: ECB added only for testing purposes. Don't try this at home!
Encryptor.cipher_modes.additional_allowed=CBC,ECB
# 128-bit is almost always sufficient and appears to be more resistant to
From 66f0d85f2efabd980246b7991185cf5d0bb39ab9 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 01:00:55 +0000
Subject: [PATCH 014/812] Fix typo in test case name. (Spell much?)
---
src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java b/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java
index 330f88f0b..f81986550 100644
--- a/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java
+++ b/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java
@@ -330,7 +330,7 @@ public final void testSetAndGetAttribute() {
// public void addAttributes(final Map attrs) throws ValidationException
// public Map getAttributes()
@Test
- public final void tesAddandGetAttributes() {
+ public final void testAddandGetAttributes() {
CryptoToken ctok = new CryptoToken();
Map origAttrs = null;
From ffae68a189d582773175232934783c6ab4efd169 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 01:04:23 +0000
Subject: [PATCH 015/812] Changes required to crypto JUnit tests because old
deprecated encrypt() / decrypt() methods were removed.
---
.../esapi/reference/crypto/EncryptorTest.java | 98 ++++++++++---------
1 file changed, 51 insertions(+), 47 deletions(-)
diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
index 8c205d8de..35166a3dd 100644
--- a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
+++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
@@ -56,9 +56,11 @@ public EncryptorTest(String testName) {
* {@inheritDoc}
* @throws Exception
*/
- protected void setUp() throws Exception {
+ @SuppressWarnings("deprecation")
+ protected void setUp() throws Exception {
// This is only mechanism to change this for now. Will do this with
- // a soon to be CryptoControls class in next release.
+ // a soon to be CryptoControls class or equivalent mechanism in a
+ // future release.
ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/PKCS5Padding");
}
@@ -99,55 +101,52 @@ public void testHash() throws EncryptionException {
}
/**
- * Test of deprecated encrypt method for Strings.
+ * Test of new encrypt / decrypt method for Strings whose length is
+ * not a multiple of the cipher block size (16 bytes for AES).
*
* @throws EncryptionException
* the encryption exception
*/
- public void testEncrypt() throws EncryptionException {
- System.out.println("testEncrypt()");
+ public void testEncryptDecrypt1() throws EncryptionException {
+ System.out.println("testEncryptDecrypt2()");
Encryptor instance = ESAPI.encryptor();
- String plaintext = "test123456"; // Not multiple of block cipher size
- String ciphertext = instance.encrypt(plaintext);
- String result = instance.decrypt(ciphertext);
- assertEquals(plaintext, result);
+ String plaintext = "test1234test1234tes"; // Not a multiple of block size (16 bytes)
+ try {
+ CipherText ct = instance.encrypt(new PlainText(plaintext));
+ PlainText pt = instance.decrypt(ct);
+ assertTrue( pt.toString().equals(plaintext) );
+ }
+ catch( EncryptionException e ) {
+ fail("testEncryptDecrypt2(): Caught exception: " + e);
+ }
}
/**
- * Test of deprecated decrypt method for Strings.
+ * Test of new encrypt / decrypt method for Strings whose length is
+ * same as cipher block size (16 bytes for AES).
*/
- public void testDecrypt() {
- System.out.println("testDecrypt()");
+ public void testEncryptDecrypt2() {
+ System.out.println("testEncryptDecrypt2()");
Encryptor instance = ESAPI.encryptor();
+ String plaintext = "test1234test1234";
try {
- String plaintext = "test123";
- String ciphertext = instance.encrypt(plaintext);
- assertFalse(plaintext.equals(ciphertext));
- String result = instance.decrypt(ciphertext);
- assertEquals(plaintext, result);
+ CipherText ct = instance.encrypt(new PlainText(plaintext));
+ PlainText pt = instance.decrypt(ct);
+ assertTrue( pt.toString().equals(plaintext) );
}
catch( EncryptionException e ) {
- fail();
+ fail("testEncryptDecrypt2(): Caught exception: " + e);
}
}
/**
* Test of encrypt methods for empty String.
- *
- * @throws EncryptionException
- * the encryption exception
*/
- @SuppressWarnings("deprecation")
public void testEncryptEmptyStrings() {
System.out.println("testEncryptEmptyStrings()");
Encryptor instance = ESAPI.encryptor();
String plaintext = "";
try {
- // System.out.println("Deprecated encryption methods");
- String ciphertext = instance.encrypt(plaintext);
- String result = instance.decrypt(ciphertext);
- assertTrue( result.equals("") );
-
// System.out.println("New encryption methods");
CipherText ct = instance.encrypt(new PlainText(plaintext));
PlainText pt = instance.decrypt(ct);
@@ -158,23 +157,35 @@ public void testEncryptEmptyStrings() {
}
/**
- * Test encryption / decryption methods for null.
+ * Test encryption method for null.
*/
- @SuppressWarnings("deprecation")
public void testEncryptNull() {
System.out.println("testEncryptNull()");
Encryptor instance = ESAPI.encryptor();
- String plaintext = "";
try {
- String nullStr = null;
- instance.encrypt(nullStr);
- fail("testEncryptNull(): Did not result in expected exception!");
+ CipherText ct = instance.encrypt( null ); // Should throw NPE or AssertionError
+ fail("New encrypt(PlainText) method did not throw. Result was: " + ct.toString());
} catch(Throwable t) {
// It should be one of these, depending on whether or not assertions are enabled.
assertTrue( t instanceof NullPointerException || t instanceof AssertionError);
}
}
+ /**
+ * Test decryption method for null.
+ */
+ public void testDecryptNull() {
+ System.out.println("testDecryptNull()");
+ Encryptor instance = ESAPI.encryptor();
+ try {
+ PlainText pt = instance.decrypt( null ); // Should throw IllegalArgumentException or AssertionError
+ fail("New decrypt(PlainText) method did not throw. Result was: " + pt.toString());
+ } catch(Throwable t) {
+ // It should be one of these, depending on whether or not assertions are enabled.
+ assertTrue( t instanceof IllegalArgumentException || t instanceof AssertionError);
+ }
+ }
+
/**
* Test of new encrypt / decrypt methods added in ESAPI 2.0.
*/
@@ -246,7 +257,8 @@ private String runNewEncryptDecryptTestCase(String cipherXform, int keySize, byt
// Change to a possibly different cipher. This is kludgey at best. Am thinking about an
// alternate way to do this using a new 'CryptoControls' class. Maybe not until release 2.1.
// Change the cipher transform from whatever it currently is to the specified cipherXform.
- String oldCipherXform = ESAPI.securityConfiguration().setCipherTransformation(cipherXform);
+ @SuppressWarnings("deprecation")
+ String oldCipherXform = ESAPI.securityConfiguration().setCipherTransformation(cipherXform);
if ( ! cipherXform.equals(oldCipherXform) ) {
System.out.println("Cipher xform changed from \"" + oldCipherXform + "\" to \"" + cipherXform + "\"");
}
@@ -281,7 +293,8 @@ private String runNewEncryptDecryptTestCase(String cipherXform, int keySize, byt
assertTrue( "Failed to decrypt properly.", origPlainText.toString().equals( decryptedPlaintext.toString() ) );
// Restore the previous cipher transformation. For now, this is only way to do this.
- String previousCipherXform = ESAPI.securityConfiguration().setCipherTransformation(null);
+ @SuppressWarnings("deprecation")
+ String previousCipherXform = ESAPI.securityConfiguration().setCipherTransformation(null);
assertTrue( previousCipherXform.equals( cipherXform ) );
String defaultCipherXform = ESAPI.securityConfiguration().getCipherTransformation();
assertTrue( defaultCipherXform.equals( oldCipherXform ) );
@@ -331,7 +344,8 @@ private static boolean isPlaintextOverwritten(PlainText plaintext) {
// TODO - Need to test rainy day paths of new encrypt / decrypt so can
// verify that exception handling working OK, etc. Maybe also in
// a separate JUnit test, since everything here seems to be sunny
- // day path.
+ // day path. (Note: Some of this no in new test case,
+ // org.owasp.esapi.crypto.ESAPICryptoMACByPassTest.)
//
// -kevin wall
@@ -508,15 +522,5 @@ public void testMain() throws Exception {
// and checked against (at least some of) the expected output.
// Left as an exercise to some future, ambitious ESAPI developer. ;-)
JavaEncryptor.main( args1 );
- }
-
- private boolean checkByteArray(byte[] ba, byte b) {
- for(int i = 0; i < ba.length; i++ ) {
- if ( ba[i] != b ) {
- return false;
- }
- }
- return true;
- }
-
+ }
}
From 600ecc1fc19056a56fbb31a8a0cb188b3e870ccb Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Thu, 29 Aug 2013 01:19:51 +0000
Subject: [PATCH 016/812] Argh! Forgot to change test from NullPointerException
to IllegalArgumentException. Always good to retest one last time.
---
.../java/org/owasp/esapi/reference/crypto/EncryptorTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
index 35166a3dd..1143fd3a2 100644
--- a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
+++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
@@ -167,7 +167,7 @@ public void testEncryptNull() {
fail("New encrypt(PlainText) method did not throw. Result was: " + ct.toString());
} catch(Throwable t) {
// It should be one of these, depending on whether or not assertions are enabled.
- assertTrue( t instanceof NullPointerException || t instanceof AssertionError);
+ assertTrue( t instanceof IllegalArgumentException || t instanceof AssertionError);
}
}
From edab9e3f8b4db407a1dc5e7630fedc2e48c6809b Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Fri, 30 Aug 2013 03:33:42 +0000
Subject: [PATCH 017/812] A few more minor updates have been documented.
---
.../esapi4java-core-2.1-release-notes.txt | 21 ++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/documentation/esapi4java-core-2.1-release-notes.txt b/documentation/esapi4java-core-2.1-release-notes.txt
index b5b04897f..3570d0f88 100644
--- a/documentation/esapi4java-core-2.1-release-notes.txt
+++ b/documentation/esapi4java-core-2.1-release-notes.txt
@@ -28,7 +28,7 @@ ESAPI for Java - 2.1.0 Release Notes
3) Fixed Javadoc for Encoder.encryptForJavaScript(). [Revision r1879]
-4) DefaultEncryptedProperties - made minor javadoc changes.
+4) DefaultEncryptedProperties - made minor Javadoc changes.
5) The ESAPI 2.0 Encryptor.encrypt() methods now all throw an appropriate
IllegalArgumentException if any of the arguments are null. Previously,
@@ -37,8 +37,23 @@ ESAPI for Java - 2.1.0 Release Notes
assertions were disabled. While IllegalArgumentException is still an
unchecked RuntimeException, note that if you were previously catching
NullPointerExceptions for these cases, you may need to change your code.
-
-6) Other miscellaneous minor code clean-up, mostly to remove compiler warnings.
+
+6) The public constructor, CiphertextSerializer(CipherText ct), was changed
+ to explicitly check that the parameter is not null. Previously it had
+ checked with assertions which might later result in a NullPointerException
+ being thrown if assertions were disabled. Now if the parameter is null,
+ an appropriate IllegalArgumentException is thrown. This should not really
+ affect existing code (unless you are experimenting implementing your own
+ crypto) since user code should not really be using CiperTextSerializer
+ directly.
+
+7) Some of the setter methods in KeyDerivationFunction were changed to explicitly
+ check for invalid arguments and throw an IllegalArgumentException rather than
+ checking these parameters via assertions. This should not affect general
+ user code as most would not be calling the KeyDerivationFunction class
+ directly.
+
+8) Other miscellaneous minor code clean-up, mostly to remove compiler warnings.
NOTE: A follow-up patch release is scheduled within the next few months to
address some questionable design decisions regarding what data in
From 602bdd096c69b38afbde655d500cb642f30a3195 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:37:45 +0000
Subject: [PATCH 018/812] General code clean up and new tests to ensure that
new ESAPI release can still deserialize encrypted data from ESAPI 2.0.x.
---
.../crypto/CipherTextSerializerTest.java | 3 +-
.../owasp/esapi/crypto/CipherTextTest.java | 79 ++++++++++++++++---
.../owasp/esapi/crypto/CryptoHelperTest.java | 24 ++++++
.../esapi/reference/crypto/CryptoPolicy.java | 3 +-
.../esapi/reference/crypto/EncryptorTest.java | 3 +-
5 files changed, 96 insertions(+), 16 deletions(-)
diff --git a/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java b/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java
index cf6af911f..9f86b9fb7 100644
--- a/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java
+++ b/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java
@@ -17,7 +17,8 @@
public class CipherTextSerializerTest {
private Cipher encryptor = null;
private IvParameterSpec ivSpec = null; // Note: FindBugs reports false positive
- // about this being unread field.
+ // about this being unread field. See
+ // testAsSerializedByteArray().
@BeforeClass
public static void setUpBeforeClass() throws Exception {
diff --git a/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java b/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java
index 4bf07cfb3..18c7fb505 100644
--- a/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java
+++ b/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java
@@ -35,15 +35,21 @@ public class CipherTextTest {
private static final boolean POST_CLEANUP = true;
- private CipherSpec cipherSpec = null;
+ private CipherSpec cipherSpec_ = null;
private Cipher encryptor = null;
private Cipher decryptor = null;
private IvParameterSpec ivSpec = null;
@BeforeClass public static void preCleanup() {
- // These two calls have side-effects that cause FindBugs to complain.
- new File("ciphertext.ser").delete();
- new File("ciphertext-portable.ser").delete();
+ try {
+ // These two calls have side-effects that cause FindBugs to complain.
+ removeFile("ciphertext.ser");
+ removeFile("ciphertext-portable.ser");
+ // Do NOT remove this file...
+ // src/test/resource/ESAPI2.0-ciphertext-portable.ser
+ } catch(Exception ex) {
+ ; // Do nothing
+ }
}
@Before
@@ -62,8 +68,8 @@ public void tearDown() throws Exception {
@AfterClass public static void postCleanup() {
if ( POST_CLEANUP ) {
// These two calls have side-effects that cause FindBugs to complain.
- new File("ciphertext.ser").delete();
- new File("ciphertext-portable.ser").delete();
+ removeFile("ciphertext.ser");
+ removeFile("ciphertext-portable.ser");
}
}
@@ -72,18 +78,18 @@ public void tearDown() throws Exception {
public final void testCipherText() {
CipherText ct = new CipherText();
- cipherSpec = new CipherSpec();
- assertTrue( ct.getCipherTransformation().equals( cipherSpec.getCipherTransformation()));
- assertTrue( ct.getBlockSize() == cipherSpec.getBlockSize() );
+ cipherSpec_ = new CipherSpec();
+ assertTrue( ct.getCipherTransformation().equals( cipherSpec_.getCipherTransformation()));
+ assertTrue( ct.getBlockSize() == cipherSpec_.getBlockSize() );
}
@Test
public final void testCipherTextCipherSpec() {
- cipherSpec = new CipherSpec("DESede/OFB8/NoPadding", 112);
- CipherText ct = new CipherText( cipherSpec );
+ cipherSpec_ = new CipherSpec("DESede/OFB8/NoPadding", 112);
+ CipherText ct = new CipherText( cipherSpec_ );
assertTrue( ct.getRawCipherText() == null );
assertTrue( ct.getCipherAlgorithm().equals("DESede") );
- assertTrue( ct.getKeySize() == cipherSpec.getKeySize() );
+ assertTrue( ct.getKeySize() == cipherSpec_.getKeySize() );
}
@Test
@@ -200,7 +206,7 @@ public final void testMIC() {
/** Test portable serialization. */
@Test public final void testPortableSerialization() {
- System.err.println("CipherTextTest.testPortableSerialization()...");
+ System.out.println("CipherTextTest.testPortableSerialization()starting...");
String filename = "ciphertext-portable.ser";
File serializedFile = new File(filename);
serializedFile.delete(); // Delete any old serialized file.
@@ -218,6 +224,8 @@ public final void testMIC() {
encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] raw = encryptor.doFinal("This is my secret message!!!".getBytes("UTF8"));
CipherText ciphertext = new CipherText(cipherSpec, raw);
+ // TODO: Replace this w/ call to KeyDerivationFunction as this is
+ // deprecated! Shame on me!
SecretKey authKey = CryptoHelper.computeDerivedKey(key, key.getEncoded().length * 8, "authenticity");
ciphertext.computeAndStoreMAC( authKey );
// System.err.println("Original ciphertext being serialized: " + ciphertext);
@@ -261,6 +269,39 @@ public final void testMIC() {
}
}
+ /** Test portable serialization for backward compatibility with ESAPI 2.0. */
+ @Test public final void testPortableSerializationBackwardCompatibility() {
+ System.out.println("testPortableSerializationBackwardCompatibility()starting...");
+ String filename = "src/test/resources/ESAPI2.0-ciphertext-portable.ser"; // Do NOT remove
+ File serializedFile = new File(filename);
+
+ try {
+ // String expectedMsg = "This is my secret message!!!";
+
+ // NOTE: FindBugs complains about this (OS_OPEN_STREAM). It apparently
+ // is too lame to know that 'fis.read()' is a serious side-effect.
+ FileInputStream fis = new FileInputStream(serializedFile);
+ int avail = fis.available();
+ byte[] bytes = new byte[avail];
+ fis.read(bytes, 0, avail);
+ // We can't go as far and decrypt it because the file was encrypted using a
+ // temporary session key.
+ CipherText restoredCipherText = CipherText.fromPortableSerializedBytes(bytes);
+ assertTrue( restoredCipherText != null );
+ int retrievedKdfVersion = restoredCipherText.getKDFVersion();
+ } catch (EncryptionException e) {
+ Assert.fail("Caught EncryptionException: " + e);
+ } catch (FileNotFoundException e) {
+ Assert.fail("Caught FileNotFoundException: " + e);
+ } catch (IOException e) {
+ Assert.fail("Caught IOException: " + e);
+ } catch (Exception e) {
+ Assert.fail("Caught Exception: " + e);
+ } finally {
+ ; // Do NOT delete the file.
+ }
+ }
+
/** Test Java serialization. */
@Test public final void testJavaSerialization() {
String filename = "ciphertext.ser";
@@ -334,4 +375,16 @@ public final void testMIC() {
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(CipherTextTest.class);
}
+
+ private static void removeFile(String fname) {
+ try {
+ if ( fname != null ) {
+ File f = new File(fname);
+ // Findbugs complains about ignoring this return value. Too bad.
+ f.delete();
+ }
+ } catch(Exception ex) {
+ ; // Do nothing
+ }
+ }
}
diff --git a/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java b/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java
index 0e55723fe..678b0acf8 100644
--- a/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java
+++ b/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java
@@ -140,6 +140,30 @@ public final void testArrayCompare() {
// System.out.println("diff: " + diff + " nanosec");
}
+ @Test
+ public final void testIsValidKDFVersion() {
+ assertTrue( CryptoHelper.isValidKDFVersion(20110203, false, false));
+ assertTrue( CryptoHelper.isValidKDFVersion(20130830, false, false));
+ assertTrue( CryptoHelper.isValidKDFVersion(33330303, false, false));
+ assertTrue( CryptoHelper.isValidKDFVersion(99991231, false, false));
+
+ assertFalse( CryptoHelper.isValidKDFVersion(0, false, false));
+ assertFalse( CryptoHelper.isValidKDFVersion(99991232, false, false));
+ assertFalse( CryptoHelper.isValidKDFVersion(20110202, false, false));
+
+ assertTrue( CryptoHelper.isValidKDFVersion(20110203, true, false));
+ assertTrue( CryptoHelper.isValidKDFVersion(KeyDerivationFunction.kdfVersion, true, false));
+ assertFalse( CryptoHelper.isValidKDFVersion(KeyDerivationFunction.kdfVersion + 1, true, false));
+
+ try {
+ CryptoHelper.isValidKDFVersion(77777777, true, true);
+ fail("Failed to CryptoHelper.isValidKDFVersion() failed to throw IllegalArgumentException.");
+ }
+ catch (Exception e) {
+ assertTrue( e instanceof IllegalArgumentException);
+ }
+ }
+
private void fillByteArray(byte[] ba, byte b) {
for (int i = 0; i < ba.length; i++) {
ba[i] = b;
diff --git a/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java b/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java
index 2a3c26ba4..fe3a8e948 100644
--- a/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java
+++ b/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java
@@ -82,7 +82,8 @@ private static boolean checkCrypto()
// (default) provider.
}
} catch( InvalidKeyException ikex ) {
- System.out.println("Invalid key size - unlimited strength crypto NOT installed!");
+ System.out.println("CryptoPolicy: 256 bits is " +
+ "invalid key size ==> unlimited strength crypto NOT installed!");
return false;
} catch( Exception ex ) {
System.out.println("Caught unexpected exception: " + ex);
diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
index 1143fd3a2..35709a21a 100644
--- a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
+++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java
@@ -443,7 +443,8 @@ public void testVerifySeal() throws EnterpriseSecurityException {
String plaintext = "ridiculous:with:delimiters"; // Should now work w/ : (issue #28)
String seal = instance.seal( plaintext, instance.getRelativeTimeStamp( 1000 * NSEC ) );
try {
- assertTrue( instance.verifySeal( seal ) );
+ assertNotNull("Encryptor.seal() returned null", seal );
+ assertTrue("Failed to verify seal", instance.verifySeal( seal ) );
} catch ( Exception e ) {
fail();
}
From 139318ed3d72cdfe02f08c3b615fb44f3e4273d3 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:38:40 +0000
Subject: [PATCH 019/812] New files to test for backwards compatibility with
revised crypto.
---
.../resources/ESAPI2.0-ciphertext-portable.ser | Bin 0 -> 114 bytes
src/test/resources/Readme.txt | 5 +++++
2 files changed, 5 insertions(+)
create mode 100644 src/test/resources/ESAPI2.0-ciphertext-portable.ser
create mode 100644 src/test/resources/Readme.txt
diff --git a/src/test/resources/ESAPI2.0-ciphertext-portable.ser b/src/test/resources/ESAPI2.0-ciphertext-portable.ser
new file mode 100644
index 0000000000000000000000000000000000000000..dfe173c949c6042b597f746264843043b7099c3d
GIT binary patch
literal 114
zcmV-&0FD0X8?cz5C9M}UtOUT
zaVIqAW!lU8Y0KyU001CaI}ONJlv$P>6$gX61o{yuTRg(Zey7RQAXyyi0S!9<6k}LZ
USwZS~D$eSlIH?=UHzN7)_<&j}umAu6
literal 0
HcmV?d00001
diff --git a/src/test/resources/Readme.txt b/src/test/resources/Readme.txt
new file mode 100644
index 000000000..1bb4585ed
--- /dev/null
+++ b/src/test/resources/Readme.txt
@@ -0,0 +1,5 @@
+ESAPI2.0-ciphertext-portable.ser is a test for the backwards compatibility
+of ESAPI 2.1.x and later crypto with ESAPI 2.0 crypto.
+
+The file was created on Windows using the 128-bit test key from
+Encryptor.MasterKey and encrypted with AES/CBC/PKCS5Padding.
From b69a2261ebe0feef88b0580806275b4088035d8e Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:41:13 +0000
Subject: [PATCH 020/812] Changes to ensure backward compatibility with
previous ESAPI crypto from ESAPI 2.0 / 2.0.1 releases (crypto version
20110203).
---
.../org/owasp/esapi/crypto/CipherSpec.java | 3 +-
.../org/owasp/esapi/crypto/CipherText.java | 21 ++-
.../esapi/crypto/CipherTextSerializer.java | 151 ++++++++++++++----
.../org/owasp/esapi/crypto/CryptoHelper.java | 43 ++++-
.../org/owasp/esapi/crypto/CryptoToken.java | 4 +-
.../esapi/crypto/KeyDerivationFunction.java | 37 +++--
6 files changed, 215 insertions(+), 44 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherSpec.java b/src/main/java/org/owasp/esapi/crypto/CipherSpec.java
index ac9237fac..556ef8edb 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherSpec.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherSpec.java
@@ -365,7 +365,8 @@ public int hashCode() {
* will just allow it to work in the future should we decide to allow
* sub-classing of this class.)
*
*/
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherText.java b/src/main/java/org/owasp/esapi/crypto/CipherText.java
index 689ef1c21..47e6fc78f 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherText.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherText.java
@@ -102,6 +102,17 @@ private enum CipherTextFlags {
// How much we've collected so far. We start out with having collected nothing.
private EnumSet progress = EnumSet.noneOf(CipherTextFlags.class);
+
+ // Check if versions of KeyDerivationFunction, CipherText, and
+ // CipherTextSerializer are all the same.
+ {
+ // Ignore error about comparing identical versions and dead code.
+ // We expect them to be, but the point is to catch us if they aren't.
+ assert CipherTextSerializer.cipherTextSerializerVersion == CipherText.cipherTextVersion :
+ "Versions of CipherTextSerializer and CipherText are not compatible.";
+ assert CipherTextSerializer.cipherTextSerializerVersion == KeyDerivationFunction.kdfVersion :
+ "Versions of CipherTextSerializer and KeyDerivationFunction are not compatible.";
+ }
/////////////////////////// C O N S T R U C T O R S /////////////////////////
@@ -307,7 +318,9 @@ public int getRawCipherTextByteLength() {
*
* If there is a need to store an encrypted value, say in a database, this
* is not the method you should use unless you are using a fixed
- * IV. If you are not using a fixed IV, you should normally use
+ * IV or are planning on retrieving the IV and storing it somewhere separately
+ * (e.g., a different database column). If you are not using a fixed IV
+ * (which is highly discouraged), you should normally use
* {@link #getEncodedIVCipherText()} instead.
*
* @see #getEncodedIVCipherText()
@@ -566,7 +579,7 @@ public int getKDFVersion() {
}
public void setKDFVersion(int vers) {
- assert vers > 0 && vers <= 99991231 : "Version must be positive, in format YYYYMMDD and <= 99991231.";
+ CryptoHelper.isValidKDFVersion(vers, false, true);
kdfVersion_ = vers;
}
@@ -843,8 +856,8 @@ public int getKDFInfo() {
// kdf version is bits 1-27, bit 28 (reserved) should be 0, and
// bits 29-32 are the MAC algorithm indicating which PRF to use for the KDF.
- int kdfVers = getKDFVersion();
- assert kdfVers > 0 && kdfVers <= 99991231 : "KDF version (YYYYMMDD, max 99991231) out of range: " + kdfVers;
+ int kdfVers = this.getKDFVersion();
+ assert CryptoHelper.isValidKDFVersion(kdfVers, true, false);
int kdfInfo = kdfVers;
int macAlg = kdfPRFAsInt();
assert macAlg >= 0 && macAlg <= 15 : "MAC algorithm indicator must be between 0 to 15 inclusion; value is: " + macAlg;
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
index b00dd245c..ee69e7baf 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
@@ -24,27 +24,45 @@
* Message Syntax (CMS) Authenticated-Enveloped-Data Content Type, or CMS' predecessor,
* PKCS#7 (RFC 2315)), but these serialization schemes are by comparison very complicated,
* and do not have extensive support for the various implementation languages which ESAPI
- * supports.
+ * supports. (Perhaps wishful thinking that other ESAPI implementations such as
+ * ESAPI for .NET, ESAPI for C, ESAPI for C++, etc. will all support a single, common
+ * serialization technique so they could exchange encrypted data.)
*
* @author kevin.w.wall@gmail.com
*
*/
public class CipherTextSerializer {
- // This should be *same* version as in CipherText & KeyDerivationFunction.
- // If one changes, the other should as well to accommodate any differences.
+ // This should be *same* version as in CipherText & KeyDerivationFunction as
+ // these versions all need to work together. Therefore, when one changes one
+ // one these versions, the other should be reviewed and changed as well to
+ // accommodate any differences.
// Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1)
// 20130830 - Fix to issue #306 (release 2.1.0)
- public static final int cipherTextSerializerVersion = 20130830; // Format: YYYYMMDD, max is 99991231.
+ // We check that in an static initialization block (when assertions are enabled)
+ // below.
+ public static final int cipherTextSerializerVersion = 20130830; // Current version. Format: YYYYMMDD, max is 99991231.
private static final long serialVersionUID = cipherTextSerializerVersion;
private static final Logger logger = ESAPI.getLogger("CipherTextSerializer");
private CipherText cipherText_ = null;
+ // Check if versions of KeyDerivationFunction, CipherText, and
+ // CipherTextSerializer are all the same.
+ {
+ // Ignore error about comparing identical versions and dead code.
+ // We expect them to be, but the point is to catch us if they aren't.
+ assert CipherTextSerializer.cipherTextSerializerVersion == CipherText.cipherTextVersion :
+ "Versions of CipherTextSerializer and CipherText are not compatible.";
+ assert CipherTextSerializer.cipherTextSerializerVersion == KeyDerivationFunction.kdfVersion :
+ "Versions of CipherTextSerializer and KeyDerivationFunction are not compatible.";
+ }
+
public CipherTextSerializer(CipherText cipherTextObj) {
- assert cipherTextObj != null : "CipherText object must not be null.";
- assert cipherTextSerializerVersion == CipherText.cipherTextVersion :
- "Version of CipherText and CipherTextSerializer not compatible.";
+ if ( cipherTextObj == null ) {
+ throw new IllegalArgumentException("CipherText object must not be null.");
+ }
+ assert cipherTextObj != null : "CipherText object must not be null.";
cipherText_ = cipherTextObj;
}
@@ -59,8 +77,6 @@ public CipherTextSerializer(CipherText cipherTextObj) {
public CipherTextSerializer(byte[] cipherTextSerializedBytes)
throws EncryptionException /* DISCUSS: Change exception type?? */
{
- assert cipherTextSerializerVersion == CipherText.cipherTextVersion :
- "Version of CipherText and CipherTextSerializer not compatible.";
cipherText_ = convertToCipherText(cipherTextSerializedBytes);
}
@@ -69,7 +85,6 @@ public CipherTextSerializer(byte[] cipherTextSerializedBytes)
* @return A serialization of this object. Note that this is not the
* Java serialization.
*/
- @SuppressWarnings("static-access")
public byte[] asSerializedByteArray() {
int kdfInfo = cipherText_.getKDFInfo();
debug("asSerializedByteArray: kdfInfo = " + kdfInfo);
@@ -114,9 +129,35 @@ public byte[] asSerializedByteArray() {
* @return The {@code CipherText} object that we are serializing.
*/
public CipherText asCipherText() {
+ assert cipherText_ != null;
return cipherText_;
}
+ /**
+ * Take all the individual elements that make of the serialized ciphertext
+ * format and put them in order and return them as a byte array.
+ * @param kdfInfo Info about the KDF... which PRF and the KDF version {@link #asCipherText()}.
+ * @param timestamp Timestamp when the data was encrypted. Intended to help
+ * facilitate key change operations and nothing more. If it is meaningless,
+ * then the expectations are just that the recipient should ignore it. Mostly
+ * intended when encrypted data is kept long term over a period of many
+ * key change operations.
+ * @param cipherXform Details of how the ciphertext was encrypted. The format used
+ * is the same as used by {@code javax.crypto.Cipher}, namely,
+ * "cipherAlg/cipherMode/paddingScheme".
+ * @param keySize The key size used for encrypting. Intended for cipher algorithms
+ * supporting multiple key sizes such as triple DES (DESede) or
+ * Blowfish.
+ * @param blockSize The cipher block size. Intended to support cipher algorithms
+ * that support variable block sizes, such as Rijndael.
+ * @param ivLen The length of the IV.
+ * @param iv The actual IV (initialization vector) bytes.
+ * @param ciphertextLen The length of the raw ciphertext.
+ * @param rawCiphertext The actual raw ciphertext itself
+ * @param macLen The length of the MAC (message authentication code).
+ * @param mac The MAC itself.
+ * @return A byte array representing the serialized ciphertext.
+ */
private byte[] computeSerialization(int kdfInfo, long timestamp,
String cipherXform, short keySize,
short blockSize,
@@ -152,7 +193,9 @@ private byte[] computeSerialization(int kdfInfo, long timestamp,
}
// All strings are written as UTF-8 encoded byte streams with the
- // length prepended before it as a short.
+ // length prepended before it as a short. The prepended length is
+ // more for the benefit of languages like C so they can pre-allocate
+ // char arrays without worrying about buffer overflows.
private void writeString(ByteArrayOutputStream baos, String str) {
byte[] bytes;
try {
@@ -223,6 +266,13 @@ private long readLong(ByteArrayInputStream bais)
return ByteConversionUtil.toLong(longAsByteArray);
}
+ /** Convert the serialized ciphertext byte array to a {@code CipherText}
+ * object.
+ * @param cipherTextSerializedBytes The serialized ciphertext as a byte array.
+ * @return The corresponding {@code CipherText} object.
+ * @throws EncryptionException Thrown if the byte array data is corrupt or
+ * there are version mismatches, etc.
+ */
private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
throws EncryptionException
{
@@ -236,19 +286,27 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
debug("kdfPrf: " + kdfPrf);
assert kdfPrf >= 0 && kdfPrf <= 15 : "kdfPrf == " + kdfPrf + " must be between 0 and 15.";
int kdfVers = ( kdfInfo & 0x07ffffff);
- assert kdfVers >= 20110203 && kdfVers <= 99991231 : "KDF Version (" + kdfVers + ") out of range."; // 20110203 (orig version).
+
+ // First do a quick sanity check on the argument. Previously this was an assertion.
+ if ( ! CryptoHelper.isValidKDFVersion(kdfVers, false, false) ) {
+ // TODO: Clean up. Use StringBuilder. Good enough for now.
+ String logMsg = "KDF version read from serialized ciphertext (" + kdfVers + ") is out of range. " +
+ "Valid range for KDF version is [" + KeyDerivationFunction.originalVersion + ", " +
+ "99991231].";
+ // This should never happen under actual circumstances (barring programming errors; but we've
+ // tested the code, right?), so it is likely an attempted attack. Thus don't get the originator
+ // of the suspect ciphertext too much info. They ought to know what they sent anyhow.
+ throw new EncryptionException("Version info from serialized ciphertext not in valid range.",
+ "Likely tampering with KDF version on serialized ciphertext." + logMsg);
+ }
+
debug("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers);
- if ( kdfVers != CipherText.cipherTextVersion ) {
- // NOTE: In future, support backward compatibility via this mechanism. When we do this
- // we will have to compare as longs and watch out for sign extension of kdfInfo
- // since it may have the sign bit set. Then we will do different things depending
- // on what KDF version we encounter. However, as for now, since this is
- // is first ESAPI 2.0 GA version, there nothing to be backward compatible with.
- // (We did not promise backward compatibility for earlier release candidates.)
- // Thus any version mismatch at this point is an error.
- throw new InvalidClassException("This serialized byte stream not compatible " +
- "with loaded CipherText class. Version read = " + kdfInfo +
- "; version from loaded CipherText class = " + CipherText.cipherTextVersion);
+ System.err.println("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers);
+
+ if ( ! versionIsCompatible( kdfVers) ) {
+ throw new EncryptionException("This version of ESAPI does is not compatible with the version of ESAPI that encrypted your data.",
+ "KDF version " + kdfVers + " from serialized ciphertext not compatibile with current KDF version of " +
+ KeyDerivationFunction.kdfVersion);
}
long timestamp = readLong(bais);
debug("convertToCipherText: timestamp = " + new Date(timestamp));
@@ -292,8 +350,10 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
cipherSpec.setIV(iv);
debug("convertToCipherText: CipherSpec: " + cipherSpec);
CipherText ct = new CipherText(cipherSpec);
- assert (ivLen > 0 && ct.requiresIV()) :
- "convertToCipherText: Mismatch between IV length and cipher mode.";
+ if ( ! (ivLen > 0 && ct.requiresIV()) ) {
+ throw new EncryptionException("convertToCipherText: Mismatch between IV length and cipher mode.",
+ "Possible tampering of serialized ciphertext?");
+ }
ct.setCiphertext(rawCiphertext);
// Set this *AFTER* setting raw ciphertext because setCiphertext()
// method also sets encryption time.
@@ -301,6 +361,13 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
if ( macLen > 0 ) {
ct.storeSeparateMAC(mac);
}
+ // Fixed in ESAPI crypto version 20130839. Previously is didn't really matter
+ // because there was only one version (20110203) and it defaulted to that
+ // version, which was the current version. But we don't want that as now there
+ // are two versions and we could be decrypting data encrypted using the previous
+ // version.
+ ct.setKDF_PRF(kdfPrf);
+ ct.setKDFVersion(kdfVers);
return ct;
} catch(EncryptionException ex) {
throw new EncryptionException("Cannot deserialize byte array into CipherText object",
@@ -311,8 +378,38 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
"Cannot deserialize byte array into CipherText object", e);
}
}
-
- private void debug(String msg) {
+
+ /** Check to see if we can support the KSF version that was extracted from
+ * the serialized ciphertext. In particular, we assume that if we have a
+ * newer version of KDF than we can support it as we assume that we have
+ * built in backward compatibility.
+ *
+ * At this point (ESAPI 2.1.0, KDF version 20130830), all we need to check
+ * if the version is either the current version or the previous version as
+ * both versions work the same. This checking may get more complicated in
+ * the future.
+ *
+ * @param readKdfVers The version information extracted from the serialized
+ * ciphertext.
+ */
+ private static boolean versionIsCompatible(int readKdfVers) {
+ // We've checked elsewhere for this, so assertion is OK here.
+ assert readKdfVers > 0 : "Extracted KDF version is negative!";
+
+ switch ( readKdfVers ) {
+ case KeyDerivationFunction.originalVersion: // First version
+ return true;
+ // Add new versions here; hard coding is OK...
+ // case YYYYMMDD:
+ // return true;
+ case KeyDerivationFunction.kdfVersion: // Current version
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void debug(String msg) {
if ( logger.isDebugEnabled() ) {
logger.debug(Logger.EVENT_SUCCESS, msg);
}
diff --git a/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java b/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java
index 2763a2832..024150bda 100644
--- a/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java
+++ b/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java
@@ -210,7 +210,7 @@ public static boolean isAllowedCipherMode(String cipherMode)
*
* @param ct The specified {@code CipherText} object to check to see if
* it requires a MAC.
- * @returns True if a MAC is required, false if it is not required.
+ * @return True if a MAC is required, false if it is not required.
*/
public static boolean isMACRequired(CipherText ct) {
boolean preferredCipherMode =
@@ -345,10 +345,51 @@ public static boolean arrayCompare(byte[] b1, byte[] b2) {
return (result == 0) ? true : false;
}
+ /**
+ * Is this particular KDF version number one that is sane? For that, we
+ * just make sure it is inbounds of the valid range which is:
+ *
+ * [20110203, 99991231]
+ *
+ * @param kdfVers KDF version # that we are checking. Generally this is
+ * extracted from the serialized {@code CipherText}.
+ * @param restrictToCurrent If this is set, we do an additional check
+ * to see if the KDF version is a later version than the
+ * one that this current ESAPI version supports.
+ * @param throwIfError Instead of returning {@code false} in the case of
+ * an error, throw an {@code IllegalArgumentException}
+ * @return True if in range, false otherwise (except if {@code throwIfError}
+ * is true.}
+ */
+ public static boolean isValidKDFVersion(int kdfVers, boolean restrictToCurrent,
+ boolean throwIfError)
+ throws IllegalArgumentException
+ {
+ boolean ret = true;
+
+ if ( kdfVers < KeyDerivationFunction.originalVersion || kdfVers > 99991231 ) {
+ ret = false;
+ } else if ( restrictToCurrent ) {
+ ret = ( kdfVers <= KeyDerivationFunction.kdfVersion );
+ }
+ if ( ret ) {
+ return ret; // True
+ } else { // False, so throw or not.
+ logger.warning(Logger.SECURITY_FAILURE, "Possible data tampering. Encountered invalid KDF version #. " +
+ ( throwIfError ? "Throwing IllegalArgumentException" : "" ));
+ if ( throwIfError ) {
+ throw new IllegalArgumentException("Version (" + kdfVers + ") invalid. " +
+ "Must be date in format of YYYYMMDD between " + KeyDerivationFunction.originalVersion + "and 99991231.");
+ }
+ }
+ return false;
+ }
+
/**
* Prevent public, no-argument CTOR from being auto-generated. Public CTOR
* is not needed as all methods are static.
*/
private CryptoHelper() {
+ ; // Prevent default CTOR from being auto-created.
}
}
diff --git a/src/main/java/org/owasp/esapi/crypto/CryptoToken.java b/src/main/java/org/owasp/esapi/crypto/CryptoToken.java
index 8df9dc107..4276079f9 100644
--- a/src/main/java/org/owasp/esapi/crypto/CryptoToken.java
+++ b/src/main/java/org/owasp/esapi/crypto/CryptoToken.java
@@ -250,8 +250,8 @@ public boolean isExpired() {
/**
* Set expiration time to expire in 'interval' seconds (NOT milliseconds).
- * @param interval Number of seconds in the future from current date/time
- * to set expiration. Must be positive.
+ * @param intervalSecs Number of seconds in the future from current date/time
+ * to set expiration. Must be positive.
*/
public void setExpiration(int intervalSecs) throws IllegalArgumentException
{
diff --git a/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
index 40c095b89..17635ce5a 100644
--- a/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
+++ b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java
@@ -57,7 +57,8 @@ public class KeyDerivationFunction {
* @see CipherText#asPortableSerializedByteArray()
* @see CipherText#fromPortableSerializedBytes(byte[])
*/
- public static final int kdfVersion = 20130830; // Format: YYYYMMDD, max is 99991231.
+ public static final int originalVersion = 20110203; // First version. Do not change. EVER!
+ public static final int kdfVersion = 20130830; // Current version. Format: YYYYMMDD, max is 99991231.
private static final long serialVersionUID = kdfVersion; // Format: YYYYMMDD
// Pseudo-random function algorithms suitable for NIST KDF in counter mode.
@@ -102,6 +103,17 @@ public enum PRF_ALGORITHMS {
private int version_ = kdfVersion;
private String context_ = "";
+ // Check if versions of KeyDerivationFunction, CipherText, and
+ // CipherTextSerializer are all the same.
+ {
+ // Ignore error about comparing identical versions and dead code.
+ // We expect them to be, but the point is to catch us if they aren't.
+ assert CipherTextSerializer.cipherTextSerializerVersion == CipherText.cipherTextVersion :
+ "Versions of CipherTextSerializer and CipherText are not compatible.";
+ assert CipherTextSerializer.cipherTextSerializerVersion == KeyDerivationFunction.kdfVersion :
+ "Versions of CipherTextSerializer and KeyDerivationFunction are not compatible.";
+ }
+
/**
* Construct a {@code KeyDerivationFunction}.
* @param prfAlg Specifies a supported algorithm.
@@ -155,12 +167,11 @@ static int getDefaultPRFSelection() {
* be decrypted.
* @param version Date as a integer, in format of YYYYMMDD. Maximum
* version date is 99991231 (December 31, 9999).
+ * @throws IllegalArgumentException If {@code version} is not within
+ * the valid range of [20110203, 99991231].
*/
- public void setVersion(int version) {
- if ( version < 0 || version > 99991231 ) {
- throw new IllegalArgumentException("Version (" + version + ") invalid. " +
- "Must be date in format of YYYYMMDD < 99991231.");
- }
+ public void setVersion(int version) throws IllegalArgumentException {
+ CryptoHelper.isValidKDFVersion(version, false, true);
this.version_ = version;
}
@@ -173,6 +184,12 @@ public int getVersion() {
return version_;
}
+
+ // TODO: IMPORTANT NOTE: In a future release (hopefully starting in 2.1.1),
+ // we will be using the 'context' to mix in some additional things. At a
+ // minimum, we will be using the KDF version (version_) so that downgrade version
+ // attacks are not possible. Other candidates are the cipher xform and
+ // the timestamp.
/**
* Set the 'context' as specified by NIST Special Publication 800-108. NIST
* defines 'context' as "A binary string containing the information related
@@ -186,7 +203,7 @@ public int getVersion() {
* entities and other information to identify the derived
* keying material. This is called context binding.
* In particular, the identity (or identifier, as the term
- * is defined in [NIST SP 800- 56A , sic] and [NIST SP
+ * is defined in [NIST SP 800-56A , sic] and [NIST SP
* 800-56B , sic]) of each entity that will access (meaning
* derive, hold, use, and/or distribute) any segment of
* the keying material should be included in the Context
@@ -204,7 +221,9 @@ public int getVersion() {
* value but {@code null}.
*/
public void setContext(String context) {
- assert context != null : "Context may not be null.";
+ if ( context == null ) {
+ throw new IllegalArgumentException("Context may not be null.");
+ }
context_ = context;
}
@@ -239,7 +258,7 @@ public String getContext() {
* @param keyDerivationKey A key used as an input to a key derivation function
* to derive other keys. This is the key that generally
* is created using some key generation mechanism such as
- * {@link #generateSecretKey(String, int)}. The
+ * {@link CryptoHelper#generateSecretKey(String, int)}. The
* "input" key from which the other keys are derived.
* The derived key will have the same algorithm type
* as this key. This KDK cannot be null.
From d08e7f81397ebadaef033dd53f14c0f4b79b0393 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:43:12 +0000
Subject: [PATCH 021/812] Future 'TODO' comment to ensure future backward
compatibility with previous ESAPI crypto versions going forward. A reminder
for release 2.1.1 and later.
---
src/main/java/org/owasp/esapi/crypto/PlainText.java | 3 ++-
.../org/owasp/esapi/crypto/SecurityProviderLoader.java | 8 ++++----
.../org/owasp/esapi/reference/crypto/JavaEncryptor.java | 9 +++++++++
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/crypto/PlainText.java b/src/main/java/org/owasp/esapi/crypto/PlainText.java
index bfa9fd3a2..4491404d5 100644
--- a/src/main/java/org/owasp/esapi/crypto/PlainText.java
+++ b/src/main/java/org/owasp/esapi/crypto/PlainText.java
@@ -148,7 +148,8 @@ public void overwrite() {
* though; this will just allow it to work in the future should we
* decide to allow * sub-classing of this class.)
*
*/
diff --git a/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java b/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java
index 1c1e35ae8..cacc9c9ef 100644
--- a/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java
+++ b/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java
@@ -100,13 +100,13 @@ public class SecurityProviderLoader {
* certificate has expired as of August 28, 2009. (This likely is true
* for ABA, but I can't even find a copy to download!). Lastly, the IAIK
* provider is no longer offered as free, open source. It is not a
- * commercial product. See {@link http://jce.iaik.tugraz.at/} for
+ * commercial product. See {@link "http://jce.iaik.tugraz.at/"} for
* details. While some older versions were offered free, it is not clear
* whether the accompanying license still allows you to use it, and if
* it does, whether or not the code signing certificate used to sign
* their JCE jar(s) has expired are not. Therefore, if you are looking
* for a FOSS alternative to SunJCE, Bouncy Castle
- * ({@link http://www.bouncycastle.org/} is probably your best bet. The
+ * ({@link "http://www.bouncycastle.org/"} is probably your best bet. The
* BC provider does support many the "combined cipher modes" that provide
* both confidentiality and authenticity. (See the {@code ESAPI.properties}
* property {@code Encryptor.cipher_modes.combined_modes} for details.)
@@ -116,9 +116,9 @@ public class SecurityProviderLoader {
* by NIST's Cryptographic Module Validation Program and are therefore
* not considered FIPS 140-2 compliant. There are a few approved
* JCE compatible Java libraries that are on NIST's CMVP list, but this
- * list changes constantly so they are not listed here. For futher details
+ * list changes constantly so they are not listed here. For further details
* on NIST's CMVP, see
- * {@link http://csrc.nist.gov/groups/STM/cmvp/index.html}.
+ * {@link "http://csrc.nist.gov/groups/STM/cmvp/index.html"}.
*
* Finally, if you wish to use some other JCE provider not recognized above,
* you must specify the provider's fully-qualified class name (which in
diff --git a/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
index 064fa932c..a20c6122f 100644
--- a/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
+++ b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
@@ -692,6 +692,15 @@ private PlainText handleDecryption(SecretKey key, CipherText ciphertext)
// But remember Jon Bentley's "Rule #1 on performance: First make it right, then make it fast."
// This would be a security trade-off as it would leave keys in memory a bit longer, so it
// should probably be off by default and controlled via a property.
+ //
+ // TODO: Feed in some additional parms here to use as the 'context' for the
+ // KeyDerivationFunction...especially the KDF version. We would have to
+ // store that in the CipherText object. We *possibly* could make it
+ // transient so it would not be serialized with the CipherText object,
+ // otherwise we would have to implement readObject() and writeObject()
+ // methods there to support backward compatibility. Anyhow the intent
+ // is to prevent down grade attacks when we finally re-design and
+ // re-implement the MAC. Think about this in version 2.1.1.
encKey = computeDerivedKey( ciphertext.getKDFVersion(), ciphertext.getKDF_PRF(),
key, keySize, "encryption");
}
From 9162dcd5cc5edd97920d7fc99606803802f41212 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:44:12 +0000
Subject: [PATCH 022/812] Javadoc cleanup.
---
src/main/java/org/owasp/esapi/Encoder.java | 6 +++---
src/main/java/org/owasp/esapi/SecurityConfiguration.java | 2 +-
src/main/java/org/owasp/esapi/codecs/MySQLCodec.java | 2 +-
src/main/java/org/owasp/esapi/codecs/PercentCodec.java | 4 ++--
src/main/java/org/owasp/esapi/codecs/PushbackString.java | 8 +++-----
.../org/owasp/esapi/reference/AbstractAuthenticator.java | 3 ++-
.../java/org/owasp/esapi/reference/DefaultExecutor.java | 2 --
.../org/owasp/esapi/reference/DefaultHTTPUtilities.java | 3 ++-
.../java/org/owasp/esapi/waf/ConfigurationException.java | 2 +-
.../esapi/waf/configuration/ConfigurationParser.java | 2 +-
10 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/Encoder.java b/src/main/java/org/owasp/esapi/Encoder.java
index 8a0ccd94e..3bce42fc4 100644
--- a/src/main/java/org/owasp/esapi/Encoder.java
+++ b/src/main/java/org/owasp/esapi/Encoder.java
@@ -295,9 +295,9 @@ public interface Encoder {
*
* For example:
*
- *
+ * <script>
+ * window.setInterval('<%= EVEN IF YOU ENCODE UNTRUSTED DATA YOU ARE XSSED HERE %>');
+ * </script>
*
* @param input
* the text to encode for JavaScript
diff --git a/src/main/java/org/owasp/esapi/SecurityConfiguration.java b/src/main/java/org/owasp/esapi/SecurityConfiguration.java
index 1700d66f5..9c54acb9c 100644
--- a/src/main/java/org/owasp/esapi/SecurityConfiguration.java
+++ b/src/main/java/org/owasp/esapi/SecurityConfiguration.java
@@ -288,7 +288,7 @@ public interface SecurityConfiguration {
* to an empty string, which means that the preferred JCE provider is not
* changed.
* @return The property {@code Encryptor.PreferredJCEProvider} is returned.
- * @see org.owasp.esapi.crypto.SecurityProvider
+ * @see org.owasp.esapi.crypto.SecurityProviderLoader
*/
public String getPreferredJCEProvider();
diff --git a/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java b/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java
index 7bdc60d39..01db4faf5 100644
--- a/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java
+++ b/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java
@@ -52,7 +52,7 @@ static Mode findByKey(int key) {
/** Target MySQL Server is running in Standard MySQL (Default) mode. */
public static final int MYSQL_MODE = 0;
- /** Target MySQL Server is running in {@link http://dev.mysql.com/doc/refman/5.0/en/ansi-mode.html ANSI Mode} */
+ /** Target MySQL Server is running in {@link "http://dev.mysql.com/doc/refman/5.0/en/ansi-mode.html"} ANSI Mode */
public static final int ANSI_MODE = 1;
//private int mode = 0;
diff --git a/src/main/java/org/owasp/esapi/codecs/PercentCodec.java b/src/main/java/org/owasp/esapi/codecs/PercentCodec.java
index 147795ab5..307da471a 100644
--- a/src/main/java/org/owasp/esapi/codecs/PercentCodec.java
+++ b/src/main/java/org/owasp/esapi/codecs/PercentCodec.java
@@ -47,7 +47,7 @@ public class PercentCodec extends Codec
/**
* Convinence method to encode a string into UTF-8. This
* wraps the {@link UnsupportedEncodingException} that
- * {@link String.getBytes(String)} throws in a
+ * {@link String#getBytes(String)} throws in a
* {@link IllegalStateException} as UTF-8 support is required
* by the Java spec and should never throw this exception.
* @param str the string to encode
@@ -72,7 +72,7 @@ private static byte[] toUtf8Bytes(String str)
* Append the two upper case hex characters for a byte.
* @param sb The string buffer to append to.
* @param b The byte to hexify
- * @returns sb with the hex characters appended.
+ * @return sb with the hex characters appended.
*/
// rfc3986 2.1: For consistency, URI producers
// should use uppercase hexadecimal digits for all percent-
diff --git a/src/main/java/org/owasp/esapi/codecs/PushbackString.java b/src/main/java/org/owasp/esapi/codecs/PushbackString.java
index 60a4c5e13..d218eb932 100644
--- a/src/main/java/org/owasp/esapi/codecs/PushbackString.java
+++ b/src/main/java/org/owasp/esapi/codecs/PushbackString.java
@@ -49,12 +49,10 @@ public void pushback( Character c ) {
pushback = c;
}
- /*
- * Get the current index of the PushbackString. Typically used in error messages.
- */
+
/**
- *
- * @return
+ * Get the current index of the PushbackString. Typically used in error messages.
+ * @return The current index of the PushbackString.
*/
public int index() {
return index;
diff --git a/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java b/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java
index 6a5ecdd43..4876da49d 100644
--- a/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java
+++ b/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java
@@ -115,7 +115,8 @@ protected DefaultUser getUserFromRememberToken() {
String token = ESAPI.httpUtilities().getCookie(ESAPI.currentRequest(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME);
if (token == null) return null;
- // TODO - kww - URLDecode token first, and THEN unseal. See Google Issue 144.
+ // See Google Issue 144 regarding first URLDecode the token and THEN unsealing.
+ // Note that this Google Issue was marked as "WontFix".
String[] data = ESAPI.encryptor().unseal(token).split("\\|");
if (data.length != 2) {
diff --git a/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java b/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java
index 1cfc91f96..9f4976591 100644
--- a/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java
+++ b/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java
@@ -199,8 +199,6 @@ public ExecuteResult executeSystemCommand(File executable, List params, File wor
*
* @param is
* input stream to read from
- * @return
- * a string containing as many lines as the input stream contains, with newlines between lines
* @throws IOException
*/
private static void readStream( InputStream is, StringBuilder sb ) throws IOException {
diff --git a/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java
index b1bf850d4..dc99d76b3 100644
--- a/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java
+++ b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java
@@ -912,7 +912,8 @@ public String setRememberToken( HttpServletRequest request, HttpServletResponse
long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000);
String cryptToken = ESAPI.encryptor().seal(clearToken, expiry);
- // TODO - URLEncode cryptToken before creating cookie? See Google Issue # 144 - KWW
+ // Do NOT URLEncode cryptToken before creating cookie. See Google Issue # 144,
+ // which was marked as "WontFix".
Cookie cookie = new Cookie( REMEMBER_TOKEN_COOKIE_NAME, cryptToken );
cookie.setMaxAge( maxAge );
diff --git a/src/main/java/org/owasp/esapi/waf/ConfigurationException.java b/src/main/java/org/owasp/esapi/waf/ConfigurationException.java
index 314828bfd..9ea04fd7b 100644
--- a/src/main/java/org/owasp/esapi/waf/ConfigurationException.java
+++ b/src/main/java/org/owasp/esapi/waf/ConfigurationException.java
@@ -23,7 +23,7 @@
* The Exception to be thrown when there is an error parsing a policy file.
*
* @author Arshan Dabirsiaghi
- * @see org.owasp.esapi.configuration.ConfigurationParser
+ * @see org.owasp.esapi.waf.configuration.ConfigurationParser
*
*/
public class ConfigurationException extends EnterpriseSecurityException {
diff --git a/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java b/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java
index 2087eee2f..2366fcdf5 100644
--- a/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java
+++ b/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java
@@ -56,7 +56,7 @@
* The class used to turn a policy file's contents into an object model.
*
* @author Arshan Dabirsiaghi
- * @see org.owasp.esapi.waf.AppGuardianConfiguration
+ * @see org.owasp.esapi.waf.configuration.AppGuardianConfiguration
*/
public class ConfigurationParser {
From 67fa255324a597c750acd9e6cfffcdddf0cc83c5 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sat, 31 Aug 2013 22:47:29 +0000
Subject: [PATCH 023/812] Ant script to create Javadoc.
---
ant-javadoc.xml | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 ant-javadoc.xml
diff --git a/ant-javadoc.xml b/ant-javadoc.xml
new file mode 100644
index 000000000..084d4d1dc
--- /dev/null
+++ b/ant-javadoc.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
From e707ac86e6e162ecc64b7fd95f04fc3579d6e8b7 Mon Sep 17 00:00:00 2001
From: "chris.schmidt@owasp.org"
Date: Mon, 2 Sep 2013 20:38:25 +0000
Subject: [PATCH 024/812] Updating version back to snapshot to perform release
---
pom.xml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 2de9b9a73..39ec222cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.owasp.esapiesapi
- 2.1.0
+ 2.1.0-SNAPSHOTjar
@@ -245,6 +245,7 @@
+
+ compile <!– Eclipse q4e plugin needs this –>
display-dependency-updatesdisplay-plugin-updates
@@ -261,6 +262,7 @@
+-->
From 97d4891a1a2b277dc5997e04923bc697dd437ee8 Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Mon, 2 Sep 2013 21:47:22 +0000
Subject: [PATCH 025/812] Final clean up. Removed erroneous code from
ESAPICryptoMACByPassTest.java that caused (correct) AssertionError when
assertions were enabled during execution of JUnit tests. Removed superfluous
System.err.println() in CipherTextSerializer.
---
src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java | 2 --
.../java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java | 3 +--
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
index ee69e7baf..2a6caebff 100644
--- a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
+++ b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java
@@ -301,8 +301,6 @@ private CipherText convertToCipherText(byte[] cipherTextSerializedBytes)
}
debug("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers);
- System.err.println("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers);
-
if ( ! versionIsCompatible( kdfVers) ) {
throw new EncryptionException("This version of ESAPI does is not compatible with the version of ESAPI that encrypted your data.",
"KDF version " + kdfVers + " from serialized ciphertext not compatibile with current KDF version of " +
diff --git a/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
index 34878c705..e54ad33f8 100644
--- a/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
+++ b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java
@@ -54,7 +54,7 @@ public void setUp() throws NoSuchAlgorithmException, InvalidKeySpecException {
@Test
public void testMacBypass() throws EncryptionException, NoSuchFieldException, IllegalAccessException {
- byte[] bkey = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xA,0x0B,0x0C,0x0D,0x0E,0x0F}; //Truly random key.
+ byte[] bkey = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xA,0x0B,0x0C,0x0D,0x0E,0x0F}; //Truly random key. ;-)
SecretKey sk = new SecretKeySpec(bkey,"AES");
//Encryption with MAC
@@ -76,7 +76,6 @@ public void testMacBypass() throws EncryptionException, NoSuchFieldException, Il
String origCipherXform =
ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/NoPadding");
CipherText ct = ESAPI.encryptor().encrypt(sk,new PlainText(originalMessage));
- ct.computeAndStoreMAC(sk);
//Serialize the ciphertext in order to send it over the wire..
byte[] serializedCt = ct.asPortableSerializedByteArray();
From 4d37568b0b6aa0ad86f8faf63b6083c51741d587 Mon Sep 17 00:00:00 2001
From: "chris.schmidt@owasp.org"
Date: Tue, 3 Sep 2013 01:16:41 +0000
Subject: [PATCH 026/812] [maven-release-plugin] prepare release esapi-2.1.0
---
pom.xml | 1008 +++++++++++++++++++++++++++----------------------------
1 file changed, 504 insertions(+), 504 deletions(-)
diff --git a/pom.xml b/pom.xml
index 39ec222cc..e6ce7652e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,504 +1,504 @@
-
-
- 4.0.0
- org.owasp.esapi
- esapi
- 2.1.0-SNAPSHOT
- jar
-
-
- org.sonatype.oss
- oss-parent
- 5
-
-
-
-
- BSD
- http://www.opensource.org/licenses/bsd-license.php
- Code License - New BSD License
-
-
- Creative Commons 3.0 BY-SA
- http://creativecommons.org/licenses/by-sa/3.0/
- Content License - Create Commons 3.0 BY-SA
-
-
-
- ESAPI
- http://www.esapi.org/
- The Enterprise Security API (ESAPI) project is an OWASP project
- to create simple strong security controls for every web platform.
- Security controls are not simple to build. You can read about the
- hundreds of pitfalls for unwary developers on the OWASP web site. By
- providing developers with a set of strong controls, we aim to
- eliminate some of the complexity of creating secure web applications.
- This can result in significant cost savings across the SDLC.
-
-
-
- The Open Web Application Security Project (OWASP)
- http://www.owasp.org/index.php
-
-
-
-
- ESAPI-Users
- https://lists.owasp.org/mailman/listinfo/esapi-user/
- https://lists.owasp.org/mailman/listinfo/esapi-user/
- mailto:esapi-users@lists.owasp.org
- https://lists.owasp.org/pipermail/esapi-users/
-
-
-
- ESAPI-Developers
- https://lists.owasp.org/mailman/listinfo/esapi-dev/
- https://lists.owasp.org/mailman/listinfo/esapi-dev/
- mailto:esapi-dev@lists.owasp.org
- https://lists.owasp.org/pipermail/esapi-dev/
-
-
-
- OWASP-ESAPI (Inactive! Archive only!)
- https://lists.owasp.org/pipermail/owasp-esapi/
-
-
-
-
-
- scm:svn:http://owasp-esapi-java.googlecode.com/svn/trunk
- scm:svn:https://owasp-esapi-java.googlecode.com/svn/trunk
- http://code.google.com/p/owasp-esapi-java/source/checkout
-
-
-
- Google Code Issue Tracking
- http://code.google.com/p/owasp-esapi-java/issues/list
-
-
-
-
- Jeff Williams
- Aspect Security
-
- Project Owner
- Architect
- Developer
-
-
-
- Jim Manico
-
- Project Manager
- BuildMaster
- Developer
- Architect
-
-
-
- Chris Schmidt
- Aspect Security
-
- Project Manager
- Continuous Integration Admin
- Architect
- Developer
-
-
-
- Kevin W. Wall
- Wells Fargo
-
- Project Manager
- Architect
- Developer
- Crypto Guy
-
-
-
-
-
-
- Dave Wichers
- Aspect Security
-
- Documentation and Examples
- Minor Code Contributions
- Project Guidance
-
-
-
-
-
- UTF-8
-
-
-
-
- commons-configuration
- commons-configuration
- 1.5
-
-
- commons-beanutils
- commons-beanutils-core
- 1.7.0
-
-
- junit
- junit
- 4.4
- test
-
-
- javax.servlet
- servlet-api
- 2.4
- provided
-
-
- javax.servlet
- jsp-api
- 2.0
- provided
-
-
- commons-fileupload
- commons-fileupload
- 1.2
- compile
-
-
-
- commons-io
- commons-io
- 1.3
- test
-
-
- commons-collections
- commons-collections
- 3.2
- compile
-
-
- log4j
- log4j
- 1.2.16
- compile
- jar
-
-
- xom
- xom
- 1.2.5
-
-
- org.beanshell
- bsh-core
- 2.0b4
-
-
- org.owasp.antisamy
- antisamy
- 1.4.3
-
-
-
-
-
-
- maven-compiler-plugin
- 2.3.2
-
- 1.5
- 1.5
- true
- true
- false
-
-
-
-
- org.apache.maven.plugins
- maven-eclipse-plugin
- 2.8
-
- true
-
-
-
-
- maven-jar-plugin
- 2.3.1
-
-
-
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.codehaus.mojo
- findbugs-maven-plugin
- 2.3.1
-
- true
- true
- true
- Low
- Max
- false
-
-
-
- org.codehaus.mojo
- cobertura-maven-plugin
- 2.4
-
-
- html
- xml
-
-
-
-
- org.codehaus.mojo
- jdepend-maven-plugin
- 2.0-beta-2
-
-
- maven-pmd-plugin
- 2.5
-
- 1.5
- utf-8
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.7
-
- false
- false
-
-
-
- net.sourceforge.maven-taglib
- maven-taglib-plugin
- 2.4
-
-
- org.apache.maven.plugins
- maven-changelog-plugin
- 2.2
-
- [Ii]ssue[# ]*(\d)+
- http://code.google.com/p/owasp-esapi-java/issues/detail?id=%ISSUE%
- date
-
- 2011-05-11 00:00:00
-
-
-
-
- org.codehaus.mojo
- versions-maven-plugin
- 1.2
-
-
-
- dependency-updates-report
- plugin-updates-report
- property-updates-report
-
-
-
-
-
-
-
-
-
-
- dist
-
-
-
-
- performRelease
- true
-
-
-
-
-
- sonatype-nexus-snapshots
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- sonatype-nexus-staging
- https://oss.sonatype.org/service/local/staging/deploy/maven2
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
-
-
- sign-artifacts
- deploy
-
- sign
-
-
- 9F460575
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 2.3.1
-
-
- package
-
- sign
-
-
-
-
- codesign.keystore
- owasp foundation, inc.'s godaddy.com, inc. id
- true
-
-
- true
- true
-
-
- true
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
-
-
- enforce-jdk-version
-
- enforce
-
-
-
-
- 1.5
-
- ESAPI 2.0 uses the JDK1.5 for it's baseline. Please make sure that your
- JAVA_HOME environment variable is pointed to a JDK1.5 distribution.
-
-
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 2.2
-
-
- src/main/assembly/dist.xml
-
-
-
-
- make-dist
- package
-
- single
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
- 2.1
-
- https://owasp-esapi-java.googlecode.com/svn/tags/releases/
-
-
-
-
-
-
-
-
+
+
+ 4.0.0
+ org.owasp.esapi
+ esapi
+ 2.1.0
+ jar
+
+
+ org.sonatype.oss
+ oss-parent
+ 5
+
+
+
+
+ BSD
+ http://www.opensource.org/licenses/bsd-license.php
+ Code License - New BSD License
+
+
+ Creative Commons 3.0 BY-SA
+ http://creativecommons.org/licenses/by-sa/3.0/
+ Content License - Create Commons 3.0 BY-SA
+
+
+
+ ESAPI
+ http://www.esapi.org/
+ The Enterprise Security API (ESAPI) project is an OWASP project
+ to create simple strong security controls for every web platform.
+ Security controls are not simple to build. You can read about the
+ hundreds of pitfalls for unwary developers on the OWASP web site. By
+ providing developers with a set of strong controls, we aim to
+ eliminate some of the complexity of creating secure web applications.
+ This can result in significant cost savings across the SDLC.
+
+
+
+ The Open Web Application Security Project (OWASP)
+ http://www.owasp.org/index.php
+
+
+
+
+ ESAPI-Users
+ https://lists.owasp.org/mailman/listinfo/esapi-user/
+ https://lists.owasp.org/mailman/listinfo/esapi-user/
+ mailto:esapi-users@lists.owasp.org
+ https://lists.owasp.org/pipermail/esapi-users/
+
+
+
+ ESAPI-Developers
+ https://lists.owasp.org/mailman/listinfo/esapi-dev/
+ https://lists.owasp.org/mailman/listinfo/esapi-dev/
+ mailto:esapi-dev@lists.owasp.org
+ https://lists.owasp.org/pipermail/esapi-dev/
+
+
+
+ OWASP-ESAPI (Inactive! Archive only!)
+ https://lists.owasp.org/pipermail/owasp-esapi/
+
+
+
+
+
+ scm:svn:http://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.1.0
+ scm:svn:https://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.1.0
+ http://code.google.com/p/owasp-esapi-java/source/checkout/tags/esapi-2.1.0
+
+
+
+ Google Code Issue Tracking
+ http://code.google.com/p/owasp-esapi-java/issues/list
+
+
+
+
+ Jeff Williams
+ Aspect Security
+
+ Project Owner
+ Architect
+ Developer
+
+
+
+ Jim Manico
+
+ Project Manager
+ BuildMaster
+ Developer
+ Architect
+
+
+
+ Chris Schmidt
+ Aspect Security
+
+ Project Manager
+ Continuous Integration Admin
+ Architect
+ Developer
+
+
+
+ Kevin W. Wall
+ Wells Fargo
+
+ Project Manager
+ Architect
+ Developer
+ Crypto Guy
+
+
+
+
+
+
+ Dave Wichers
+ Aspect Security
+
+ Documentation and Examples
+ Minor Code Contributions
+ Project Guidance
+
+
+
+
+
+ UTF-8
+
+
+
+
+ commons-configuration
+ commons-configuration
+ 1.5
+
+
+ commons-beanutils
+ commons-beanutils-core
+ 1.7.0
+
+
+ junit
+ junit
+ 4.4
+ test
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+ javax.servlet
+ jsp-api
+ 2.0
+ provided
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.2
+ compile
+
+
+
+ commons-io
+ commons-io
+ 1.3
+ test
+
+
+ commons-collections
+ commons-collections
+ 3.2
+ compile
+
+
+ log4j
+ log4j
+ 1.2.16
+ compile
+ jar
+
+
+ xom
+ xom
+ 1.2.5
+
+
+ org.beanshell
+ bsh-core
+ 2.0b4
+
+
+ org.owasp.antisamy
+ antisamy
+ 1.4.3
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.5
+ 1.5
+ true
+ true
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+ 2.8
+
+ true
+
+
+
+
+ maven-jar-plugin
+ 2.3.1
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ 2.3.1
+
+ true
+ true
+ true
+ Low
+ Max
+ false
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ 2.4
+
+
+ html
+ xml
+
+
+
+
+ org.codehaus.mojo
+ jdepend-maven-plugin
+ 2.0-beta-2
+
+
+ maven-pmd-plugin
+ 2.5
+
+ 1.5
+ utf-8
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.7
+
+ false
+ false
+
+
+
+ net.sourceforge.maven-taglib
+ maven-taglib-plugin
+ 2.4
+
+
+ org.apache.maven.plugins
+ maven-changelog-plugin
+ 2.2
+
+ [Ii]ssue[# ]*(\d)+
+ http://code.google.com/p/owasp-esapi-java/issues/detail?id=%ISSUE%
+ date
+
+ 2011-05-11 00:00:00
+
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 1.2
+
+
+
+ dependency-updates-report
+ plugin-updates-report
+ property-updates-report
+
+
+
+
+
+
+
+
+
+
+ dist
+
+
+
+
+ performRelease
+ true
+
+
+
+
+
+ sonatype-nexus-snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ sonatype-nexus-staging
+ https://oss.sonatype.org/service/local/staging/deploy/maven2
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+ sign-artifacts
+ deploy
+
+ sign
+
+
+ 9F460575
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.3.1
+
+
+ package
+
+ sign
+
+
+
+
+ codesign.keystore
+ owasp foundation, inc.'s godaddy.com, inc. id
+ true
+
+
+ true
+ true
+
+
+ true
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-jdk-version
+
+ enforce
+
+
+
+
+ 1.5
+
+ ESAPI 2.0 uses the JDK1.5 for it's baseline. Please make sure that your
+ JAVA_HOME environment variable is pointed to a JDK1.5 distribution.
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.2
+
+
+ src/main/assembly/dist.xml
+
+
+
+
+ make-dist
+ package
+
+ single
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 2.1
+
+ https://owasp-esapi-java.googlecode.com/svn/tags/releases/
+
+
+
+
+
+
+
+
From 95c8c1dd46060d36b40576e521f1fb8afa150d01 Mon Sep 17 00:00:00 2001
From: "chris.schmidt@owasp.org"
Date: Tue, 3 Sep 2013 01:16:50 +0000
Subject: [PATCH 027/812] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index e6ce7652e..5e0fdd4bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.owasp.esapiesapi
- 2.1.0
+ 2.1.1-SNAPSHOTjar
@@ -66,9 +66,9 @@
- scm:svn:http://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.1.0
- scm:svn:https://owasp-esapi-java.googlecode.com/svn/tags/esapi-2.1.0
- http://code.google.com/p/owasp-esapi-java/source/checkout/tags/esapi-2.1.0
+ scm:svn:http://owasp-esapi-java.googlecode.com/svn/trunk
+ scm:svn:https://owasp-esapi-java.googlecode.com/svn/trunk
+ http://code.google.com/p/owasp-esapi-java/source/checkout
From 204636f7ff3a71dad567f5abe1cc86d038de39ed Mon Sep 17 00:00:00 2001
From: "kevin.w.wall"
Date: Sun, 15 Sep 2013 19:52:51 +0000
Subject: [PATCH 028/812] ESAPI Security Advisory as posted to Full Disclosure
and Bugtraq mailing lists. Keywords: CVE-2013-5679, Google Issue # 306.
---
documentation/ESAPI-security-bulletin1.docx | Bin 0 -> 25167 bytes
documentation/ESAPI-security-bulletin1.pdf | Bin 0 -> 648851 bytes
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 documentation/ESAPI-security-bulletin1.docx
create mode 100644 documentation/ESAPI-security-bulletin1.pdf
diff --git a/documentation/ESAPI-security-bulletin1.docx b/documentation/ESAPI-security-bulletin1.docx
new file mode 100644
index 0000000000000000000000000000000000000000..9ab49c9bb04429a0448236f727e503faba0709e9
GIT binary patch
literal 25167
zcmeFYW3VW}^Cfs~+qU1eZQHhO+qSKDZQHhO+rImL|Jm7?*_jXfeYPXIq9VFFGrOu!
zp019Q@>0McC;(sp5C8xGgaCJhS3a?T0078f|4sl1AT1#~TW1qnXFX*PdlM%eI(Hju
zf