{"id":2494,"date":"2022-03-18T15:43:26","date_gmt":"2022-03-18T15:43:26","guid":{"rendered":"https:\/\/devel0pment.de\/?p=2494"},"modified":"2022-03-21T08:41:14","modified_gmt":"2022-03-21T08:41:14","slug":"from-single-double-quote-confusion-to-rce-cve-2022-x-y","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=2494","title":{"rendered":"From Single \/ Double Quote Confusion To RCE (CVE-2022-24637)"},"content":{"rendered":"\n<style>\n.hl {\n  color:#2222ff;\n  font-family:'Courier New', monospace;\n  font-weight:bold;\n}\n\n.hl2 {\n  color:#ff0000;\n}\n<\/style>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.openwebanalytics.com\/\" target=\"_blank\">Open Web Analytics (OWA)<\/a> is an open-source alternative to Google Analytics. OWA is written in PHP and can be hosted on an own server. Version 1.7.3 suffers from two vulnerabilities, which can be exploited by an unauthenticated attacker to gain RCE, when chained together.<\/p>\n\n\n\n<p>The cause of the first vulnerability (<a href=\"https:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2022-24637\" rel=\"noopener noreferrer\" target=\"_blank\">CVE-2022-24637<\/a>) is a single quote \/ double quote confusion, which leads to an information disclosure. The header of an automatically generated PHP cache file containing sensitive information is defined as <span class=\"hl\">&#x27;&lt;?php\\n&#8230;&#x27;<\/span> instead of <span class=\"hl\">&#x22;&lt;?php\\n&#8230;&#x22;<\/span>. This leads to a literal <span class=\"hl\">backslash<\/span> and <span class=\"hl\">n<\/span> character being written instead of a <span class=\"hl\">newline<\/span> character resulting in a broken PHP tag. Because of this the file is not interpreted as PHP code, but delivered in plain leaking sensitive cache information. This information can be leveraged to set a new password for the admin user.<\/p>\n\n\n\n<p>The second vulnerability is a PHP file write, which requires admin privileges. The internal settings for the logfile path as well as the log level can be changed by manually crafting a POST request. This way the logfile can be set to a PHP file. By also increasing the log level and generating an event with attacker controlled data, PHP code can be injected into this logfile. This results in the possibility to execute arbitrary PHP code.<\/p>\n\n\n\n<p>I would like to thank Peter Adams, the creator and maintainer of OWA who released a patch for the issue only one day after my initial notification. I was really amazed by the quick and professional reaction. There are security issues in each and every software, but the difference is how these are dealt with.<\/p>\n\n\n\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#intro\">Introduction<\/a><br>\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#vuln1\">Single \/ Double Quote Confusion<\/a><br>\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#vuln2\">PHP file write<\/a><br>\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#demo\">Demonstration<\/a><br>\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#patch\">Patch and Mitigations<\/a><br>\n\u2013 <a href=\"https:\/\/devel0pment.de\/?p=2494#con\">Conclusion<\/a><br><p><\/p>\n\n\n\n<!--more-->\n\n\n\n<style>\ncode {\n  font-family:\"Courier 10 Pitch\", Courier, monospace;\n  font-size:14px;\n  line-height:18px;\n  background-color:#000000;\n  color:#00ff00 !important;\n  padding-left:10px;\n  padding-right:10px;\n  padding-bottom:10px;\n  display:block;\n  white-space:pre-wrap;\n  word-wrap:break-word;\n  margin-bottom:15px;\n}\n<\/style>\n\n\n\n<hr>\n<h1 id=\"intro\">Introduction<\/h1>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.openwebanalytics.com\/\" target=\"_blank\">Open Web Analytics (OWA)<\/a> is an open-source web analytics software written in PHP and using a MySQL database. The source code is freely available on <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/Open-Web-Analytics\/Open-Web-Analytics\" target=\"_blank\">GitHub<\/a>. OWA offers profound tracking capabilities as well as a wide variety of detailed reports. In contrast to Google Analytics, OWA can be hosted on an own server.<\/p>\n\n\n\n<p>In this article we will take a look at two vulnerabilities in OWA, which enable an unauthenticated attacker to gain RCE on the underlying webserver when combined. After determining the root cause of these vulnerabilities, we will point out how these can be mitigated and highlight a few general aspects regarding secure coding.<\/p>\n\n\n\n<h1 id=\"vuln1\">Single \/ Double Quote Confusion<\/h1>\n\n\n\n<p>A basic entity in OWA is represented by the <span class=\"hl\">owa_entity<\/span> class. Examples for such entities inheriting from <span class=\"hl\">owa_entity<\/span> are documents (<span class=\"hl\">owa_document<\/span>), sites (<span class=\"hl\">owa_site<\/span>) or users (<span class=\"hl\">owa_user<\/span>). These entities are persisted in the MySQL database. In order to increase performance, OWA version 1.7.3 and prior uses a file based caching mechanism by default. When an entity is loaded from the database the first time, it is cached by writing its serialized data to a cache file.<\/p>\n\n\n\n<p>The creation of these cache files is implemented in the <span class=\"hl\">putItemToCacheStore<\/span> method within the <span class=\"hl\">owa_fileCache<\/span> class (<span class=\"hl\">modules\/base\/classes\/fileCache.php<\/span>):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n...\n\n    function putItemToCacheStore($collection, $id) {\n    \n            ...\n        \n            $data = $this-&gt;cache_file_header.base64_encode(serialize($this-&gt;cache&#x5B;$collection]&#x5B;$id])).$this-&gt;cache_file_footer;\n\n            ...\n            \n            $tcf_handle = @fopen($temp_cache_file, &#039;w&#039;);\n\n            ...\n            \n                fputs($tcf_handle, $data);\n                \n                ...\n<\/pre><\/div>\n\n\n<p>As we can see, the serialized entity is base64 encoded and written to a temporary cache file. The name of this temporary file is later changed to consist of a unique id with a <span class=\"hl\">.php<\/span> extension:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n            ...\n            \n            $cache_file = $collection_dir.$id.&#039;.php&#039;;\n    \n            ...\n            \n                if (!@ rename($temp_cache_file, $cache_file)) {\n                \n                    ...\n<\/pre><\/div>\n\n\n<p>In the first code snippet we can also see that the base64 encoded data is prefixed by <span class=\"hl\">cache_file_header<\/span> and suffixed by <span class=\"hl\">cache_file_footer<\/span>. Let&#8217;s see how these are defined:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n...\n\nclass owa_fileCache extends owa_cache {\n\n    ...\n    \n    var $cache_file_header = &#039;&lt;?php\\n\/*&#039;;\n    var $cache_file_footer = &#039;*\/\\n?&gt;&#039;;\n    \n    ...\n<\/pre><\/div>\n\n\n<p>Accordingly a cache file is supposed to look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n&lt;?php\n\/*BASE64-ENCODED DATA*\/\n?&gt;\n<\/pre><\/div>\n\n\n<p>When directly accessing such a PHP file, the response is supposed to be empty, because the file only contains a comment. Though the above strings are surrounded by single quotes instead of double quotes, which makes a severe difference when it comes to escape sequences:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nphp &gt; echo &#039;&lt;?php\\n\/*&#039;; \/\/ &lt;-- single quotes\n&lt;?php\\n\/*\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nphp &gt; echo &quot;&lt;?php\\n\/*&quot;; \/\/ &lt;-- double quotes\n&lt;?php\n\/*\n<\/pre><\/div>\n\n\n<p>As the above example shows, when using single quotes, escape sequences such as <span class=\"hl\">\\n<\/span> are not evaluated.<\/p>\n\n\n\n<p>What does this mean for the generated PHP file? The PHP tag <span class=\"hl\">&lt;?php<\/span> is supposed to be followed by a line feed (<span class=\"hl\">0x0a<\/span>) like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nuser@b0x:~$ cat sample1.php \n&lt;?php\necho 1;\n?&gt;\n\nuser@b0x:~$ php -f sample1.php\n1\n<\/pre><\/div>\n\n\n<p>Valid alternatives for the line feed are tab (<span class=\"hl\">0x09<\/span>), carriage return (<span class=\"hl\">0x0d<\/span>) or space (<span class=\"hl\">0x20<\/span>). Though, when the PHP tag is directly followed by a backslash character, it is no a valid PHP tag anymore and the PHP code is not interpreted, but rather displayed in plain:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nuser@b0x:\/tmp$ cat sample2.php\n&lt;?php\\necho 1;\\n?&gt;\n\nuser@b0x:\/tmp$ php -f sample2.php\n&lt;?php\\necho 1;\\n?&gt;\n<\/pre><\/div>\n\n\n<p>Since the PHP cache files are publicly accessible (<span class=\"hl\">owa-data\/caches\/<\/span>), we can retrieve the base64 encoded serialized data. In order to do this, we need to know the name of the cache file. Though it turned out, that the filename is predictable. If the admin user at least logged in once, the cache file exists. But even if the user never logged in, we can trigger the creation by trying to login with this user. The failed login attempt does also create the cache file.<\/p>\n\n\n\n<p>After calculating the filename, we can easily retrieve the cache file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [3]; title: ; notranslate\" title=\"\">\nuser@b0x:~$ curl http:\/\/localhost\/owa_web\/owa-data\/caches\/1\/owa_user\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.php\n\n&lt;?php\\n\/*Tzo4OiJvd2FfdXNlciI6NTp7czo0OiJ ... YWNoZSI7Tjt9*\/\\n?&gt;\n<\/pre><\/div>\n\n\n<p>The base64 encoded data contains all properties of the user within the MySQL database including the username, hashed password, <span class=\"hl\">temp_passkey<\/span> and API key:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nuser@b0x:~$ echo Tzo4OiJvd2FfdXNlciI6NTp7czo0OiJ ... YWNoZSI7Tjt9 | base64 -d\nO:8:&quot;owa_user&quot;:5:{s:4:&quot;name&quot;;s:9:&quot;base.user&quot;;s:10:&quot;properties&quot;; ...\n...\n... s:4:&quot;name&quot;;N;s:5:&quot;value&quot;;s:5:&quot;admin&quot;; ...\n... s:8:&quot;password&quot;;O:12:&quot;owa_dbColumn&quot;:11:{s:4:&quot;name&quot;;N;s:5:&quot;value&quot;;s:60:&quot;$2y$10$vT89Rpbp\/kz92SdR2j03luLVFOy7ldaqdyOIpTmFtmp2WGGOmFIwS&quot;; ...\n... s:12:&quot;temp_passkey&quot;;O:12:&quot;owa_dbColumn&quot;:11:{s:4:&quot;name&quot;;N;s:5:&quot;value&quot;;s:32:&quot;d7d8c0d6c8da08adea071fa80220b121&quot;; ...\n... s:7:&quot;api_key&quot;;s:5:&quot;value&quot;;s:32:&quot;2f37b9889afb326b2ae21a5eb45933bd&quot;; ...\n...\n}s:12:&quot;wasPersisted&quot;;b:1;s:5:&quot;cache&quot;;N;}\n<\/pre><\/div>\n\n\n<p>The password is hashed and thus needs to be cracked before being valuable. Though the <span class=\"hl\">temp_passkey<\/span> can directly be used to set a new password for the user via the <span class=\"hl\">base.usersChangePassword<\/span> action. After changing the password, an attacker can successfully login and now has full admin privileges.<\/p>\n\n\n\n<h1 id=\"vuln2\">PHP file write<\/h1>\n\n\n\n<p>The second vulnerability is a PHP file write, which requires admin privileges.<\/p>\n\n\n\n<p>By browsing to the <span class=\"hl\">Settings<\/span> tab in the admin interface, different options can be set:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/02\/screen01.png\" alt=\"\" class=\"wp-image-2506\" width=\"768\" height=\"526\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/02\/screen01.png 1081w, https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/02\/screen01-300x206.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/02\/screen01-1024x702.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/02\/screen01-768x526.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p>When updating the settings (action <span class=\"hl\">base.optionsUpdate<\/span>) the controller <span class=\"hl\">owa_optionsUpdateController<\/span> is triggered, which is responsible for persisting the new settings:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\nclass owa_optionsUpdateController extends owa_adminController {\n\n    ...\n\n    function action() {\n\n        $c = owa_coreAPI::configSingleton();\n\n        $config_values = $this-&gt;get(&#039;config&#039;);\n\n        if (!empty($config_values)) {\n\n            foreach ($config_values as $k =&gt; $v) {\n\n                list($module, $name) = explode(&#039;.&#039;, $k);\n\n                if ( $module &amp;&amp; $name ) {\n                    $c-&gt;persistSetting($module, $name, $v);\n                }\n            }\n\n            $c-&gt;save();\n            owa_coreAPI::notice(&quot;Configuration changes saved to database.&quot;);\n            $this-&gt;setStatusCode(2500);\n        }\n\n        $this-&gt;setRedirectAction(&#039;base.optionsGeneral&#039;);\n    }\n\n    ...\n<\/pre><\/div>\n\n\n<p>The selected settings are sent via the <span class=\"hl\">config<\/span> parameter (<span class=\"hl\">$config_values<\/span>). As we can see there is no restriction on the settings we can define. Although only a few settings are displayed in the GUI on the <span class=\"hl\">Settings<\/span> tab, we can change all other settings by crafting a corresponding POST request.<\/p>\n\n\n\n<p>Two of these settings are used within the <span class=\"hl\">owa_error<\/span> class, which is responsible for logging. When the application is running in production mode, the method <span class=\"hl\">createProductionHandler<\/span> is called to initialize the logfile by calling <span class=\"hl\">make_file_logger<\/span>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n...\nclass owa_error {\n\n    ...\n\n    function createProductionHandler() {\n\n        ...\n        \n        $this-&gt;make_file_logger();\n\n        ...\n    }\n    \n    ...\n    \n    function make_file_logger() {\n\n        $path = owa_coreAPI::getSetting(&#039;base&#039;, &#039;error_log_file&#039;);\n        \/\/instantiate a a log file\n        $conf = array(&#039;name&#039; =&gt; &#039;debug_log&#039;, &#039;file_path&#039; =&gt; $path);\n        $this-&gt;loggers&#x5B;&#039;file&#039;] = owa_coreAPI::supportClassFactory( &#039;base&#039;, &#039;logFile&#039;, $conf );\n    }\n<\/pre><\/div>\n\n\n<p>As we can see the file path of the logfile is determined by calling the <span class=\"hl\">owa_coreAPI::getSetting<\/span> method. The setting being used is <span class=\"hl\">base.error_log_file<\/span>. We can control this value and thus control the file path, where the log is being written. This means that we can also set the file path to be a PHP file. In order to execute arbitrary PHP code, we only need to control some data, which is written to the logfile.<\/p>\n\n\n\n<p>By default the application is only logging events with the log level <span class=\"hl\">OWA_LOG_NOTICE<\/span>. These messages are mainly static and do not contain any data, which can be controlled by an attacker. Thus let&#8217;s have a look at the logging mechanism.<\/p>\n\n\n\n<p>When a message is supposed to be logged, the method <span class=\"hl\">logMsg<\/span> is called with the corresponding priority (log level):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; gutter: false; title: ; notranslate\" title=\"\">\n    function logMsg( $msg, $priority ) {\n\n        ...\n        \n        \/\/ check error priority before logging.\n        if ( owa_coreAPI::getSetting(&#039;base&#039;, &#039;error_log_level&#039;) &lt;= $priority ) {\n\n            $dt = date(&quot;H:i:s Y-m-d&quot;);\n            $pid = getmypid();\n            foreach ( $this-&gt;loggers as $logger ) {\n\n                $message = sprintf(&quot;%s %s &#x5B;%s] %s \\n&quot;, $dt, $pid, $logger-&gt;name, $msg);\n                $logger-&gt;append( $message );\n                ...\n<\/pre><\/div>\n\n\n<p>The code snippet above shows that before the message is actually logged, the value of <span class=\"hl\">base.error_log_level<\/span> is checked. If the <span class=\"hl\">$priority<\/span> value is greater or equal than the current <span class=\"hl\">base.error_log_level<\/span>, the message is logged. We can also control the value of <span class=\"hl\">base.error_log_level<\/span>. By setting this value to <span class=\"hl\">OWA_LOG_DEBUG = 2<\/span>, the messages being logged are very verbose and even include each POST parameter send to the application. This way an attacker can easily inject arbitrary PHP code into the logfile. By accessing this logfile, which was set to a PHP file, the injected code is executed resulting in RCE.<\/p>\n\n\n\n<h1 id=\"demo\">Demonstration<\/h1>\n\n\n\n<p>The combination of both vulnerabilities can be leveraged by an unauthenticated attacker to gain RCE as the following demonstration shows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"420\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2022\/03\/owa_unauth_rce.gif\" alt=\"\" class=\"wp-image-2564\"\/><\/figure>\n\n\n\n<h1 id=\"patch\">Patch and Mitigations<\/h1>\n\n\n\n<p>Within this section we want to determine how both of these vulnerabilities can be mitigated and point out a few general aspects regarding secure coding.<\/p>\n\n\n\n<p>Only shortly after my notification Peter provided a <a href=\"https:\/\/github.com\/Open-Web-Analytics\/Open-Web-Analytics\/commit\/c1c823445df7dc96ee940e340805a7ba7a538482\" rel=\"noopener noreferrer\" target=\"_blank\">patch<\/a> for the file cache vulnerability (CVE-2022-24637). This patch tackles the vulnerability on multiple layers. At first single quotes for the <span class=\"hl\">cache_file_header<\/span> and <span class=\"hl\">cache_file_footer<\/span> are replaced by double quotes preventing the leak, which was the actual cause of the vulnerability. Though the patch contains further hardening. The secret <span class=\"hl\">OWA_AUTH_KEY<\/span> value is included into the cache filename calculation. Without knowing this value, it is far harder to determine the name of the cache file. Also the <span class=\"hl\">owa_user<\/span> entity was removed from the cache at all. Thus there is no cache file for user entities. Not part of the above commit, but also a crucial mitigation is to prevent files from being accessed via the webserver, which are not supposed to be accessed directly. One way to achieve this is to move all files out of the webroot, which are not supposed to be accessed via the webserver. The problem with this solution is that the website administrator needs file system access beyond the webroot. Depending on the hosting or security model this might not be intended. Another way is to use a webserver specific restriction mechanism like an <span class=\"hl\">.htaccess<\/span> file, when an apache webserver is in place.<\/p>\n\n\n\n<p>The second vulnerability is quite common for PHP. File writes should really be handled carefully. If an attacker can control what is being written to a file, RCE is not far away. Even if the file does not reside within the webroot or does not have a <span class=\"hl\">.php<\/span> extension, an additional local file inclusion (LFI) vulnerability, which might be useless on its own, turns this into easy RCE. In this case a restriction should enforce that the logfile can only be a <span class=\"hl\">.txt<\/span> file. Also this file should not reside within the webroot, if viable. This restriction must be enforced, if there is the necessity of making the file path configurable. Generally the settings, which are configurable via the webinterface, should be very limited. A more adequate way to make sensitive settings configurable is by defining constant values in a config file. These can only be changed by actually altering the config file (which in the best case should only be possible to the legitimate website administrator).<\/p>\n\n\n\n<p>Summing up, the key takeaways are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Mind the difference between single and double quotes in PHP<\/li><li>When hashing values, add a secret pepper \/ salt value<\/li><li>Do not store any files in the webroot, which are not supposed to be accessed via the webserver, or employ restrictions to prevent direct access to these files<\/li><li>Carefully restrict file writes (content, file path and extension)<\/li><li>Restrict which settings are configurable via the webinterface<\/li><\/ul>\n\n\n\n<h1 id=\"con\">Conclusion<\/h1>\n\n\n\n<p>The article described the chaining of two vulnerabilities in OWA, which can be exploited by an unauthenticated attacker to gain RCE on the underlying webserver. Also we took a look at how these vulnerabilities can be mitigated and pointed out a few general aspects regarding secure coding.<\/p>\n\n\n\n<p>Thanks again to Peter for professionally handling these issues and quickly providing a patch.<\/p>\n\n\n\n<p><strong>Timeline<\/strong><br>01 February 2022 &#8211; Vendor Notification<br>01 February 2022 &#8211; Vendor Acknowledgement<br>02 February 2022 &#8211; Vendor Patch<br>18 March 2022 &#8211; Public Disclosure<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Open Web Analytics (OWA) is an open-source alternative to Google Analytics. OWA is written in PHP and can be hosted on an own server. Version 1.7.3 suffers from two vulnerabilities, which can be exploited by an unauthenticated attacker to gain RCE, when chained together. The cause of the first vulnerability (CVE-2022-24637) is a single quote &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/devel0pment.de\/?p=2494\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;From Single \/ Double Quote Confusion To RCE (CVE-2022-24637)&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[54,55,28],"class_list":["post-2494","post","type-post","status-publish","format-standard","hentry","category-article","tag-cve-2022-24637","tag-php","tag-web"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/2494"}],"collection":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2494"}],"version-history":[{"count":80,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/2494\/revisions"}],"predecessor-version":[{"id":2590,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/2494\/revisions\/2590"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}