Monday 30 August 2010

iPlanet / Sun One Web Server Fun with Security

I've always been a fan of the Apache HTTP Server derived web servers. The reason is simple – as they are open source at the core they have been extended and built upon to provide the ultimate in flexibility. Then high end vendors, such as Oracle, build and license enterprise level functionality (such as for security and management), and ship their derivative with enterprise level products. This is the case with the Oracle HTTP Server (OHS) web tier packaging for the Oracle WebLogic Server middleware and related products that build upon it.

Take for instance security, where the Apache HTTP Server and its derivatives have the benefits of openssl support supplemented with the modsecurity plugin. This latter plugin offers an engine that implements a large number of security rules, defined in terms of extended regular expressions, that are applied against every request to reject or transform the input or output. This plugin turns the web server into a web application firewall that sits in the flow of each request to whatever sits behind it, whether it be a static page, a CGI application written in Perl, or a Java-based web application server.

The modsecurity plugin is one of the major differentiators between the different web server solutions, and purely targets the Apache derived web servers. The rules are set up in a hierarchy of basic through to extended rules for different security problems, with a basic core set recommended for use everywhere. Processing all of the rules is expensive which is why the modsecurity plugin sits in the normal request flow for the web server and is highly optimised.

However, what if you have been using the Sun One / NetScape / iPlanet web server family? This family of web servers is extensible but with a different API set (Netscape NSAPI), so the Apache derived extensions can't be used. Whilst NSAPI extensions have long been produced for many uses, which often function with greater performance than for the similar function on the Apache web server family, the same breadth of functionality just isn't there. Before the Oracle purchase of Sun, this weakness had been recognised and a multipronged attack on the key problem areas was undertaken. A direct port of the modsecurity engine to the Sun One / iPlanet web server has been started, with an unsupported implementation with near complete functionality in the version 7 codebase, but not all keywords required for the rules are available in this release and it remains unsupported for production use. A simpler but fully supported solution is the sed filter; which is also provided with the version 7 product, but as a separate NSAPI plugin implementing the sed_request and sed_response server application functions (SAFs) which could theoretically be lifted out and run against earlier versions of the web server.

So, how does the sed filter help? Well, although the functionality is less than that of the full modsecurity engine and performance is more limited, as implementing the Unix stream editor (sed) support for simple basic regular expressions it is possible to port some of the key modsecurity rules. The approach is a simple one:

  1. Choose the key rules for modsecurity that are to implemented, e.g. SQL injection, cross-site scripting, etc

  2. Open the rule set for each and copy out the extended regular expression

  3. Translate the extended regular expression to a standard basic regular expression, including replacing the found string with nothing

  4. Import the new sed rule into the obj.conf for the web server instance

This is best explained with a simple example.

First download the modsecurity source code from http://www.modsecurity.org and unpackage the tarball. In the resulting directory tree go to the rules/base_rules subdirectory and open the modsecurity_crs_41_sql_injection_attacks.conf file. In this file are a number of security rules defined, but a simple examination of each will show the format, the phase and a description after the SecRule keyword and some type information. Note that many of the security rules can be applied unchanged by the unsupported Sun One / iPlanet modsecurity engine that will be a full implementation in a future release. After the type information the extended regular expression used to define when the rule is to be applied can be found. For example, consider one SQL injection rule:

SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\buser_tab_columns\b" \

"phase:2,rev:'2.0.5',capture,t:none,ctl:auditLogParts=+E,pass,no

log,auditlog,msg:'Blind SQL Injection Attack',id:'959536',tag:'WEB_ATTACK/SQL_IN

JECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',t

ag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar

:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%

{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matc

hed_var_name}=%{tx.0}"


In this the extended regular expression saying when this rule applies is "\buser_tab_columns\b"

which tells the rules engine to look for the phrase “user_tab_columns” in the input stream.

We want to replace this with nothing, so a sample sed rule for this would be

sed="s/\buser_tab_columns\b//g"

This says to replace all occurences found in the stream with nothing.

Taking this to its extreme, which will not result in the fastest processing, but will ptotect from cross-site scripting and SQL injection POST attacks against a back end Oracle environment, we end up with a complex segment of an obj.conf for Oracle iPlanet Web Server 7.09

Input fn="insert-filter"

method="POST"

filter="sed-request"

sed="s/

