All posts by Pramod T P

escapeshellcmd

escapeshellcmd() escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands. This function should be used to make sure that any data coming from user input is escaped before this data is passed to the exec() or system() functions, or to the backtick operator.

Following characters are preceded by a backslash: &#;`|*?~<>^()[]{}$\, \x0A and \xFF. ‘ and ” are escaped only if they are not paired. In Windows, all these characters plus % and ! are replaced by a space instead.

<?php
 $command = './configure '.$_POST['configure_options'];
 $escaped_command = escapeshellcmd($command);
 system($escaped_command);
 ?>

allow_url_include

The PHP option allow_url_include normally allows a programmer to include() a remote file (as PHP code) using a URL rather than a local file path. For security reasons, this feature should be disabled. If a script claims to require this feature, you should look into alternative software, as the use of this feature indicates serious design flaws.

There are a number of reasons why URL includes should always be avoided:

It’s insecure – if your application can be tricked into including content from a URL outside itself (and there are a number of common ways this can happen), an attacker can force your application to start running code from their own web site.

It’s inefficient – if your PHP script includes content from a URL, then the web server must make HTTP requests to generate the page. This makes your page load much slower than necessary, especially if the site you’re loading content from is responding slowly.

It’s unreliable, for the same reasons – if the web server you are loading content from occasionally fails to respond, your web site also sometimes fails to load properly.

It’s usually unnecessary – in most cases, allow_url_include can be avoided either by including the content directly (if it is being loaded from a domain you host) or by loading and printing the content without evaluating it as PHP.

Remote Code Injection

Remote code injections attempt to run the attacker’s code on a server, often by exploiting the functionality of the include or require functions.

The eval(), exec(), system(), and shell_exec() functions are vulnerable to remote code injections.

Include / Require attacks occur when including and executing files (possible from remote servers and includes remote code execution)

Counter Measures

• Check data against a whitelist

• Remove paths using basename()

• Set allow_url_include = off in php.ini that helps somewhat but not sufficient, as some attack vectors remain open

Cross Site Request Forgeries

• A request generated from a user’s browser without the user’s knowledge

• Relies on web site trust of logged-in users

• An attack involves tricking a user into transmitting ‘bad’ html with a request, which then returns sensitive data to the attacker

• Executed via iframes, xmlhttprequest calls or embedded in tags such as <script>, <object>, <embed>, <img>, …

Example

<form name="myForm">
<input type="hidden" name="item_id" value="123" />
<input type="hidden" name="quantity" value="1" />
</form>
<script>document.forms['myForm'].submit();</script>

Counter Measures

• Use a unique form token in a hidden input field to verify the request

• Require re-login before sensitive operations (ex: financial)

Session Security

Counter Measures

• Regenerate the session id upon login, before authentication, using session_regenerate_id(true). passing boolean true removes the old session and is critical as a counter measure

• Also, regenerate session id prior to “critical” operations

• Use ssl encryption for the login, or assign a hidden key (not as good)

• Check that the ip address remains the same (although not always reliable)

• Use short session timeout

• Provide user logout

• Destroy an old and create a new session with: session_regenerate_id(true)

• Set php configuration directive session.use_only_cookies = 1

• Prevent javascript access to session cookie with php configuration directive session.cookie_httponly = 1

cgi.force_redirect

The configuration directive cgi.force_redirect prevents anyone from calling PHP directly with a URL like http://my.host/cgi-bin/php/secretdir/script.php. Instead, PHP will only parse in this mode if it has gone through a web server redirect rule. PHP older than 4.2.0 used –enable-force-cgi-redirect compile time option for this.

Usually the redirection in the Apache configuration is done with the following directives:

Action php-script /cgi-bin/php
AddHandler php-script .php

This option has only been tested with the Apache web server, and relies on Apache to set the non-standard CGI environment variable REDIRECT_STATUS on redirected requests. If your web server does not support any way of telling if the request is direct or redirected, you cannot use this option and you must use one of the other ways of running the CGI version.

session_regenerate_id

session_regenerate_id — Update the current session id with a newly generated one

session_regenerate_id() will replace the current session id with a new one, and keep the current session information.

When session.use_trans_sid is enabled, output must be started after session_regenerate_id() call. Otherwise, old session ID is used.

Example

<?php
 session_start();

if (isset($_SESSION['destroyed'])
 && $_SESSION['destroyed'] < time() - 300) {
 remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
 throw(new DestroyedSessionAccessException);
 }

$old_sessionid = session_id();
 $_SESSION['destroyed'] = time(); 
 session_regenerate_id();
 unset($_SESSION['destroyed']);
 $new_sessionid = session_id();
 echo "Old Session: $old_sessionid<br />";
 echo "New Session: $new_sessionid<br />";

print_r($_SESSION);
?>