VYPR
Moderate severityNVD Advisory· Published Sep 30, 2013· Updated Apr 29, 2026

CVE-2013-5960

CVE-2013-5960

Description

The authenticated-encryption feature in the symmetric-encryption implementation in the OWASP Enterprise Security API (ESAPI) for Java 2.x before 2.1.0.1 does not properly resist tampering with serialized ciphertext, which makes it easier for remote attackers to bypass intended cryptographic protection mechanisms via an attack against the intended cipher mode in a non-default configuration, a different vulnerability than CVE-2013-5679.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.owasp.esapi:esapiMaven
>= 2.0.0.0, < 2.1.0.12.1.0.1

Affected products

1

Patches

1
b7cbc53f9cc9

Close #306. Close #359

2 files changed · +149 1
  • src/main/java/org/owasp/esapi/codecs/PercentCodec.java+11 1 modified
    @@ -89,7 +89,12 @@ private static StringBuilder appendTwoUpperHex(StringBuilder sb, int b)
     
     	/**
     	 * Encode a character for URLs
    -	 * @param immune characters not to encode
    +	 * @param immune Additional characters not to encode. Note this could
    +     *               break URL encoding as referenced in RFC 3986. You should
    +     *               especially be wary of including '%' in this list of immune
    +     *               characters since it is used as the "escape" character for
    +     *               the hex encoding and including it may result in subsequent
    +     *               and/or dangerous results when decoding.
     	 * @param c character to encode
     	 * @return the encoded string representing c
     	 */
    @@ -99,6 +104,11 @@ public String encodeCharacter( char[] immune, Character c )
     		byte[] bytes;
     		StringBuilder sb;
     
    +        // check for user specified immune characters
    +        if ( immune != null && containsCharacter( c.charValue(), immune ) )
    +            return cStr;
    +
    +        // check for standard characters (e.g., alphanumeric, etc.)
     		if(UNENCODED_SET.contains(c))
     			return cStr;
     
    
  • src/test/java/org/owasp/esapi/codecs/CodecImmunityTest.java+138 0 added
    @@ -0,0 +1,138 @@
    +package org.owasp.esapi.codecs;
    +
    +import java.util.ArrayList;
    +import java.util.Arrays;
    +import java.util.Collection;
    +import java.util.List;
    +
    +import org.junit.Assert;
    +import org.junit.Test;
    +import org.junit.runner.RunWith;
    +import org.junit.runners.Parameterized;
    +import org.junit.runners.Parameterized.Parameters;
    +import org.owasp.esapi.EncoderConstants;
    +import org.owasp.esapi.StringUtilities;
    +import org.owasp.esapi.codecs.*;
    +
    +/**
    + * Parameterized test to verify that the Immunity parameter for a codec
    + * encode/decode event works as expected on a series of special characters.
    + *  
    + * @author jeremiah.j.stacey@gmail.com
    + * @since 2.1.0.1
    + *
    + */
    +@RunWith(Parameterized.class)
    +public class CodecImmunityTest {
    +    /** character arrays used as immunity lists from Default Encoder.*/
    +    private final static char[] IMMUNE_HTML = { ',', '.', '-', '_', ' ' };
    +    private final static char[] IMMUNE_HTMLATTR = { ',', '.', '-', '_' };
    +    private final static char[] IMMUNE_CSS = {};
    +    private final static char[] IMMUNE_JAVASCRIPT = { ',', '.', '_' };
    +    private final static char[] IMMUNE_VBSCRIPT = { ',', '.', '_' };
    +    private final static char[] IMMUNE_XML = { ',', '.', '-', '_', ' ' };
    +    private final static char[] IMMUNE_SQL = { ' ' };
    +    private final static char[] IMMUNE_OS = { '-' };
    +    private final static char[] IMMUNE_XMLATTR = { ',', '.', '-', '_' };
    +    private final static char[] IMMUNE_XPATH = { ',', '.', '-', '_', ' ' };
    +    private final static char[] IMMUNE_PERCENT = { '%' };
    +    // These are inline in the encode methods, but same principle.
    +    // private final static char[] IMMUNE_LDAP = { '\\', '*', '(', ')', '\0' };
    +    // private final static char[] IMMUNE_DN = { '\\', ',', '+', '"', '<', '>', ';' };
    +
    +
    +    @Parameters(name = "{0}")
    +    public static Collection<Object[]> getParams() {
    +        Collection<Codec> knownCodecs = new ArrayList<Codec>();
    +        knownCodecs.add(new CSSCodec());
    +        knownCodecs.add(new DB2Codec());
    +        knownCodecs.add(new HTMLEntityCodec());
    +        knownCodecs.add(new JavaScriptCodec());
    +        knownCodecs.add(new MySQLCodec(0)); //Standard
    +        knownCodecs.add(new MySQLCodec(1)); //ANSI
    +        knownCodecs.add(new OracleCodec());
    +        knownCodecs.add(new PercentCodec());
    +        knownCodecs.add(new UnixCodec());
    +        knownCodecs.add(new VBScriptCodec());
    +        knownCodecs.add(new WindowsCodec());
    +        knownCodecs.add(new XMLEntityCodec());
    +
    +        // TODO:  Add more strings here!!
    +        List<String> sampleStrings = Arrays.asList("%De");
    +
    +        Collection<Object[]> params = new ArrayList<Object[]>();
    +        for (Codec codec : knownCodecs) {
    +            for (String sample : sampleStrings) {
    +                params.add(new Object[]{codec.getClass().getSimpleName() + " " + sample, codec, sample});
    +            }
    +        }
    +
    +        // Add Tests for codecs against the configured ImmunityLists within the Default Encoder.
    +        params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_HTML, "IMMUNE_HTML"));
    +        params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_XPATH, "IMMUNE_XPATH"));
    +        params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_HTMLATTR, "IMMUNE_HTMLATTR"));
    +        params.addAll(buildImmunitiyValidation(new CSSCodec(), IMMUNE_CSS, "IMMUNE_CSS"));
    +        //params.addAll(buildImmunitiyValidation(new DB2Codec(), IMMUNE_HTML, ""));
    +        params.addAll(buildImmunitiyValidation(new JavaScriptCodec(), IMMUNE_JAVASCRIPT, "IMMUNE_JAVASCRIPT"));
    +        params.addAll(buildImmunitiyValidation(new MySQLCodec(0), IMMUNE_SQL, "IMMUNE_SQL"));
    +        params.addAll(buildImmunitiyValidation(new MySQLCodec(1), IMMUNE_SQL, "IMMUNE_SQL"));
    +        params.addAll(buildImmunitiyValidation(new OracleCodec(), IMMUNE_HTML, "IMMUNE_HTML"));
    +            // No standard Immunity char array defined for PercentEncoder, but for
    +            // GitHub issues #306 and $350, we use '%'.
    +        params.addAll(buildImmunitiyValidation(new PercentCodec(), IMMUNE_PERCENT, "IMMUNE_PERCENT"));
    +        params.addAll(buildImmunitiyValidation(new UnixCodec(), IMMUNE_OS, "IMMUNE_OS"));
    +        params.addAll(buildImmunitiyValidation(new VBScriptCodec(), IMMUNE_VBSCRIPT, "IMMUNE_VBSCRIPT"));
    +        params.addAll(buildImmunitiyValidation(new WindowsCodec(), IMMUNE_OS, "IMMUNE_OS"));
    +        params.addAll(buildImmunitiyValidation(new XMLEntityCodec(), IMMUNE_XML, "IMMUNE_XML"));
    +        params.addAll(buildImmunitiyValidation(new XMLEntityCodec(), IMMUNE_XMLATTR, "IMMUNE_XMLATTR"));
    +
    +        params.addAll(fullCharacterCodecValidation(knownCodecs));
    +
    +        return params;
    +    }
    +
    +    private static Collection<Object[]> buildImmunitiyValidation(Codec codec, char[] immunities, String descriptor) {
    +        Collection<Object[]> params = new ArrayList<Object[]>();
    +        for (char c : immunities) {
    +            params.add(new Object[]{codec.getClass().getSimpleName() + " " + descriptor + " ("+ c + ")", codec, String.valueOf(c)});
    +        }
    +        return params;
    +    }
    +
    +    private static Collection<Object[]> fullCharacterCodecValidation(Collection<Codec> codecs) {
    +        char[] holyCowTesting = StringUtilities.union(EncoderConstants.CHAR_ALPHANUMERICS, EncoderConstants.CHAR_SPECIALS); 
    +        Collection<Object[]> params = new ArrayList<Object[]>();
    +        for (Codec codec: codecs) {
    +            params.addAll(buildImmunitiyValidation(codec, holyCowTesting, "Full_ALPHA_AND_SPECIALS"));
    +        }
    +
    +        return params;
    +    }
    +
    +    private final Codec codec;
    +    private final String string;
    +    private final char[] immunityList;
    +
    +    public CodecImmunityTest(String ignored, Codec codec, String toTest) {
    +        this.codec = codec;
    +        this.string = toTest;
    +        /**
    +         * The Immunity character array is every character in the String we're testing.
    +         * 
    +         */
    +        this.immunityList = toTest.toCharArray();
    +    }
    +
    +    @Test
    +    public void testImmuneEncode() {
    +        String encoded = codec.encode(immunityList, string);
    +        Assert.assertEquals(string, encoded);
    +    }
    +    /*
    +    @Test
    +    public void testImmuneDecode() {
    +        String decoded = codec.decode(string);
    +        Assert.assertEquals(string, decoded);
    +    }
    +*/
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.