sed="s/%3c/\\</g"

sed="s/%3C/\\</g"

sed="s/>/\\>/g"

sed="s/%3e/\\>/g"

sed="s/%3E/\\>/g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\x2Eexecscript\b//g"

sed="s/

sed="s/\burl\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\blivescript://g"

sed="s/\bsettimeout\b[^a-zA-Z_0-9]*?//g"

sed="s/\x3C ?iframe//g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\becmascript\b//g"

sed="s/\x2Ecookie\b//g"

sed="s/\x3C\x21\x5Bcdata\x5B//g"

sed="s/\x2Eaddimport\b//g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bjscript\b//g"

sed="s/\balert\b[^a-zA-Z_0-9]*?\x28//g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\bapplication\b[^a-zA-Z_0-9]*?\bx-vbscript\b//g"

sed="s/\x3C ?meta\b//g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bhttp://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bvbscript\b//g"

sed="s/\blowsrc\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\burl\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/\x2Einnerhtml\b//g"

sed="s/\x40import\b//g"

sed="s/\x3C ?script\b//g"

sed="s/\biframe\b.{0,100}?\bsrc\b//g"

sed="s/

sed="s/\burl\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bjavascript\b//g"

sed="s/\x2Efromcharcode\b//g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\x2Eexecscript\b//g"

sed="s/

sed="s/\burl\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\bsettimeout\b[^a-zA-Z_0-9]*?\x28//g"

sed="s/\x3C ?iframe//g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\becmascript\b//g"

sed="s/\x2Ecookie\b//g"

sed="s/\x3C\x21\x5Bcdata\x5B//g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\bapplication\b[^a-zA-Z_0-9]*?\bx-javascript\b//g"

sed="s/\x2Eaddimport\b//g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bjscript\b//g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\bapplication\b[^a-zA-Z_0-9]*?\bx-vbscript\b//g"

sed="s/\x3C ?meta\b//g"

sed="s/\bsrc\b[^a-zA-Z_0-9]*?\bhttp://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bvbscript\b//g"

sed="s/\bhref\b[^a-zA-Z_0-9]*?\bvbscript://g"

sed="s/\burl\b[^a-zA-Z_0-9]*?\bjavascript://g"

sed="s/\x2Einnerhtml\b//g"

sed="s/\x3C ?script\b//g"

sed="s/\biframe\b.{0,100}?\bsrc\b//g"

sed="s/

sed="s/\burl\b[^a-zA-Z_0-9]*?\bshell://g"

sed="s/\btype\b[^a-zA-Z_0-9]*?\btext\b[^a-zA-Z_0-9]*?\bjavascript\b//g"

sed="s/<(a|abbr|acronym|address|applet|area|audioscope|b|base|basefront|bdo|bgso

und|big|blackface|blink|blockquote|body|bq|br|button|caption|center|cite|code|co

l|colgroup|comment|dd|del|dfn|dir|div|dl|dt|em|embed|fieldset|fn|font|form|frame

|frameset|h1|head|hr|html|i|iframe|ilayer|img|input|ins|isindex|kdb|keygen|label

|layer|legend|li|limittext|link|listing|map|marquee|menu|meta|multicol|nobr|noem

bed|noframes|noscript|nosmartquotes|object|ol|optgroup|option|p|param|plaintext|

pre|q|rt|ruby|s|samp|script|select|server|shadow|sidebar|small|spacer|span|strik

e|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|ul|v

ar|wbr|xml|xmp)[^a-zA-Z_0-9]//g"

sed="s/(asfunction|javascript|vbscript|data|mocha|livescript)://g"

sed="s/(fromcharcode|alert|eval)\x73*\x28//g"

sed="s///g"

sed="s/[/'\"<]xss[/'\">]//g"

sed="s/(88,83,83)//g"

sed="s/'';!--\"=&{()}//g"

sed="s/&{//g"

sed="s/

