Date post: | 16-Apr-2017 |
Category: |
Technology |
Upload: | aung-khant |
View: | 22,448 times |
Download: | 0 times |
PHP5 Built-in String Filter Functions
For Your Application Security
Byd0ubl3_h3lix
http://yehg.orgApril 2008
Agenda
• Why We Use?• Need to Know• Secure Practice• Validation Vs Sanization• PHP5 Built-in Filtering Functions
Why We Use?
• 100% injection attacks (XSS,SQL,XPATH,OS CMD ...etc) come from inputs where filtering is weak or none
• Be aware of inputs as well as outputs • You know Garbage In Garbage Out • For attackers, Garbage In Gold Out
Need to Know• A lot more issues in filtering such as
encoding issues• An attacker can send strings in different
charset formats• Causes your visitors’ browser auto-detect
and interpret the way the attacker wants• Reason: Application failed to convert this
string to its intended charset since first stored in database
Secure Practice
Always Convert Input/Output
to Intended Charset BeforeIntensive
Filtering/Sanitization
Validation Vs Sanization
• Validation means the string format is exactly what you want
• Validated String can't be assumed 'Secure'
• Can't know if validated string might have malicious characters meaningful for various back-end systems
• That's why, validated one needs to be sanitized!
PHP5 Built-inString FilterFunctions
htmlspecialchars • Description: Convert special characters
to HTML entities • Usage:
string htmlspecialchars ( string string [, int quote_style [, string charset]] )
Quote_StyleENT_COMPAT
Will convert double-quotes and leave single-quotes alone.
ENT_QUOTES Will convert both double and single
quotes.ENT_NOQUOTES Will leave both double and single quotes
unconverted.
Supported Charsets• ISO-8859-1 • ISO-8859-15 • UTF-8 • cp866 (ibm866, 866)• cp1251 (Windows-1251, win-1251, 1251)• cp1252 (Windows-1252, 1252)• KOI8-R (koi8-ru, koi8r)• BIG5 • GB2312 • BIG5-HKSCS • Shift_JIS • EUC-JP
Not Secure: htmlspecialchars($untrusted_input);
Relatively Secure: htmlspecialchars($untrusted_input,
ENT_QUOTES,"UTF-8");
Example
htmlentities• Description: Convert all applicable
characters to HTML entities • Usage:
string htmlentities ( string string [, int quote_style [, string charset]] )
ExampleNot Secure: htmlentities($untrusted_input);
Relatively Secure: htmlentities($untrusted_input,
ENT_QUOTES,"UTF-8");
htmlspecialchars vs htmlentities
• htmlentities() converts every char to html applicable chars while htmlspecialchars() converts only:
& => &" => "' => '< => < > => >
• Description: Strip HTML and PHP tags from a string
• Usage:
string strip_tags ( string str [, string allowable_tags] )
strip_tags
// Return Hello Admin!alert('0wned u');strip_tags("<b>Hello
Admin!</b><script>alert('0wned u');</script>");
// Return <b>Hello Admin!</b> Nicestrip_tags("<b>bold</b> <i>Nice</i>" , "<b>");
Example: Stripping HTML
// Return Hello Admin!
strip_tags("Hello Admin!<?php /*attacker's shellcode/backdoor script*/?>");
It's commonly embedded in images and some binary-like files
Example: Stripping PHP
escapeshellcmd• Description: Escape shell
metacharacters - #&;`|*?~<>^()[]{}$\, \x0A and \xFF
• Usage:
string escapeshellcmd ( string command )
$input = "solution & whoami &"escapeshellcmd("process $input");
// Process solution whoami// Escape &
Example
• Description: Escapes special characters in a string for use in a SQL statement ; First need to open database connection
• Usage:
string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] )
mysql_real_escape_string
mysql_escape_string • Description: Escapes a string for use in
a mysql_query ; First need to open database connection
• Usage:
string mysql_escape_string ( string unescaped_string )
is_* FunctionsTo Check whether a variable is desiredType:• is_array -- Whether a variable is an array • is_binary -- Whether a variable is a native
binary string • is_bool -- Whether a variable is a boolean • is_buffer -- Whether a variable is a native
unicode or binary string • is_callable -- Verify that the contents of a
variable can be called as a function • is_double -- Alias of is_float()
is_* Functions• is_float -- Whether a variable is a float • is_int -- Whether a variable is an integer • is_integer -- Alias of is_int() • is_long -- Alias of is_int() • is_null -- Whether a variable is NULL • is_numeric -- Whether a variable is a number or a
numeric string • is_object -- Whether a variable is an object • is_real -- Alias of is_float() • is_resource -- Whether a variable is a resource • is_scalar -- Whether a variable is a scalar • is_string -- Whether a variable is a string • is_unicode -- Whether a variable is a unicode string
Good Practice With is_*
For example:
$start = (isset($_GET['num']) && is_numeric($_GET['num']))?(int)$_GET['num']:die("Hacking Attempt!");
filter_* Functions• filter_has_var -- Checks if variable of specified type
exists • filter_id -- Returns the filter ID belonging to a named
filter • filter_input_array -- Gets multiple variables from outside
PHP and optionally filters them • filter_input -- Gets variable from outside PHP and
optionally filters it • filter_list -- Returns a list of all supported filters • filter_var_array -- Gets multiple variables and optionally
filters them • filter_var -- Filters a variable with a specified filter
Filterable Types• INPUT_POST (integer)
– POST variables. • INPUT_GET (integer)
– GET variables. • INPUT_COOKIE (integer)
– COOKIE variables. • INPUT_ENV (integer)
– ENV variables. • INPUT_SERVER (integer)
– SERVER variables. • INPUT_SESSION (integer)
– SESSION variables. (not implemented yet in Php5) • INPUT_REQUEST (integer)
– REQUEST variables. (not implemented yet in Php5)
Filter Options
• FILTER_FLAG_NONE (integer) – No flags.
• FILTER_REQUIRE_SCALAR (integer) – Flag used to require scalar as input
Scalar variables are those containing an integer, float, string or boolean. Types array, object and resource are not scalar.
Filter Options
• FILTER_REQUIRE_ARRAY (integer) – Require an array as input.
• FILTER_FORCE_ARRAY (integer) – Always returns an array.
• FILTER_NULL_ON_FAILURE (integer) – Use NULL instead of FALSE on failure.
Filter Options
• FILTER_VALIDATE_INT (integer) – ID of "int" filter.
• FILTER_VALIDATE_BOOLEAN (integer) – ID of "boolean" filter.
• FILTER_VALIDATE_FLOAT (integer) – ID of "float" filter.
Filter Options
• FILTER_VALIDATE_REGEXP (integer) – ID of "validate_regexp" filter.
• FILTER_VALIDATE_URL (integer) – ID of "validate_url" filter.
• FILTER_VALIDATE_EMAIL (integer) – ID of "validate_email" filter.
Filter Options
• FILTER_VALIDATE_IP (integer) – ID of "validate_ip" filter.
• FILTER_DEFAULT (integer) – ID of default ("string") filter.
• FILTER_UNSAFE_RAW (integer) – ID of "unsafe_raw" filter.
• FILTER_SANITIZE_STRING (integer) – ID of "string" filter.
Filter Options• FILTER_SANITIZE_STRIPPED (integer)
– ID of "stripped" filter. • FILTER_SANITIZE_ENCODED (integer)
– ID of "encoded" filter. • FILTER_SANITIZE_SPECIAL_CHARS
(integer) – ID of "special_chars" filter.
• FILTER_SANITIZE_EMAIL (integer) – ID of "email" filter.
Filter Options• FILTER_SANITIZE_URL (integer)
– ID of "url" filter. • FILTER_SANITIZE_NUMBER_INT (integer)
– ID of "number_int" filter. • FILTER_SANITIZE_NUMBER_FLOAT
(integer) – ID of "number_float" filter.
• FILTER_SANITIZE_MAGIC_QUOTES (integer) – ID of "magic_quotes" filter.
Filter Options• FILTER_CALLBACK (integer)
– ID of "callback" filter. • FILTER_FLAG_ALLOW_OCTAL (integer)
– Allow octal notation (0[0-7]+) in "int" filter. • FILTER_FLAG_ALLOW_HEX (integer)
– Allow hex notation (0x[0-9a-fA-F]+) in "int" filter.
• FILTER_FLAG_STRIP_LOW (integer) – Strip characters with ASCII value less than 32.
Filter Options• FILTER_FLAG_STRIP_HIGH (integer)
– Strip characters with ASCII value greater than 127.
• FILTER_FLAG_ENCODE_LOW (integer) – Encode characters with ASCII value less than
32. • FILTER_FLAG_ENCODE_HIGH (integer)
– Encode characters with ASCII value greater than 127.
• FILTER_FLAG_ENCODE_AMP (integer) – Encode &.
Filter Options• FILTER_FLAG_NO_ENCODE_QUOTES
(integer) – Don't encode ' and ".
• FILTER_FLAG_EMPTY_STRING_NULL (integer) – (No use for now.)
• FILTER_FLAG_ALLOW_FRACTION (integer) – Allow fractional part in "number_float" filter.
Filter Options• FILTER_FLAG_ALLOW_THOUSAND
(integer) – Allow thousand separator (,) in "number_float"
filter. • FILTER_FLAG_ALLOW_SCIENTIFIC
(integer) – Allow scientific notation (e, E) in "number_float"
filter. • FILTER_FLAG_SCHEME_REQUIRED
(integer) – Require scheme in "validate_url" filter.
Filter Options• FILTER_FLAG_HOST_REQUIRED
(integer) – Require host in "validate_url" filter.
• FILTER_FLAG_PATH_REQUIRED (integer) – Require path in "validate_url" filter.
• FILTER_FLAG_QUERY_REQUIRED (integer) – Require query in "validate_url" filter.
Filter Options• FILTER_FLAG_IPV4 (integer)
– Allow only IPv4 address in "validate_ip" filter. • FILTER_FLAG_IPV6 (integer)
– Allow only IPv6 address in "validate_ip" filter. • FILTER_FLAG_NO_RES_RANGE (integer)
– Deny reserved addresses in "validate_ip" filter. • FILTER_FLAG_NO_PRIV_RANGE (integer)
– Deny private addresses in "validate_ip" filter.
Filter Definitions
• ID: FILTER_VALIDATE_INT • Options: min_range, max_range • Flags:
FILTER_FLAG_ALLOW_OCTAL, FILTER_FLAG_ALLOW_HEX
• Description:Validates value as integer, optionally from the specified range.
Filter Definitions
• ID: FILTER_VALIDATE_BOOLEAN • Flags:
FILTER_NULL_ON_FAILURE • Description:
Returns TRUE for "1", "true", "on" and "yes", FALSE for "0", "false", "off", "no", and "", NULL otherwise.
Filter Definitions
• ID: FILTER_VALIDATE_FLOAT • Flags:
FILTER_FLAG_ALLOW_THOUSAND • Description:
Validates value as float.
Filter Definitions
• ID: FILTER_VALIDATE_REGEXP
• Options: regexp
• Description:
Validates value against regexp, a Perl-compatible regular expression.
Filter Definitions• ID: FILTER_VALIDATE_URL • Flags:
FILTER_FLAG_PATH_REQUIRED, FILTER_FLAG_QUERY_REQUIRED
• Description:Validates value as URL, optionally with required components.
Filter Definitions
• ID: FILTER_VALIDATE_EMAIL
• Description:
Validates value as e-mail.
Filter Definitions• ID: FILTER_VALIDATE_IP • Flags:
FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE
• Description:Validates value as IP address, optionally only IPv4 or IPv6 or not from private or reserved ranges.
Filter Definitions• ID: FILTER_SANITIZE_STRING • Flags:
FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP
• Description:Strip tags, optionally strip or encode special characters.
Filter Definitions
• ID: FILTER_SANITIZE_STRIPPED
• Alias of FILTER_SANITIZE_STRING.
Filter Definitions• ID: FILTER_SANITIZE_ENCODED
• Flags:FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH
• Description:URL-encode string, optionally strip or encode special characters.
Filter Definitions• ID: FILTER_SANITIZE_SPECIAL_CHARS • Flags:
FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_HIGH
• Description:HTML-escape '"<>& and characters with ASCII value less than 32, optionally strip or encode other special characters.
Filter Definitions• ID: FILTER_UNSAFE_RAW
• Flags:FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP
• Description:Do nothing, optionally strip or encode special characters.
Filter Definitions
• ID: FILTER_SANITIZE_EMAIL
• Description:
Remove all characters except letters, digits and !#$%&'*+-/=?^_`{|}~@.[].
Filter Definitions
• ID: FILTER_SANITIZE_URL
• Description:
Remove all characters except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
Filter Definitions
• ID: FILTER_SANITIZE_NUMBER_INT
• Description:
Remove all characters except digits and +-.
Filter Definitions• ID: FILTER_SANITIZE_NUMBER_FLOAT • Flags:
FILTER_FLAG_ALLOW_FRACTION, FILTER_FLAG_ALLOW_THOUSAND, FILTER_FLAG_ALLOW_SCIENTIFIC
• Description:Remove all characters except digits, +- and optionally .,eE.
Filter Definitions
• ID: FILTER_SANITIZE_MAGIC_QUOTES
• Description:Apply addslashes().
Filter Definitions
• ID: FILTER_CALLBACK
• Options:callback function or method
• Description:Call user-defined function to filter data.
Remind: filter_* Functions• filter_has_var -- Checks if variable of specified type
exists • filter_id -- Returns the filter ID belonging to a named
filter • filter_input_array -- Gets multiple variables from outside
PHP and optionally filters them • filter_input -- Gets variable from outside PHP and
optionally filters it • filter_list -- Returns a list of all supported filters • filter_var_array -- Gets multiple variables and optionally
filters them • filter_var -- Filters a variable with a specified filter
• Description: Checks if variable of specified type exists
• Usage:
bool filter_has_var ( int type, string variable_name )
filter_has_var
Example
filter_has_var(INPUT_GET,'searchstr');
is equivalent to
isset($_GET['searchstr'])
• Description: Returns the filter ID belonging to a named filter
• Usage:
int filter_id ( string filtername )
filter_id
• Description: Returns a list of all supported filters
• Usage:
array filter_list ( void )
filter_list
• Description: Gets variable from outside PHP and optionally filters it
• Usage:
mixed filter_input ( int type, string variable_name [, int filter [, mixed options]] )
filter_input
filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
filter_input (INPUT_GET, 'number',FILTER_VALIDATE_INT,array(
'flags' => FILTER_FLAG_ARRAY, 'options' => array('min_range' => 1,
'max_range' => 10) )
);
Example
• Description: Gets multiple variables from outside PHP and optionally filters them
• Usage:
mixed filter_input_array ( int type [, mixed definition] )
filter_input_array
/* Let's say: data come from POST as follows:*/
$_POST = array( 'visitor_name' => 'MgMg', 'visitor_email' => '[email protected]', 'visitor_url' => 'http://myanmar.com');
Example
We can write filter rules like:
$visitor_sanitized_rules = array( 'visitor_name' => FILTER_SANITIZE__SPECIAL_CHARS,
'visitor_email' => FILTER_VALIDATE_EMAIL,'visitor_url' => FILTER_VALIDATE_URL);
Example
Then, we can implement like:
$visitor_inputs = filter_input_array(INPUT_POST, $visitor_sanitized_rules);
Example
No Real Difference!
filter_input(_array) Vs filter_var(_array)
are totally same.
• Description: Filters a variable with a specified filter
• Usage:
mixed filter_var ( mixed variable [, int filter [, mixed options]] )
filter_var
filter_var($_POST['visitor_name'], FILTER_SANITIZE_SPECIAL_CHARS);
filter_var($_POST['visitor_email'], FILTER_VALIDATE_EMAIL);
filter_var($_POST['visitor_url'], FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED);
Example
• Description: Gets multiple variables and optionally filters them
• Usage:
mixed filter_var_array ( array data [, mixed definition] )
filter_var_array
/* Same as before. No big difference:*/
$visitor_data = array( 'visitor_name' => 'MgMg', 'visitor_email' => '[email protected]', 'visitor_url' => 'http://myanmar.com');
Example
We can write filter rules like:
$visitor_sanitized_rules = array( 'visitor_name' => FILTER_SANITIZE__SPECIAL_CHARS,
'visitor_email' => FILTER_VALIDATE_EMAIL,'visitor_url' => FILTER_VALIDATE_URL);
Example
Then, we can implement like:
$visitor_inputs = filter_input_array($visitor_data,
$visitor_sanitized_rules);
Example
Last But Not Least,
Did you notice two things lack in Filter_* Functions ?
First ..
Have to filter twice for some cases like:
$email = $_GET['email'];$email =filter_var($email,FILTER_VALIDATE_EMAIL);$email =filter_var($email,FILTER_SANITIZE_EMAIL);
Second …
No Charset ConversionFunctions!
Do-It-Yourself Exercise!
Thank You!
Reference
• PHP 5.25 Manual