PROWAREtech
PHP: Tips and Tricks - Page 6
Web Development
Sessions
Prevent Hijacking of Another User's Session
Pass session IDs in cookies only. Generate an additional session token to be passed by URI. If users do not allow cookies then session hijacking can not be prevented because the session id is sent through urls and hidden input elements on forms.
output_add_rewrite_var
will add the token to every link and form.
<?php
if(!ini_get('session.use_only_cookies')) {
// set sessions to use cookies only
ini_set('session.use_only_cookies', true);
}
session_start();
$secret = 'k38n47fb47widfb7538idj';
$string = strval(date('z')).$secret; // 'z' will expire at midnight
$token = md5($string);
if(!isset($_REQUEST['token']) || $_REQUEST['token'] != $token) {
// display login form
print 'login form here';
exit;
} else {
$_SESSION['token'] = $token;
output_add_rewrite_var('token', $token);
print '<a href="'.$_SERVER['SCRIPT_NAME'].'">link #1</a>';
}
?>
<a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>">link #2</a>
Prevent Session Fixation Attacks
Assign a new session id to prevent this.
<?php
if(!ini_get('session.use_only_cookies')) {
// set sessions to use cookies only
ini_set('session.use_only_cookies', true);
}
session_start();
if(!isset($_SESSION['last_regenerated']) || $_SESSION['last_regenerated']< (time() - 30)) {
session_regenerate_id();
$_SESSION['last_regenerated'] = time();
}
?>
Session Tracking
Track users as they navigate the website. If the user does not accept cookies then add this line of code:
ini_set('session.use_trans_sid', true);
The problem with session.use_trans_sid
is that users can see the session id.
<?php
if(!ini_get('session.auto_start')) {
// set sessions to automatically start
ini_set('session.auto_start', true);
session_start();
}
if(!isset($_SESSION['visit_count'])) {
$_SESSION['visit_count'] = 0;
}
$_SESSION['visit_count']++;
print $_SESSION['visit_count'].' visits';
?>
Manipulating HTML
Extracting Links from HTML
Extract links from an HTML file using a custom function. This function simply extracts the link's href value which will include relative paths.
<?php
$html = '
<html>
<head><title></title></head>
<body>
<a href="../../phpinfo.php"><img src="php.jpg" />PHP Info</a>
<p>PHP is a scripting language.</p>
<a href="http://www.prowaretech.com">Actors read from scripts</a>
<php>PHP is the real deal when it comes to scripting languages.</php>
</body>
</html>';
$links = link_extractor($html);
foreach($links as $link) {
print $link[0].'<br />';
}
function link_extractor($html) {
$links = array();
preg_match_all('/<a\s+.*?href=[\"\']?([^\"\' >]*)[\"\']?[^>]*>(.*?)<\/a>/i', $html, $matches, PREG_SET_ORDER);
foreach($matches as $match) {
$links[] = array($match[1], $match[2]);
}
return $links;
}
?>
Repairing Nonstandard HTML
Correct malformed HTML using tidy_repair_string
(or tidy_repair_file
).
<?php
$html = '
<html>
<head><title></head>
<body>
<a href="phpinfo.php"><img src="php.jpg" />PHP Info</a>
<p>PHP is a <em>scripting language.</p></em>
Actors read from scripts
<php>PHP is the real deal when it comes to scripting languages.</php>
';
$corrected = tidy_repair_string($html);
print $corrected;
?>
Highlighting Keywords in an HTML Document
A website with a custom search function will want to highlight the search words within each HTML document.
<?php
$html = '
<html>
<head><title></title></head>
<body>
<a href="phpinfo.php"><img src="php.jpg" />PHP Info</a>
<p>PHP is a scripting language.</p>
Actors read from scripts
<php>PHP is the real deal when it comes to scripting languages.</php>
</body>
</html>';
// wrap each search word with mark tags
$search_words = array('php','script');
$replacements = array();
foreach($search_words as $index => $search_word) {
$patterns[] = '/'.preg_quote($search_word).'/i';
$replacements[] = "<mark>\\0</mark>";
}
// split the page into chunks delimited by HTML elements
$html_parts = preg_split("{(<(?:\"[^\"]*\"|'[^']*'|[^'\">])*>)}", $html, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach($html_parts as $index => $html_part) {
// skip if HTML element
if(isset($html_part[0]) && ($html_part[0] == '<')) {
continue;
}
$html_parts[$index] = preg_replace($patterns, $replacements, $html_part);
}
$html = implode('', $html_parts);
print $html;
?>
Convert Plain Text into HTML
<?php
$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas imperdiet purus, sit amet aliquet sapien gravida quis.
Curabitur sed velit eu est HTTP://www.finibus.com malesuada et eu nisl. Curabitur vel sapien et massa suscipit rhoncus.';
print text2html($text);
function text2html($text) {
$text = htmlentities($text);
$grafs = split("\r\n\r\n", $text);
for($i = 0, $j = count($grafs); $i < $j; $i++) {
// http or ftp urls
$grafs[$i] = preg_replace('/((ht|f)tp:\/\/[^\s&]+)/i', '<a href="$1">$1</a>', $grafs[$i]);
$grafs[$i] = '<p>'.$grafs[$i].'</p>';
}
return implode("\r\n", $grafs);
}
?>
Connecting to Websites
file_get_contents
can retrieve documents on the Internet as simply as it does local files. Also, it follows redirects which
greatly simplifies the usage.
Use this page for testing these practices.
<!-- print.php -->
<?php
print "<pre>COOKIES\r\n";
print_r($_COOKIE);
print "REQUEST\r\n";
print_r($_REQUEST);
print '</pre>';
?>
HTTP "GET" a URI
For a GET request, just specify the URI as the file in file_get_contents
. Optionally, build a query string to include.
<?php
$query = array('search' => 'brown & cow', 'option' => 'two');
$query_string = http_build_query($query);
$page_data = file_get_contents('http://localhost/print.php?'.$query_string);
print $page_data;
?>
To specify that file_get_contents
not follow redirects, specify an additional parameter.
<?php
$options = array('max_redirects' => 0);
$stream_context = stream_context_create(array('http' => $options));
$page_data = file_get_contents('http://localhost/print.php', false, $stream_context);
print $page_data;
?>
To specify a user and password just add it to the URI.
<?php
$secure_page_data = file_get_contents('http://username:password@localhost/print.php');
print $secure_page_data;
?>
HTTP "POST" to a URI
For a POST request, file_get_contents
still works great.
<?php
$query = array('firstname' => 'brown & cow', 'lastname' => 'to whom it matters');
$request_body = http_build_query($query);
$options = array('method' => 'POST', 'content' => $request_body, 'header' => 'Content-type: application/x-www-form-urlencoded');
$stream_context = stream_context_create(array('http' => $options));
$page_data = file_get_contents('http://localhost/print.php', false, $stream_context);
print $page_data;
?>
HTTP GET with Cookies
The key here is to include the Cookie
header.
<?php
$options = array('method' => 'GET', 'header' => "Cookie: username=mrsmith");
$stream_context = stream_context_create(array('http' => $options));
$page_data = file_get_contents('http://localhost/print.php', false, $stream_context);
print $page_data;
?>
HTTP POST with Cookies
Like the GET request, include a Cookie
header.
<?php
$query = array('firstname' => 'brown & cow', 'lastname' => 'to whom it matters');
$request_body = http_build_query($query);
$options = array('method' => 'POST', 'content' => $request_body, 'header' => "Cookie: username=mrsmith\r\nContent-type: application/x-www-form-urlencoded");
$stream_context = stream_context_create(array('http' => $options));
$page_data = file_get_contents('http://localhost/print.php', false, $stream_context);
print $page_data;
?>