sed="s/(?i:.*?((@[i\\\\])|(([:=]|(&[#\x28\x29=]x?0*((58)|(3A)|(61)|(3D

));?)).*?([(\\\\]|(&[#()=]x?0*((40)|(28)|(92)|(5C));?)))))//g"

sed="s/(?i:[ /+\t\"\'`]style[ /+\t]*?=.*?([:=]|(&[#()=]x?0*((58)|(3A)|(61)|(3D))

;?)).*?([(\\\\]|(&[#()=]x?0*((40)|(28)|(92)|(5C));?)))//g"

sed="s/(?i:

)//g"

sed="s/(?i:[ /+\t\"\'`]datasrc[ +\t]*?=.)//g"

sed="s/(?i:

sed="s/(?i:

sed="s/(?i:

sed="s/(?i:

sed="s/(?i:

sed="s/(?i:[ /+\t\"\'`]on\x63\x63\x63+?[ +\t]*?=.)//g"

sed="s/(?i:<[i]?frame.*?[ /+\t]*?src[ /+\t]*=)//g"

sed="s/(?i:])//g"

sed="s/(?i:)//g"

sed="s/(?i:

sed="s/(?i:)//g"

sed="s/(?i:[\"\'][ ]*(([^a-z0-9~_:\'\" ])|(in)).*?(((l|(\\\\u006C))(o|(\\\\u006F

))(c|(\\\\u0063))(a|(\\\\u0061))(t|(\\\\u0074))(i|(\\\\u0069))(o|(\\\\u006F))(n|

(\\\\u006E)))|((n|(\\\\u006E))(a|(\\\\u0061))(m|(\\\\u006D))(e|(\\\\u0065)))).*?

=)//g"

sed="s/(?i:[\"\'][ ]*(([^a-z0-9~_:\'\" ])|(in)).+?(([.].+?)|([\x5B].*?[\x5D].*?)

)=)//g"

sed="s/\bsys\x2Euser_catalog\b//g"

sed="s/\bconstraint_type\b//g"

sed="s/\bsys\x2Euser_tables\b//g"

sed="s/\bmsysqueries\b//g"

sed="s/\bmsysaces\b//g"

sed="s/\x40\x40spid\b//g"

sed="s/\bcharindex\b//g"

sed="s/\bsys\x2Eall_tables\b//g"

sed="s/\bsys\x2Euser_constraints\b//g"

sed="s/\bselect\b.{0,40}buser\b//g"

sed="s/\bwaitfor\b[^a-zA-Z_0-9]*?\bdelay\b//g"

sed="s/\bselect\b.{0,40}\bsubstring\b//g"

sed="s/\bsys\x2Euser_triggers\b//g"

sed="s/\blocate[^a-zA-Z_0-9]+\x28//g"

sed="s/\bsys\x2Euser_tab_columns\b//g"

sed="s/\battnotnull\b//g"

sed="s/\bsys\x28tab\b//g"

sed="s/\bselect\b.{0,40}\bascii\b//g"

sed="s/\bsys\x2Euser_views\b//g"

sed="s/\binstr[^a-zA-Z_0-9]+\x28//g"

sed="s/\bsys\x2Euser_objects\b//g"

sed="s/\buser_tables\b//g"

sed="s/\buser_tab_columns\b//g"

sed="s/\ball_objects\b//g"

sed="s/\bpg_class\b//g"

sed="s/\bsyscat\b//g"

sed="s/\bsubstr\b//g"

sed="s/\bsysdba\b//g"

sed="s/\btextpos[^a-zA-Z_0-9]+\x28//g"

sed="s/\battrelid\b//g"

sed="s/\bpg_attribute\b//g"

sed="s/\buser_password\b//g"

sed="s/\buser_users\b//g"

sed="s/\buser_constraints\b//g"

sed="s/\bxtype[^a-zA-Z_0-9]+\bchar\b//g"

sed="s/\bcolumn_name\b//g"

sed="s/\bsubstring\b//g"

sed="s/\bobject_type\b//g"

sed="s/\bobject_id\b//g"

sed="s/\buser_ind_columns\b//g"

sed="s/\bcolumn_id\b//g"

sed="s/\bmb_users\b//g"

sed="s/\btable_name\b//g"

sed="s/\bobject_name\b//g"

sed="s/\brownum\b//g"

sed="s/\batttypid\b//g"

sed="s/\buser_group\b//g"

sed="s/\butl_http\b//g"

sed="s/\bselect\b.*?\bto_number\b//g"

sed="s/\btbcreator\b//g"

sed="s/\bgroup\b.*\bbyb.{1,100}?\bhaving\b//g"

sed="s/\bselect\b.*?\bdata_type\b//g"

sed="s/\bisnull\b[^a-zA-Z_0-9]*?\x28//g"

