All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.owasp.esapi.codecs.MySQLCodec Maven / Gradle / Ivy

Go to download

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 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.

There is a newer version: 2.5.5.0
Show newest version
/**
 * OWASP Enterprise Security API (ESAPI)
 * 
 * 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) 2007 - The OWASP Foundation
 * 
 * The ESAPI is published by OWASP under the BSD license. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 * 
 * @author Jeff Williams Aspect Security
 * @created 2007
 */
package org.owasp.esapi.codecs;



/**
 * Codec implementation which can be used to escape string literals in MySQL.
 * 
* Implementation accepts 2 Modes as identified by the OWASP Recommended * escaping strategies: *
    *
  • ANSI
    * Simply encode all ' (single tick) characters with '' (two single ticks)
  • *
    *
  • Standard * *
     *   NUL (0x00) --> \0  [This is a zero, not the letter O]
     *   BS  (0x08) --> \b
     *   TAB (0x09) --> \t
     *   LF  (0x0a) --> \n
     *   CR  (0x0d) --> \r
     *   SUB (0x1a) --> \Z
     *   "   (0x22) --> \"
     *   %   (0x25) --> \%
     *   '   (0x27) --> \'
     *   \   (0x5c) --> \\
     *   _   (0x5f) --> \_ 
     *   
    * all other non-alphanumeric characters with ASCII values less than 256 --> \c * where 'c' is the original non-alphanumeric character. *
    * *
  • * *
* * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) * Aspect Security * @since June 1, 2007 * * MySQL 8.0 String Literals * OWASP * SQL_Injection_Prevention_Cheat_Sheet#MySQL_Escaping */ public class MySQLCodec extends AbstractCharacterCodec { /** * Specifies the SQL Mode the target MySQL Server is running with. For details about MySQL Server Modes * please see the Manual at * @link http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_ansi * * Currently the only supported modes are: * ANSI * STANDARD */ public static enum Mode { ANSI(1),STANDARD(0); private int key; private Mode(int key) { this.key = key; } static Mode findByKey(int key) { for ( Mode m : values() ) { if ( m.key == key ) return m; } String message = String.format("No Mode for %s. Valid references are MySQLStandard: %s or ANSI: %s", key, MYSQL_MODE, ANSI_MODE); throw new IllegalArgumentException(message); } } /** Target MySQL Server is running in Standard MySQL (Default) mode. */ public static final int MYSQL_MODE = 0; /** * Target MySQL Server is running in ANSI_QUOTES Mode * * @see * https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_ansi_quotes */ public static final int ANSI_MODE = 1; //private int mode = 0; private Mode mode; /** * Instantiate the MySQL codec * * @param mode * Mode has to be one of {MYSQL_MODE|ANSI_MODE} to allow correct encoding * @deprecated * @see #MySQLCodec(org.owasp.esapi.codecs.MySQLCodec.Mode) */ @Deprecated public MySQLCodec( int mode ) { this.mode = Mode.findByKey(mode); } /** * Instantiate the MySQL Codec with the given SQL {@link Mode}. * @param mode The mode the target server is running in */ public MySQLCodec( Mode mode ) { this.mode = mode; } /** * {@inheritDoc} */ public String encodeCharacter( char[] immune, Character c ) { char ch = c.charValue(); // check for immune characters if ( containsCharacter( ch, immune ) ) { return ""+ch; } // check for alphanumeric characters String hex = super.getHexForNonAlphanumeric( ch ); if ( hex == null ) { return ""+ch; } switch( mode ) { case ANSI: return encodeCharacterANSI( c ); case STANDARD: return encodeCharacterMySQL( c ); default: return null; } } /** * encodeCharacterANSI encodes for ANSI SQL. * * Apostrophe is encoded * * Bug ###: In ANSI Mode Strings can also be passed in using the quotation. In ANSI_QUOTES mode a quotation * is considered to be an identifier, thus cannot be used at all in a value and will be dropped completely. * * @param c * character to encode * @return * String encoded to standards of MySQL running in ANSI mode */ private String encodeCharacterANSI( Character c ) { if ( c == '\'' ) return "\'\'"; return ""+c; } /** * Encode a character suitable for MySQL * * @param c * Character to encode * @return * Encoded Character */ private String encodeCharacterMySQL( Character c ) { char ch = c.charValue(); if ( ch == 0x00 ) return "\\0"; if ( ch == 0x08 ) return "\\b"; if ( ch == 0x09 ) return "\\t"; if ( ch == 0x0a ) return "\\n"; if ( ch == 0x0d ) return "\\r"; if ( ch == 0x1a ) return "\\Z"; if ( ch == 0x22 ) return "\\\""; if ( ch == 0x25 ) return "\\%"; if ( ch == 0x27 ) return "\\'"; if ( ch == 0x5c ) return "\\\\"; if ( ch == 0x5f ) return "\\_"; return "\\" + c; } /** * {@inheritDoc} * * Returns the decoded version of the character starting at index, or * null if no decoding is possible. * * Formats all are legal (case sensitive) * In ANSI_MODE '' decodes to ' * In MYSQL_MODE \x decodes to x (or a small list of specials) */ public Character decodeCharacter( PushbackSequence input ) { switch( mode ) { case ANSI: return decodeCharacterANSI( input ); case STANDARD: return decodeCharacterMySQL( input ); default: return null; } } /** * decodeCharacterANSI decodes the next character from ANSI SQL escaping * * @param input * A PushBackString containing characters you'd like decoded * @return * A single character, decoded */ private Character decodeCharacterANSI( PushbackSequence input ) { input.mark(); Character first = input.next(); if ( first == null ) { input.reset(); return null; } // if this is not an encoded character, return null if ( first.charValue() != '\'' ) { input.reset(); return null; } Character second = input.next(); if ( second == null ) { input.reset(); return null; } // if this is not an encoded character, return null if ( second.charValue() != '\'' ) { input.reset(); return null; } return( Character.valueOf( '\'' ) ); } /** * decodeCharacterMySQL decodes all the potential escaped characters that MySQL is prepared to escape * * @param input * A string you'd like to be decoded * @return * A single character from that string, decoded. */ private Character decodeCharacterMySQL( PushbackSequence input ) { input.mark(); Character first = input.next(); if ( first == null ) { input.reset(); return null; } // if this is not an encoded character, return null if ( first.charValue() != '\\' ) { input.reset(); return null; } Character second = input.next(); if ( second == null ) { input.reset(); return null; } if ( second.charValue() == '0' ) { return Character.valueOf( (char)0x00 ); } else if ( second.charValue() == 'b' ) { return Character.valueOf( (char)0x08 ); } else if ( second.charValue() == 't' ) { return Character.valueOf( (char)0x09 ); } else if ( second.charValue() == 'n' ) { return Character.valueOf( (char)0x0a ); } else if ( second.charValue() == 'r' ) { return Character.valueOf( (char)0x0d ); } else if ( second.charValue() == 'Z' ) { return Character.valueOf( (char)0x1a ); } else if ( second.charValue() == '\"' ) { return Character.valueOf( (char)0x22 ); } else if ( second.charValue() == '%' ) { return Character.valueOf( (char)0x25 ); } else if ( second.charValue() == '\'' ) { return Character.valueOf( (char)0x27 ); } else if ( second.charValue() == '\\' ) { return Character.valueOf( (char)0x5c ); } else if ( second.charValue() == '_' ) { return Character.valueOf( (char)0x5f ); } else { return second; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy