Your SlideShare is downloading. ×
0
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Creating "Secure" PHP Applications, Part 1, Explicit Code & QA

2,068

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,068
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Explicit Code & QA
  • 2. So, who are you, anyway? Bryan C. Geraghty Security Consultant at Security PS @archwisp I’m a Sr. PHP developer with a systems and security engineering background - turned application security consultant
  • 3. Remember, layersSimpler is easier to testDon’t make assumptionsCompromised browser = game over
  • 4. These are not specifically security activities but they produce morestable code
  • 5. Don’t rely on the server’s configuration Your bootstrap should Absolute Minimum set the defaults for any  Include paths PHP core functionality  Error reporting that your application is  Time zones using. These must be customizable for every environment e.g. (dev, staging, live)
  • 6. Example Bootstrap<?php// All environment configuration for this application is done from this fileini_set(display_errors, 0);ini_set(error_reporting, -1);date_default_timezone_set(UTC);$rootPath = dirname(__FILE__);set_include_path(sprintf( %s%s%s%s, $rootPath, PATH_SEPARATOR, $rootPath, /third-party));require_once(MindFrame2/AutoLoad.php);MindFrame2_AutoLoad::install();
  • 7. Don’t use global constants, variables, or registries You can’t be certain that nobody else will ever use the same global constant name Tracking down where a value is assigned to a global variable is usually very difficult Global variables remove control of that variable from the current scope Global registries are really just fancy global variables and the same problems apply
  • 8. Value Reference Rules Values should only be referenced in one of the following ways:  A direct reference in the current scope: $limit = $this->_objectPool->getConfig()- >getDefaultLimit();  A parameter: public function getUsers($limit) { return $this->_objectPool- >getMapper(‘User’)->fetchAll($limit); }
  • 9. Don’t use function parameter defaults "There should be one-- and preferably only one -- obvious way to do it." - Tim Peters Reduces understanding from the caller perspective Often add unnecessary complexity Represents the most common use-case Other use-cases are often ignored entirely Changing the default breaks all implementations Adding parameters breaks default implementations
  • 10. Default parameter exampleclass User{ public function __construct($name, $email, $status = self::STATUS_ACTIVE) { $this->_name = $name; $this->_email = $email; $this->_status = $status; }}function createUser($name, $email, $status) { $user = new User($name, email); return $this->_objectPoool->getMapper(‘User’)->create($user);}
  • 11. Use explicit operators whenever possibleThis was actual production code.if ($sincedate && (int)$sincedate) { $param["UpdatedSinceDate"] = date("Y-m-d H:i:s", strtotime(time() - ((int)$sincedate)*60*60);} elseif ($sincedate && strtotime($sincedate)) { $param["UpdatedSinceDate"] = date("Y-m-d H:i:s", strtotime($sincedate));} elseif(!isset($param["UpdatedSinceDate"])) { exit ("Invalid param UpdatedSinceDate");}Do you think this code worked as the author intended when $sincedate was set to2011-05-31?
  • 12. Use constants for possible valuesConstants cannot be re-defined, so using a constant for configuration limits your codeto only ever be able to run in one configuration in a given stack.// Bad: This code cannot execute differently in the same stackdefine(‘PDO_FETCH_MODE’, 2);$dbi->fetchAll(PDO_FETCH_MODE);// Better: The value can change but this literal value means nothing without// referencing the documentation$dbi->fetchAll(2);// Best: Implemented using a meaningful constant which represents a *possible* value$dbi->fetchAll(PDO::FETCH_ASSOC);
  • 13. Use wrappers for super-globals $_REQUEST, $_GET, $_SESSION, and $_FILES are the most commonly used PHP super-globals but there are others It’s easy to create some serious security problems It’s best to use a wrapper for interacting with these variables
  • 14. Simulate strong/static typesPHP is dynamically typed, so we cannot do true strong or static typing but we canput controls in place which provide the same protection.private function _buildSelectDatabaseTableSql($database_name, $table_name, array $select_data, array $order_by_columns, $offset, $limit) { MindFrame2_Core::assertArgumentIsNotBlank($database_name, 1, database_name); MindFrame2_Core::assertArgumentIsNotBlank($table_name, 2, table_name); MindFrame2_Core::assertArgumentIsInt($offset, 5, offset); MindFrame2_Core::assertArgumentIsInt($limit, 6, limit); $skel = "SELECTn %snFROMn %s.%sn%s%s%s%s;"; $sql = sprintf($skel, $this->_buildSelectTableSqlFieldClause($table_name), $this->getSharedModule()->escapeDbElementName($database_name), $this->getSharedModule()->escapeDbElementName($table_name), $this->_buildSelectTableSqlJoinClause( $this->getSharedModule()->getDatabase()->getName(), $table_name), $this->_buildSelectTableSqlWhereClause($table_name, $select_data), $this->_buildSelectTableSqlOrderByClause( $table_name, $order_by_columns), $this->_buildSelectTableSqlLimitClause($offset, $limit)); return $sql; }
  • 15. Example Typing Assertionspublic static function assertArgumentIsInt($value, $position, $name){ if (!is_int($value)) { $skel = Expected integer value for argument #%d (%s), %s given; $message = sprintf($skel, $position, $name, gettype($value)); throw new InvalidArgumentException($message); }}public static function assertArgumentIsNotBlank($value, $position, $name){ if (trim($value) === ) { $skel = Argument #%d (%s) cannot be blank; $message = sprintf($skel, $position, $name); throw new InvalidArgumentException($message); }}
  • 16. Use PHPMD & CodeSnifferThis is the ./bin/codecheck script in MindFrame2#!/bin/bashWD="`/usr/bin/dirname $0`/../";echo Changing to working directory: $WD;cd $WD;if [ -z $1 ]; then DIR=.;else DIR=$1;fiphpmd --exclude coverage $DIR text codesize,unusedcode,naming,designphpcs --ignore=coverage --standard=`pwd`/Standards/MindFrame2 $DIRphpcs --ignore=coverage --report=source --standard=`pwd`/Standards/MindFrame2 $DIR
  • 17. Example PHPMD Outputbryan@ubuntu-virtual ~/Code/MindFrame2 [130] $ ./bin/codecheck Dbms/DbiChanging to working directory: ./bin/..//home/bryan/Code/MindFrame2/Dbms/Dbi/Distributed.php:128 Avoid unused localvariables such as $partner./home/bryan/Code/MindFrame2/Dbms/Dbi/Distributed.php:185 Avoid unused localvariables such as $data./home/bryan/Code/MindFrame2/Dbms/Dbi/Distributed.php:199 Avoid unused localvariables such as $index./home/bryan/Code/MindFrame2/Dbms/Dbi/Distributed.php:240 Avoid unused privatemethods such as _buildReplicaDatabaseSuffix./home/bryan/Code/MindFrame2/Dbms/Dbi/Single.php:25 This class has too manymethods, consider refactoring it./home/bryan/Code/MindFrame2/Dbms/Dbi/Single.php:150 Avoid unused parameters such as$options.
  • 18. Example PHPCS OutputFILE: /home/bryan/Code/MindFrame2/Dbms/Dbi/Single.php--------------------------------------------------------------------------------FOUND 6 ERROR(S) AFFECTING 6 LINE(S)-------------------------------------------------------------------------------- 39 | ERROR | Public member variables ("_connection") are forbidden 62 | ERROR | Whitespace found at end of line 144 | ERROR | Whitespace found at end of line 160 | ERROR | Line exceeds maximum limit of 80 characters; contains 97 | | characters 195 | ERROR | Whitespace found at end of line 298 | ERROR | Line exceeds maximum limit of 80 characters; contains 81 | | characters--------------------------------------------------------------------------------
  • 19. Unit testing / TDD Test critical functionality at a minimum Add edge cases to regression tests as they are discovered Test-driven development only works if the entire team is dedicated to it I personally don’t trust code that isn’t regression-tested; even if it was written by me
  • 20. Continuous Integration Automated system for code analysis and regression testing There are a lot of continuous integration systems for PHP If your tests aren’t automated, very few people will know or care when they break
  • 21. Deployment Manually copying files is riddled with problems Tagging releases and re-deploying is a complicated and time-consuming process Deployment systems automate the build and deployment process
  • 22. ACLsMACThread limitsUnwanted services
  • 23. If you’re interested in an application security career, come talk withme.

×