📄 quercus-security.xtp
字号:
<document> <header> <product>resin</product> <title>Quercus Security</title> <description> <p>Description of Quercus and PHP Security Issues</p> </description> </header> <body> <summary/> <localtoc/><s1 title="C language vulnerabilities"><p>Since Quercus implements PHP in the Java language as opposed to C,it is automatically protected from a number of C-language securityissues. The most important issue is buffer and pointer overruns, butalso includes memory issues.</p><s2 title="Buffer Overruns in C"><p>In the C language, strings, arrays, and objects are all referenced bypointers. The simplest example of a security issue is the bufferoverflow. The following example has a string of length 10, but thecode changes a value at location 20. In Java, the equivalent codewould raise an exception. In C, this code writes data at the location20, even though it is beyond the end of the code and is almostcertainly pointing to other important information.</p><example title="example buffer overrun">voidfoo(){ char data[10]; data[20] = '!';}</example><p>At best, this kind of error will cause a segmentation-violation andforce the program to exit, at worst it can create mini-programs whichan attacker can use to gain control of the web server.</p><p>The issue in a C program like PHP is that every single pointerreference must be correct and checked for overruns by the applicationcode. If the programmers miss a single instance, a hacker could usethat bug to run malicious code on the web server.</p><p>The issue does not apply just to arrays, but to all objects, strings, andpointers, since all objects can be cast to a string and that pointercan be used to modify any memory.</p><p>In a Java program like Quercus, this isn't an issue because Javaitself protects every array or object reference. Java will catch anyapplication pointer bug or buffer overflow and throw an exception.Java code can't create and execute mini-programs like C-code can.</p></s2><s2 title="PHP language engine"><p>The first potential source of C-related bugs in PHP is in thelanguage implementation itself. A language implementation consists ofa parser, an interpreter/compiler, and runtime objects like strings,arrays, database connections, etc.</p><p>Quercus can run PHP in either interpreted or compiled modes. In theinterpreted mode, Quercus executes the parsed program directly. Inthe compiled mode, Quercus compiles the PHP code to Java code and thenexecutes Java code. In both cases, the underlying execution uses theJava virtual machine and Java's just-in-time compiler forperformance. Quercus's execution engine is protected by Java'simplementation and the JDK is very solid and safe technology.</p><p>In contrast, PHP implements its own bytecode interpreter in C.This means a bug in the PHP bytecode interpreter could result in apointer security problem, where that issue is absent fromQuercus's implementation.</p></s2><s2 title="PHP runtime objects"><p>The basic runtime objects for PHP need to be implemented as well,the strings, arrays, objects, etc. Quercus implements these objectsas Java objects directly. PHP implements these objects as C objects.The same issues that arise for the interpreter arise for the objects.A pointer failure or failure to initialize data in a PHP array couldcause security problems in the C implementation, while an identicalbug in Quercus would merely throw an exception.</p></s2><s2 title="Memory Management"><p>Quercus automatically uses Java's memory management and garbagecollection system. This means any unused object can simply be droppedand the garbage collector will automatically reuse the object at nextGC time. The garbage collector simplifies the Quercus module code(less code is less potential bugs) and makes certain kinds of memoryleaks impossible.</p><p>The C implementation of PHP needs to implement its own memorymanagement, using a reference counting system. This means any librarycode needs to explicitly dereference an object when it's done usingit. Forgetting to do so creates a new bug.</p></s2><s2 title="Library/Module implementation"><p>Quercus libraries and modules are written in Java. PHP librariesare written in C. This implementation language choice means anyextension library for PHP is subject to the same security issues asdescribed above. Not only does every aspect of the PHP language andobjects need to be correct, but all the libraries and modules need tobe correct.</p><p>In contrast, Quercus libraries are just Java programs. AnyQuercus extension is automatically protected by the Java language.So a site can confidently download a Quercus module from a site likesourceforge and be confident that it doesn't introduce an additionalC-language security bug.</p></s2></s1><s1 title="PHP include visibility"><p>Any significant PHP program will use <code>include</code> tostructure the code, executing code from another PHP file. Theincluded files are valid PHP programs, but are not meant to bebrowsed. However, since the included files are valid PHP programsthey will be browsed and executed if a browser points to theprogram.</p><p>Most PHP programs protect themselves by adding some extra code tothe top of every included file to check if they're being usedproperly:</p><example title="inc.php example protection"><php?if (! $check_include) die("illegal include file");...?></example><p>The include-protection code works, but does require the PHPprogrammer to be careful about each included files. Any mistake cancause an unexpected file to be executed.</p><p>Quercus programmers can instead put all their included files in the WEB-INFdirectory, e.g. in WEB-INF/php. Any Java application serverwill automatically protects all files in WEB-INF directory from allbrowsing. So the PHP include of WEB-INF/php/inc.php will executethe included files, but that file is not browable by an externaluser.</p><s2 title="Configuration file visibility"><p>Often, PHP configuration will be written in PHP itself.This scripting configuration makes customizing PHP programs verysimple and accessible without needing to learn a new syntax, butruns into the same potential PHP include vulnerability listed above.In Quercus, configuration files belong in the WEB-INF directory wherethey are protected from malicious spying.</p></s2><s2 title="Temporary and data file visibility"><p>Many applications need to create temporary file or store plain datafiles. Java applications are accustomed to using either WEB-INF astheir default data directory or configure an external temporarylocation. Because WEB-INF is protected, any temporary file isprotected as well.</p></s2></s1><s1 title="PHP language issues"><s2 title="register_globals"><p>Quercus does not implement the deprecated register_globals capabilityof PHP. So it is impossible for a misconfiguration to open thatparticular vulnerability.</p><p>register_globals is a deprecated feature (disabled by default in PHP),which automatically registered a form's data as PHP variables. So theregister_globals feature opened a large security hole where anattacker could post a bogus form with non-sensical variables toconfuse or reconfigure the script.</p></s2></s1><s1 title="Cross site scripting (XSS)"><p>Since cross-side scripting attacks prey on application errors, not thelanguage engine, both Quercus and PHP programs must take care tofilter their input. See <a href="http://en.wikipedia.org/wiki/Cross_site_scripting">http://en.wikipedia.org/wiki/Cross_site_scripting</a>.</p><p>The basic cross-site scripting vulnerability occurs when anapplication trusts form data and redisplays it to a user. Forexample, a buggy bulletin board system might display a comment withoutescaping the HTML. Since HTML can include JavaScript, this couldallow a malicious commenter to leave some HTML which executedJavaScript on a browser, e.g.</p><example><script language="javascript">alert("This is a bogus alert");</script></example><p>The PHP libraries provide a number of functions to help protectagainst cross-site scripting attacks. A simple example might be:</p><example><?php$clean['message'] = htmlentities($_GET['message']);?></example><ul><li>htmlentities()</li><li>htmlspecialchars()</li><li>strtr()</li><li>strip_tags()</li><li>utf8_decode()</li></ul></s1><s1 title="URLs and Forms"><p>URL and form POST data can be easily spoofed; it does not take asophisticated hacker to generate any HTTP input. So any script thattakes data from the internet must validate the GET, header and POST databefore acting on it.</p><p>The dangers of this issue is apparent to anyone who looks atweb server logs and finds many examples of bogus URLs for programsnot even installed on the server.</p><s2 title="URLs and files"><p>Because PHP can create strings so easily, it's temping to buildan application which selects a file based on the URL data, e.g. fora URL <code>http://foo.com/index.php?page=submit.php</code>.</p><example title="Bogus index.php"><?phpinclude ("page/{$_GET['page']}");?></example><p>Because that example does no validation, any PHP script on theserver at all could be displayed. A better solution would be:</p><example title="Better index.php"><?php$commands = array("comment" => "comment.php", "display" => "display.php");$clean_page = $commands[$_GET['page']];if (! $clean_page) die();</example></s2><s2 title="eval(), system(), and passthru()"><p>Any command which interprets string as PHP or executes a systemcommand is especially dangerous. Consider:</p><example title="bogus.php"><?phpeval($_GET['data']);</example><p>If the URL was<code>http://foo.com/bogus.php?data=passthru("cat/etc/passwd")</code>, you'dhave exposed the server's passwords.</p><ul><li>addslashes()</li><li>escapeshellarg()</li><li>escapeshellcmd()</li><li>realpath()</li></ul></s2><s2 title="Database Injection Protection"><p>In general, web data cannot be trusted. This is especially truefor data that modifies the database. The standard bad example is:</p><example title="php database injection"><?php$sql = "INSERT INTO test VALUES ('{$_POST['data']}')";?></example><p>With the previous bogus code, an attacker could add two recordswith the following data:</p><example>first'), ('second</example><p>To protect against this, you can use the newer PDO interface toavoid the issue entirely, or use escaping functionslike <code>mysql_escape_string()</code>. The PDO interface hastwo advantages: it works for all databases, and it's less likely toforget to escape the data. The PDO code might looks like:</p><example title='PDO bindValue INSERT code'><?php$pdo = new PDO("java:comp/env/jdbc/test");$sql = "INSERT INTO test VALUES(?)";$stmt = $pdo->prepare($sql);$stmt->bindValue(1, $_POST['data']);$stmt->execute();</example><p>The older mysql-style escaping also exists, but newer code shouldmigrate to PDO:</p><example title='PDO bindValue INSERT code'><?php$clean_data = mysql_escape_string($_POST['data']);$sql = "INSERT INTO test VALUES($clean_data)";mysql_query($sql);</example></s2></s1><s1 title="Database Security issues"><s2 title="Configuration files and passwords"><p>PHP programs often configure the databases inside the PHP codeitself or in included files. As mentioned above, Quercus can makethe confguration more secure from prying eyes by putting theconfiguration into the WEB-INF directory.</p><p>In addition, Quercus can use Java DataSources directly, taking theconfiguration out of the PHP code entirely. This configuration willtake precedence over the PHP code, so you can secure an existingapplication without any changes. The Quercus configuration lookslike:</p><example title="WEB-INF/resin-web.xml configuration of Java database"><web-app xmlns="http://caucho.com/ns/resin"> <database jndi-name="jdbc/test"> <driver type="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource" <url>jdbc:mysql://localhost:3306/test</url> <user>foo</user> <password>bar</password> </driver> </database> <servlet-mapping url-pattern="*.php" servlet-class="com.caucho.quercus.servlet.QuercusServlet"> <init> <database>jdbc/test</database> </init> </servlet-mapping></web-app></example></s2></s1><s1 title="Session Security"><s2 title="URL-based sessions"><p>We strongly discourage the use of URL-based sessions as a serioussecurity risk. By default, Quercus disables URL-based sessions.URL-based sessions are particular problems because users will blindlycut and paste URLs with their session information and post them inpublic places. Because these kinds of security breaches occur bysimple mistakes and not concerted hacker attempts, they are far morecommon and serious.</p><p>The URL-based sessions in PHP look something like:</p><example>http://foo.com/test.php?PHPSESSID=asdf</example></s2><s2 title="Cookie Hijacking"><p>Normal HTTP requests are sent in cleartext across the internet,including the cookie values which keep track of sessions. Because thedata is in the clear, it's possible for a malicious hacker to look atthe HTTP request, copy the cookie, and forward a new request to a website. For this reason, you should use SSL for any session that passesany sort of important data, and also timeout any sessions which carryimportant information.</p></s2></s1><s1 title="Extra information"><p>By default, PHP sends error messages to the browser. On aproduction system, this should be turned off:</p><example><web-app xmlns="http://caucho.com/ns/resin"> <servlet-mapping url-pattern="*.php" servlet-class="com.caucho.quercus.QuercusServlet"> <init> <php-ini display_errors="Off" log_errors="On"/> </init> </servlet-mapping></web-app></example></s1> </body></document>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -