{"id":129,"date":"2010-12-18T17:28:00","date_gmt":"2010-12-18T16:28:00","guid":{"rendered":"http:\/\/eguaj.tumblr.com\/post\/2361187940"},"modified":"2011-02-02T20:25:00","modified_gmt":"2011-02-02T19:25:00","slug":"2361187940","status":"publish","type":"post","link":"https:\/\/locallost.net\/?p=129","title":{"rendered":"Re: Hackers bypass .htaccess security by using GETS rather than GET"},"content":{"rendered":"<p><a title=\"http:\/\/cd34.com\/blog\/web-security\/hackers-bypass-htaccess-security-by-using-gets-rather-than-get\/\" href=\"http:\/\/cd34.com\/blog\/web-security\/hackers-bypass-htaccess-security-by-using-gets-rather-than-get\/\"><a href=\"http:\/\/cd34.com\/blog\/web-security\/hackers-bypass-htaccess-security-by-using-gets-rather-than-get\/\">http:\/\/cd34.com\/blog\/web-security\/hackers-bypass-htaccess-security-by-using-gets-rather-than-get\/<\/a><\/a><\/p>\n<p>After reading this article I\u00a0immediately\u00a0checked my application and found that it was subject to this issue. I started worrying and testing out how to mitigate this issue and protect my application.<\/p>\n<p>However, after calming down, I started looking for the cause of this issue, and finally I came to the conclusion that the problem is not from PHP, or Apache, but only in the content of the `.htaccess' file.<\/p>\n<p>Here are my observation on this issue and the working of Apache with mod_php5.<\/p>\n<ul>\n<li>The problem is not only with Zend Server as I replicated the problem with a standard PHP 5.3 and the same `.htaccess'.<\/li>\n<li>\n<p>Why is Apache granting access to \"GETS\" requests without authentication&#160;?<\/p>\n<p>The .htaccess specify that the \"require valid-user\" only applies to \"GET\" and \"POST\" requests. So, a \"GETS\" request is not subject to the \"require valid-user\".<\/p>\n<p>So the request is processed without asking for authentication.<\/p>\n<\/li>\n<li>\n<p>Why Apache does not reject the invalid \"GETS\" request&#160;?<\/p>\n<p>Apache does not send a \"invalid method\" HTTP error message because the ressource pointed by the URL is handled by mod_php5 (AddHandler php5-script .php), so it assumes that mod_php5 will know what to do with a \"GETS\" requests.<\/p>\n<p>So, it passes the request to mod_php5.<\/p>\n<p>This is convenient for implementing new HTTP method like DAV methods in PHP without Apache knowing in advance the full set of method for this protocol.<\/p>\n<\/li>\n<li>\n<p>Why is PHP treating the request as a \"GET\" request&#160;?<\/p>\n<p>From the source code of PHP 5.3 (main\/SAPI.C:sapi_activate()) we see that PHP first check if the request is a \"HEAD\" (special treatment \"only headers\") or \"POST\" (special treatment for decoding the POST data), then anything else is handled to the script.<\/p>\n<p>This is also convenient for handling new HTTP methods (e.g. DAV PROPFIND) from PHP scripts.<\/p>\n<p>So, mod_php5 run the scripts and assumes that the script will know what to do with a \"GETS\" method.<\/p>\n<p>The script does not check which method was used, so it print out his result on STDOUT and that gives a \"HTTP 200 OK\" response to the client.<\/p>\n<\/li>\n<\/ul>\n<p><strong>Conclusion<\/strong><\/p>\n<p>After these observations, I come to the conclusion that this behaviour is normal, and that the real problem lies in the `.htaccess' which only protects \"GET\" and \"POST\" request, missing the fact that other methods can pass and be used to trigger the execution of the PHP script.<\/p>\n<p>One solution is to deny acces to anything that is not \"GET\" or \"POST\" with a &lt;LimitExcept \/&gt;:<\/p>\n<blockquote>\n<pre>AuthUserFile .htpasswd\nAuthName \"Protected Area\"\nAuthType Basic\n\n&lt;Limit GET POST&gt;\n  require valid-user\n&lt;\/Limit&gt;\n\n&lt;LimitExcept GET POST&gt;\n  Order Allow,Deny\n  Deny from all\n&lt;\/LimitExcept&gt;<\/pre>\n<\/blockquote>\n<p>Another one would be to check in the PHP scripts that the $PHP_AUTH_USER variable is set, which will indicate that the HTTP Basic auth as been successfully completed.<\/p>\n<p>Or check $_SERVER[\"REQUEST_METHOD\"], and return an error message if the method is not \"GET\" or \"POST\".<\/p>\n","protected":false},"excerpt":{"rendered":"<p>http:\/\/cd34.com\/blog\/web-security\/hackers-bypass-htaccess-security-by-using-gets-rather-than-get\/ After reading this article I\u00a0immediately\u00a0checked my application and found that it was subject to this issue. I started worrying and testing out how to mitigate this issue and protect my application. However, after calming down, I started looking for &hellip; <a href=\"https:\/\/locallost.net\/?p=129\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4],"tags":[],"class_list":["post-129","post","type-post","status-publish","format-standard","hentry","category-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2Bei9-25","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/posts\/129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/locallost.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=129"}],"version-history":[{"count":1,"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":171,"href":"https:\/\/locallost.net\/index.php?rest_route=\/wp\/v2\/posts\/129\/revisions\/171"}],"wp:attachment":[{"href":"https:\/\/locallost.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/locallost.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/locallost.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}