sed="s/\bopenrowset\b//g"

sed="s/\bunion\b.{1,100}?\bselect\b//g"

sed="s/\binsert\b[^a-zA-Z_0-9]*?\binto\b//g"

sed="s/\bselect\b.{1,100}?\bcount\b.{1,100}?\bfrom\b//g"

sed="s/\x3B[^a-zA-Z_0-9]*?\bdrop\b//g"

sed="s/\bloadb[^a-zA-Z_0-9]*?\bdata\b.*\binfile\b//g"

sed="s/\bselect\b.*?\bto_char\b//g"

sed="s/\bdbms_java\b//g"

sed="s/\bnvarchar\b//g"

sed="s/\butl_file\b//g"

sed="s/\binner\b[^a-zA-Z_0-9]*?\bjoin\b//g"

sed="s/\bprint\b[^a-zA-Z_0-9]*?\x40\x40//g"

sed="s/\bselect\b.{1,100}?\bfrom\b.{1,100}?\bwhere\b//g"

sed="s/\bvarchar\b//g"

sed="s/\bintob[^a-zA-Z_0-9]*?\bdumpfile\b//g"

sed="s/\bifb[^a-zA-Z_0-9]*?\x28[^a-zA-Z_0-9]*?\bbenchmark[^a-zA-Z_0-9]*?\x28//g"

sed="s/\bopenquery\b//g"

sed="s/\bselect\b.{1,100}?\blength\b.{1,100}?\bfrom\b//g"

sed="s/\bcastb[^a-zA-Z_0-9]*?\x28//g"

sed="s/\bdelete\b[^a-zA-Z_0-9]*?\bfrom\b//g"

sed="s/\bsql_longvarchar\b//g"

sed="s/\bselect\b.*?\bdump\b.*\bfrom\b//g"

sed="s/\'sa\'//g"

sed="s/\bifnull\b[^a-zA-Z_0-9]*?\x28//g"

sed="s/\bintob[^a-zA-Z_0-9]*?\boutfile\b//g"

sed="s/\bsql_variant\b//g"

sed="s/\x3B[^a-zA-Z_0-9]*?\bshutdown\b//g"

sed="s/\bselect\b.*?\binstr\b//g"

sed="s/\bautonomous_transaction\b//g"

sed="s/\bdba_users\b//g"

sed="s/\bselect\b.{1,100}?\btop\b.{1,100}?\bfrom\b//g"

sed="s/\b(?:coalesce\b|root\x40)//g"

sed="s/\b(?:(?:rel(?:(?:nam|typ)e|kind)|to_(?:numbe|cha)r|d(?:elete|rop)|group\b

[^a-zA-Z_0-9]*\bby|insert|where)\b|s(?:(?:ubstr(?:ing)?|leep)[^a-zA-Z_0-9]+\x28|

(?:hutdown|elect)\b)|(?:b(?:enchmark|in)|find_in_set|position|mid)[^a-zA-Z_0-9]+

\x28|c(?:o(?:n(?:cat[^a-zA-Z_0-9]+\x28|vert\b)|unt\b)|ha?r\b)|u(?:n(?:hex[^a-zA-

Z_0-9]+\x28|ion\b)|pdate\b)|l(?:o(?:cate|wer)[^a-zA-Z_0-9]+\x28|ength\b)|a(?:ttn

(?:ame|um)\b|scii[^a-zA-Z_0-9]+\x28)|h(?:aving\b|ex[^a-zA-Z_0-9]+\x28))//g"

sed="s/(?:[\\\x28\x29\x25#]|--)//g"

sed="s/\b(?:benchmark|encode)\b//g"

sed="s/(?:[\\\x28\x29\x25#]|--)//g"

This gives maximum protection at the cost of performance, but with more web servers taking the strain the impact should be controllable. Note that the most effort in producing this was in identifying which rules are relevant to a given environment and then automating the porting of extended regular expression syntax elements to basic regular expression equivalents – which sometimes is so complex that alternatives are easier to produce from the ground up.

So, you now have a complex web application firewall using Sun One / Oracle iPlanet Web Server 7 that allows you to implement now whilst awaiting the greatly improved native modsecurity support to be implemented and fully supported in a future release. I can't guarantee this solution will meet your needs, but I can say it gives a good starting point that offers great latitude to tuning through rule deletion to meet specific security needs.