{"id":24426,"date":"2024-05-02T03:00:47","date_gmt":"2024-05-02T11:00:47","guid":{"rendered":"http:\/\/www.palada.net\/index.php\/2024\/05\/02\/news-18156\/"},"modified":"2024-05-02T03:00:47","modified_gmt":"2024-05-02T11:00:47","slug":"news-18156","status":"publish","type":"post","link":"https:\/\/www.palada.net\/index.php\/2024\/05\/02\/news-18156\/","title":{"rendered":"\u201cDirty stream\u201d attack: Discovering and mitigating a common vulnerability pattern in Android apps"},"content":{"rendered":"<p><strong>Credit to Author: Microsoft Threat Intelligence| Date: Wed, 01 May 2024 18:00:00 +0000<\/strong><\/p>\n<p>Microsoft discovered a path traversal-affiliated vulnerability pattern in multiple popular Android applications that could enable a malicious application to overwrite files in the vulnerable application\u2019s home directory. The implications of this vulnerability pattern include arbitrary code execution and token theft, depending on an application\u2019s implementation. Arbitrary code execution can provide a threat actor with full control over an application\u2019s behavior. Meanwhile, token theft can provide a threat actor with access to the user\u2019s accounts and sensitive data.<\/p>\n<p>We identified several vulnerable applications in the Google Play Store that represented over four billion installations. We anticipate that the vulnerability pattern could be found in other applications. We\u2019re sharing this research so developers and publishers can check their apps for similar issues, fix as appropriate, and prevent introducing such vulnerabilities into new apps or releases. &nbsp;As threats across all platforms continue to evolve, industry collaboration among security researchers, security vendors, and the broader security community is essential in improving security for all. Microsoft remains committed to working with the security community to share vulnerability discoveries and threat intelligence to protect users across platforms.<\/p>\n<p>After discovering this issue, we identified several vulnerable applications. As part of our responsible disclosure policy, we notified application developers through <a href=\"https:\/\/www.microsoft.com\/msrc\/cvd\">Coordinated Vulnerability Disclosure<\/a> (CVD) via <a href=\"https:\/\/www.microsoft.com\/msrc\/msvr\">Microsoft Security Vulnerability Research<\/a> (MSVR) and worked with them to address the issue. We would like to thank the Xiaomi, Inc. and WPS Office security teams for investigating and fixing the issue. As of February 2024, fixes have been deployed for the aforementioned apps, and users are advised to keep their device and installed applications up to date.<\/p>\n<p>Recognizing that more applications could be affected, we acted to increase developer awareness of the issue by collaborating with Google to publish <a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\/untrustworthy-contentprovider-provided-filename\" target=\"_blank\" rel=\"noreferrer noopener\">an article on the Android Developers website<\/a>, providing guidance in a high-visibility location to help developers avoid introducing this vulnerability pattern into their applications. We also wish to thank Google\u2019s Android Application Security Research team for their partnership in resolving this issue.<\/p>\n<p>In this blog post, we continue to raise developer and user awareness by giving a general overview of the vulnerability pattern, and then focusing on <a href=\"https:\/\/developer.android.com\/training\/sharing\/send\" target=\"_blank\" rel=\"noreferrer noopener\">Android share targets<\/a>, as they are the most prone to these types of attacks. We go through an actual code execution case study where we demonstrate impact that extends beyond the mobile device\u2019s scope and could even affect a local network. Finally, we provide guidance to users and application developers and illustrate the importance of collaboration to improve security for all.<\/p>\n<h2 class=\"wp-block-heading\" id=\"overview-data-and-file-sharing-on-android\">Overview: Data and file sharing on Android<\/h2>\n<p>The Android operating system enforces isolation by assigning each application its own dedicated data and memory space. To facilitate data and file sharing, Android provides a component called a content provider, which acts as an interface for managing and exposing data to the rest of the installed applications in a secure manner. When used correctly, a content provider provides a reliable solution. However, improper implementation can introduce vulnerabilities that could enable bypassing of read\/write restrictions within an application\u2019s home directory.<\/p>\n<p>The Android software development kit (SDK) includes the <a href=\"https:\/\/developer.android.com\/reference\/androidx\/core\/content\/FileProvider\" target=\"_blank\" rel=\"noreferrer noopener\"><em>FileProvider<\/em><\/a> class, a subclass of <em>ContentProvider<\/em> that enables file sharing between installed applications. An application that needs to share its files with other applications can declare a <em>FileProvider<\/em> in its app manifest and declare the specific paths to share.<\/p>\n<p>Every file provider has a property called <em>authority<\/em>, which identifies it system-wide, and can be used by the consumer (the app that wants to access the shared files) as a form of address. This content-based model bears a strong resemblance to the web model, but instead of the <em>http <\/em>scheme, consumers utilize the <em>content <\/em>scheme along with the <em>authority<\/em>, followed by a pseudo-path to the file that they want to access.<\/p>\n<p>For example, assuming that the application <em>com.example.server <\/em>shares some files under the <em>file:\/\/\/data\/data\/com.example.server\/files\/images<\/em> directory that it has previously declared as shared using the name <em>shared_images, <\/em>a consumer can use the <em>content:\/\/[authority]\/shared_images\/[sub-path]\/[filename] URI <\/em>to index these files.<\/p>\n<p>Access is given by the data sharing application most commonly using the <a href=\"https:\/\/developer.android.com\/guide\/topics\/manifest\/provider-element#gprmsn\" target=\"_blank\" rel=\"noreferrer noopener\"><em>grantUriPermissions<\/em><\/a> attribute of the Android manifest, in combination with special flags that are used to define a read or write mode of operation. The data sharing application creates and sends an intent to the consumer that provides temporary fine-grained access to a file. \u00a0Finally, when a provider receives a file access request, it resolves the actual file path that corresponds to the incoming URI and returns a file descriptor to it. \u00a0<\/p>\n<h3 class=\"wp-block-heading\" id=\"implementation-pitfalls\">Implementation pitfalls<\/h3>\n<p>This content provider-based model provides a well-defined file-sharing mechanism, enabling a serving application to share its files with other applications in a secure manner with fine-grained control. However, we have frequently encountered cases where the consuming application doesn\u2019t validate the content of the file that it receives and, most concerning, it uses the filename provided by the serving application to cache the received file within the consuming application\u2019s internal data directory. If the serving application implements its own malicious version of <em>FileProvider<\/em>, it may be able to cause the consuming application to overwrite critical files.<\/p>\n<h3 class=\"wp-block-heading\" id=\"share-targets\">Share targets<\/h3>\n<p>In simple terms, a share target is an Android app that declares itself to handle data and files sent by other apps. Common application categories that can be share targets include mail clients, social networking apps, messaging apps, file editors, browsers, and so on. In a common scenario, when a user clicks on a file, the Android operating system triggers the share-sheet dialog asking the user to select the component that the file should be sent to:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-1.-The-Android-share-sheet-dialog-1.webp\" alt=\"Android share sheet dialog displaying apps such as OneDrive, OneNote, Outlook, and others.\" class=\"wp-image-134138 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-1.-The-Android-share-sheet-dialog-1.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 1. The Android share sheet dialog<\/em><\/figcaption><\/figure>\n<p>While this type of guided file-sharing interaction itself may not trigger a successful attack against a share target, a malicious Android application can create a custom, <a href=\"https:\/\/developer.android.com\/guide\/components\/intents-filters#Types\" target=\"_blank\" rel=\"noreferrer noopener\">explicit intent<\/a> and send a file directly to a share target with a malicious filename and without the user\u2019s knowledge or approval. Essentially, the malicious application is substituting its own malicious <em>FileProvider<\/em> implementation and provides a filename that is improperly trusted by the consuming application.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-1024x249.webp\" alt=\"Diagram displaying the distry stream attack steps between the malicious app and a share target APK. First, the request to process file is sent to the APK, which replies with a request for the file name. The malicious app replies with the name, the APK allows it, granting the malicious app the ability to deliver the final malicious payload.\" class=\"wp-image-134122 webp-format\" srcset=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-1024x249.webp 1024w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-300x73.webp 300w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-768x187.webp 768w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-1536x373.webp 1536w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-2048x498.webp 2048w\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-2.-Dirty-stream-attack-1024x249.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 2. Dirty stream attack<\/em><\/figcaption><\/figure>\n<p>In Figure 2, the malicious app, on the left, creates an explicit intent that targets the file processing component of the share target, on the right, and attaches a content URI as an intent\u2019s extra. It then sends this intent to the share target using the <em>startActivity<\/em> API call.<\/p>\n<p>After this point, most of the share targets that we have reviewed seem to follow a specific code pattern that includes the following steps:<\/p>\n<ol>\n<li>Request the actual filename from the remote file provider<\/li>\n<li>Use this filename to initialize a file that is subsequently used to initialize a file output stream<\/li>\n<li>Create an input stream using the incoming content URI<\/li>\n<li>Copy the input stream to the output stream<\/li>\n<\/ol>\n<p>Since the rogue app controls the name as well as the content of the file, by blindly trusting this input, a share target may overwrite critical files in its private data space, which may lead to serious consequences.<\/p>\n<h3 class=\"wp-block-heading\" id=\"impact\">Impact<\/h3>\n<p>We identified this vulnerability pattern in the then-current versions of several Android applications published on the Google Play Store, including at least four with more than 500 million installations each. In each case, we responsibly disclosed to the vendor. Two example vulnerable applications that we identified are <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.mi.android.globalFileexplorer\" target=\"_blank\" rel=\"noreferrer noopener\">Xiaomi Inc.\u2019s File Manager<\/a> (1B+ installs) and <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=cn.wps.moffice_eng\" target=\"_blank\" rel=\"noreferrer noopener\">WPS Office<\/a> (500M+ installs).<\/p>\n<p>In Xiaomi Inc.\u2019s File Manager, we were able to obtain arbitrary code execution in version V1-210567. After our disclosure, Xiaomi published version V1-210593, and we verified that the vulnerability has been addressed. In WPS Office, we were able to obtain arbitrary code execution in version 16.8.1. After our disclosure, WPS published and informed us that the vulnerability has been addressed as of version 17.0.0.<\/p>\n<p>The potential impact varies depending on implementation specifics. For example, it\u2019s very common for Android applications to read their server settings from the <em>shared_prefs <\/em>directory. In such cases, the malicious app can overwrite these settings, causing the vulnerable app to communicate with an attacker-controlled server and send the user\u2019s authentication tokens or other sensitive information.<\/p>\n<p>In a worst-case (and not so uncommon) scenario, the vulnerable application might load native libraries from its data directory (as opposed to the more secure <em>\/data\/app-lib<\/em> directory, where the libraries are <a href=\"https:\/\/googlesamples.github.io\/android-custom-lint-rules\/checks\/UnsafeDynamicallyLoadedCode.md.html\" target=\"_blank\" rel=\"noreferrer noopener\">protected from modification<\/a>). In this case, the malicious application can overwrite a native library with malicious code that gets executed when the library is loaded. In the following section, we use Xiaomi Inc.\u2019s File Manager to illustrate this case. We demonstrated the ability for a malicious application to overwrite the application\u2019s shared preferences, write a native library to the application\u2019s internal storage, and cause the application to load the library. These actions provided arbitrary code execution with the file manager\u2019s user ID and permissions.<\/p>\n<p>In the following sections, we focus on this case and delve into the technical details of this vulnerability pattern.<\/p>\n<h2 class=\"wp-block-heading\" id=\"case-study-xiaomi-inc-s-file-manager\">Case study: Xiaomi Inc.\u2019s File Manager<\/h2>\n<p>Xiaomi Inc.\u2019s File Manager is the default file manager application for Xiaomi devices and is <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.mi.android.globalFileexplorer\" target=\"_blank\" rel=\"noreferrer noopener\">published under the package name <em>com.mi.android.globalFileexplorer<\/em> on the Google Play Store<\/a>, where it has been installed over one billion times.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1-1024x461.webp\" alt=\"Xiaomi&rsquo;s File Manager profile according to Android rank\" class=\"wp-image-134139 webp-format\" srcset=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1-1024x461.webp 1024w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1-300x135.webp 300w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1-768x346.webp 768w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1.webp 1089w\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-3.-Xiaomis-File-Manager-profile-according-to-Android-rank-1-1024x461.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 3. Xiaomi&rsquo;s File Manager profile according to Android rank (source: <a href=\"https:\/\/androidrank.org\/application\/file_manager\/com.mi.android.globalFileexplorer\" target=\"_blank\" rel=\"noreferrer noopener\">File Manager<\/a>)<\/em><\/figcaption><\/figure>\n<p>Besides having full access to the device\u2019s external storage, the application requests many permissions, including the ability to install other applications:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-4.-A-snapshot-of-the-applications-permissions-2.webp\" alt=\"Screenshot of code displaying the app's permissions\" class=\"wp-image-134148 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-4.-A-snapshot-of-the-applications-permissions-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 4. A snapshot of the application&rsquo;s permissions<\/em><\/figcaption><\/figure>\n<p>Further, it offers a junk files cleaner plugin as well as the ability to connect to remote FTP and SMB shares:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-1024x730.webp\" alt=\"Screenshot of using the file manager to connect to remote shares.\" class=\"wp-image-134125 webp-format\" srcset=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-1024x730.webp 1024w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-300x214.webp 300w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-768x547.webp 768w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-1536x1094.webp 1536w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-2048x1459.webp 2048w\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-5.-Connecting-to-remote-shares-using-the-file-manager-1024x730.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 5. Connecting to remote shares using the file manager<\/em><\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"vulnerability-assessment-findings\">Vulnerability assessment findings<\/h2>\n<p>During our investigation, we identified that the application exports the <em>CopyFileActivity<\/em>, an activity alias of the <em>com.android.fileexplorer.activity.FileActivity<\/em>, which is used to handle copy-from-to file operations:<\/p>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-6.-Triggering-the-copy-to-CopyFileActivity.webp\" alt=\"Screenshot of the copy to CopyFileActivity event.\" class=\"wp-image-134126 webp-format\" style=\"width:551px;height:auto\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-6.-Triggering-the-copy-to-CopyFileActivity.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 6. Triggering the copy to CopyFileActivity<\/em><\/figcaption><\/figure>\n<p>Since this activity is exported, it can be triggered by any application installed on the same device by using an explicit intent of action <em>SEND<\/em> or <em>SEND_MULTIPLE<\/em> and attaching a content URI corresponding to a file stream.<\/p>\n<p>Upon receiving such an intent, the browser performs a validity check, which we found to be insufficient:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-1024x720.webp\" alt=\"Screenshot of code displaying the steps for validating an incoming copy file request.\" class=\"wp-image-134127 webp-format\" srcset=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-1024x720.webp 1024w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-300x211.webp 300w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-768x540.webp 768w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-1536x1079.webp 1536w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-2048x1439.webp 2048w\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-7.-Validating-an-incoming-copy-file-request-1024x720.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 7. Validating an incoming copy file request<\/em><\/figcaption><\/figure>\n<p>As depicted above, the <em>initCopyOrMoveIntent<\/em> method calls the<em> checkValid <\/em>method passing as an argument a content URI (steps 1 and 2). However, the <em>checkValid<\/em> method is designed to handle a file path, not a content URI. It always returns true for a content URI. Instead, a safer practice is to <a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\/unsafe-uri-loading\" target=\"_blank\" rel=\"noreferrer noopener\">parse the string as a URI<\/a>, including ensuring the scheme is the expected value (in this case, <em>file<\/em>, not <em>content<\/em>).The <em>checkValid <\/em>method verifies that the copy or move operation doesn\u2019t affect the private directory of the app, by initializing a file object using the incoming string as an argument to the <em>File <\/em>class constructor and comparing its canonical path with the path that corresponds to the home directory of the application (steps 3 and 4). Given a content URI as a path, the <em>File <\/em>constructor normalizes it (following a Unix file system normalization), thus the <em>getCanonicalPath <\/em>method returns a string starting with \u201c<em>\/content:\/<\/em>&#8220;, which will always pass the validity check. More specifically, the app performs a query to the remote content provider for the _<em>size<\/em>, _<em>display<\/em>_<em>name <\/em>and _<em>data <\/em>columns (see line 48 below). Then it uses the values returned by these rows to initialize the fields of an object of the <em>com.android.fileexplorer.mode.c <\/em>class:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-8.-Getting-file-metadata-from-the-remote-content-provider-2.webp\" alt=\"Screenshot of code getting file metadata from the remote content provider.\" class=\"wp-image-134149 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-8.-Getting-file-metadata-from-the-remote-content-provider-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 8. Getting file metadata from the remote content provider<\/em><\/figcaption><\/figure>\n<p>Given the case that the _<em>display<\/em>_<em>name <\/em>and _<em>data <\/em>values, returned from the external file provider, are relative paths to the destination directory, after exiting from the method above, these class fields will contain values like the ones depicted below:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-9.-The-file-model-initialized-after-calling-the-method-a-2.webp\" alt=\"Screenshot of code displaying the file model initialized after calling method a\" class=\"wp-image-134150 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-9.-The-file-model-initialized-after-calling-the-method-a-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 9. The file model initialized after calling the method a<\/em><\/figcaption><\/figure>\n<p>As shown above, the paths (variables <em>d<\/em> and <em>e<\/em>) of this file-model point to files within the home directory of the application, thus the file streams attached to the incoming intent are going to be written under the specific locations.<\/p>\n<h2 class=\"wp-block-heading\" id=\"getting-code-execution\">Getting code execution<\/h2>\n<p>As previously mentioned, the application uses a plugin to clean the device\u2019s junk files:<\/p>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-10.-The-junk-files-cleaner-plugin-user-interface.webp\" alt=\"Screenshot of the junk files cleaner plugin user interface\" class=\"wp-image-134130 webp-format\" style=\"width:333px;height:auto\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-10.-The-junk-files-cleaner-plugin-user-interface.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 10. The junk files cleaner plugin user interface<\/em><\/figcaption><\/figure>\n<p>When the application loads this plugin, it makes use of two native libraries: <em>libixiaomifileu.so<\/em>, which fetches from the <em>\/data\/app<\/em> directory, and <em>libixiaomifileuext.so<\/em> from the home directory:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-11.-Tracing-the-loaded-native-libraries-using-medusa-2.webp\" alt=\"Screenshot of code displaying the loaded native libraries traced using medusa\" class=\"wp-image-134151 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-11.-Tracing-the-loaded-native-libraries-using-medusa-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 11. Tracing the loaded native libraries using medusa<\/em><\/figcaption><\/figure>\n<p>As apps don\u2019t have write access to the <em>\/data\/app<\/em> folder, the <em>libixiaomifileu.so<\/em> file stored there cannot be replaced. The easiest way to get code execution is to replace the <em>libixiaomifileuext.so <\/em>with a malicious one<em>. <\/em>However, an attempt to do so would fail since <strong>in this particular case, the vulnerability that we described can only be used to write new files within the home directory, not overwrite existing files. <\/strong>Our next inquiry was to determine how the application loads the <em>libixiaomifileu.so.<\/em><\/p>\n<p>Our assessment showed that before the application loads this library, it follows the following steps:<\/p>\n<ol>\n<li>Calculate the hash of the file <em>libixiaomifileu.so, <\/em>located in the <em>\/data\/app<\/em> directory<\/li>\n<\/ol>\n<ol start=\"2\">\n<li>Compare this hash with the value assigned to the \u201c<em>libixiaomifileu.so_hm5<\/em>\u201d string, fetched from the <em>com.mi.android.globalFileexprorer_preferences.xml<\/em> file<\/li>\n<\/ol>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-12.-the-com.mi_.android.globalFileexprorer_preferences.xml_-3.webp\" alt=\"Screenshot of code displaying the com.mi.android.globalFileexprorer_preferences.xml\" class=\"wp-image-134153 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-12.-the-com.mi_.android.globalFileexprorer_preferences.xml_-3.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 12. the com.mi.android.globalFileexprorer_preferences.xml<\/em><\/figcaption><\/figure>\n<ol start=\"3\">\n<li>If the values don\u2019t match, search for the <em>libixiaomifileu.so<\/em> file in the <em>\/files\/lib<\/em> path in the home directory<\/li>\n<\/ol>\n<ol start=\"4\">\n<li>If the file is found there, calculate its hash and compare it again with the value from the <em>shared_preferences<\/em> folder<\/li>\n<\/ol>\n<ol start=\"5\">\n<li>If the hashes match, load the file under the <em>\/files\/lib<\/em> using the <em>System.load<\/em> method<\/li>\n<\/ol>\n<p>Given this behavior, in order to get code execution with the file manager\u2019s user ID, an attacker must take the following steps:<\/p>\n<ol>\n<li>Use the path traversal vulnerability to save a malicious library as <em>\/files\/lib\/libixiaomifileu.so <\/em>(the file does not already exist in that directory, so overwriting is not an issue)<\/li>\n<\/ol>\n<ol start=\"2\">\n<li>Calculate the hash of this library to replace the value of the <em>libixiaomifileu.so_hm5 <\/em>string<\/li>\n<\/ol>\n<ol start=\"3\">\n<li>Trigger the junk cleaner plugin with an explicit intent, since the activity that loads the native libraries is exported<\/li>\n<\/ol>\n<p>An acute reader might have noticed that the second step requires the attacker to force the browser to overwrite the <em>com.mi.android.globalFileexprorer_preferences.xml, <\/em>which, as we already mentioned, was not possible.<\/p>\n<p>To overcome this restriction, we referred to the actual implementation of the <em>SharedPreferences <\/em>class, where we found that when an Android application uses the <em>getSharedPreferences <\/em>API method to retrieve an instance of the <em>SharedPreferences <\/em>class, giving the name of the shared preferences file as an argument, then the constructor of the <em>SharedPreferencesImpl <\/em>class <a href=\"https:\/\/cs.android.com\/android\/platform\/superproject\/+\/master:frameworks\/base\/core\/java\/android\/app\/SharedPreferencesImpl.java;l=150\" target=\"_blank\" rel=\"noreferrer noopener\">performs the following steps<\/a>:<\/p>\n<ol>\n<li>Create a new file object using the name provided to the <em>getSharedPreferences <\/em>method, followed by the .xml extension, followed by the .bak extension<\/li>\n<\/ol>\n<ol start=\"2\">\n<li>Check if this file exists, and in case it does, delete the original xml file and replace it with the one created in the first step<\/li>\n<\/ol>\n<p>Through this behavior, we were able to save the <em>com.mi.android.globalFileexprorer_preferences.xml.bak <\/em>under the shared preferences folder (as during the application\u2019s runtime it is unlikely to exist), so when the app tried to verify the hash, the original xml file was already replaced by our own copy. After this point, by using a single intent to start the junk cleaner plugin, we were able to trick the application to load the malicious library instead of the one under the <em>\/data\/app<\/em> folder and get code execution with the browser\u2019s user ID.<\/p>\n<h2 class=\"wp-block-heading\" id=\"impact\">Impact<\/h2>\n<p>One reason we chose to use this app as a showcase is because the impact extends beyond the user\u2019s mobile device. The application gives the option to connect to remote file shares using the FTP and SMB protocols and the user credentials are saved in clear text in the <em>\/data\/data\/com.mi.android.globalFileexplorer\/files\/rmt_i.properties<\/em> file:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-13.-SMB-FTP-credentials-saved-in-clear-text-2.webp\" alt=\"Screenshot of code displaying the SMB or FTP credentials being saved in clear text\" class=\"wp-image-134154 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-13.-SMB-FTP-credentials-saved-in-clear-text-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 13. SMB\/FTP credentials saved in clear text<\/em><\/figcaption><\/figure>\n<p>If a third party app was able to exploit this vulnerability and obtain code execution, an attacker could retrieve these credentials. The impact would then extend even further, since by the time that a user requests to open a remote share, the browser creates the directory <em>\/sdcard\/Android\/data\/com.mi.android.globalFileexplorer\/files\/usbTemp\/ <\/em>where it saves the files that the user retrieves:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-14.-SMB-shared-files-saved-in-the-external-storage-2.webp\" alt=\"Screenshot of code displaying the SMB shared files saved in the external storage\" class=\"wp-image-134155 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-14.-SMB-shared-files-saved-in-the-external-storage-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 14. SMB shared files, saved in the external storage<\/em><\/figcaption><\/figure>\n<p>This means that a remote attacker would be able to read or write files to SMB shares of a local network, assuming that the device was connected to it. The same stands for FTP shares as they are handled exactly in the same way:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-15.-FTP-shared-files-saved-in-the-external-storage-2.webp\" alt=\"Screenshot of code displaying the FTP shared files saved in the external storage\" class=\"wp-image-134156 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-15.-FTP-shared-files-saved-in-the-external-storage-2.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 15. FTP shared files, saved in the external storage<\/em><\/figcaption><\/figure>\n<p>In summary, the exploitation flow is depicted in the figure below:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-1024x369.webp\" alt=\"Diagram displaying how the attacker obtains remote access to local shares, as further detailed in text.\" class=\"wp-image-134136 webp-format\" srcset=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-1024x369.webp 1024w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-300x108.webp 300w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-768x277.webp 768w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-1536x554.webp 1536w, https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-2048x738.webp 2048w\" data-orig-src=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/wp-content\/uploads\/2024\/04\/Figure-16.-Getting-remote-access-to-local-shares-1-1024x369.webp\"><figcaption class=\"wp-element-caption\"><em>Figure 16. Getting remote access to local shares<\/em><\/figcaption><\/figure>\n<p>In<strong> step 1<\/strong>, the user opens a malicious app that may pose as a file editor, messaging app, mail client, or any app in general and request the user to save a file. By the time that the user attempts to save such a file, no matter what destination path they choose to save it, the malicious app forces the file browser app to write it under its internal <em>\/files\/lib<\/em> folder. Then, the malicious app can start the junk cleaner using an explicit intent (no user interaction is required) and this will lead to code execution with the browser\u2019s ID (<strong>step 2<\/strong>).<\/p>\n<p>In <strong>step 3, <\/strong>the attacker uses the arbitrary code execution capability to retrieve the SMB and FTP credentials from the <em>rmt_i.properties <\/em>file. Subsequently, the attacker can now jump to <strong>step 5<\/strong> and access the shares directly using the stolen credentials. Alternatively, after retrieving the share credentials, the mobile device can connect to a local network (<strong>step 4<\/strong>) and access an SMB or FTP share<strong>,<\/strong> allowing the attacker to access the shared files through the <em>\/sdcard\/Android\/data\/com.mi.android.globalFileexplorer\/files\/usbTemp\/ <\/em>folder (<strong>step 5<\/strong>).<\/p>\n<h2 class=\"wp-block-heading\" id=\"recommendations\">Recommendations<\/h2>\n<p>Recognizing that this vulnerability pattern may be widespread, we shared our findings with Google\u2019s Android Application Security Research team. We collaborated with Google to <a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\/untrustworthy-contentprovider-provided-filename\" target=\"_blank\" rel=\"noreferrer noopener\">author guidance<\/a> for Android application developers to help them recognize and avoid this pattern. We recommend developers and security analysts familiarize themselves with the <a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\" target=\"_blank\" rel=\"noreferrer noopener\">excellent Android application security guidance<\/a> provided by Google as well as make use of the <a href=\"https:\/\/developer.android.com\/studio\/write\/lint#gradle\" target=\"_blank\" rel=\"noreferrer noopener\">Android Lint tool<\/a> included with the Android SDK and integrated with Android Studio (supplemented with Google\u2019s <a href=\"https:\/\/github.com\/google\/android-security-lints\/\" target=\"_blank\" rel=\"noreferrer noopener\">additional security-focused checks<\/a>) to identify and avoid potential vulnerabilities. GitHub\u2019s CodeQL also <a href=\"https:\/\/codeql.github.com\/codeql-query-help\/java\/\" target=\"_blank\" rel=\"noreferrer noopener\">provides capabilities<\/a> to identify vulnerabilities.<\/p>\n<p>To prevent these issues, when handling file streams sent by other applications, the safest solution is to completely ignore the name returned by the remote file provider when caching the received content. Some of the most robust approaches we encountered use randomly generated names, so even in the case that the content of an incoming stream is malformed, it won\u2019t tamper with the application.<\/p>\n<p>In cases where such an approach is not feasible, developers need to take extra steps to ascertain that the cached file is written to a dedicated directory. As an incoming file stream is usually identified by a content URI, the first step is to reliably identify and sanitize the corresponding filename. Besides filtering characters that may lead to a path traversal and before performing any write operation, developers must verify that the cached file is within the dedicated directory by performing a call to the <em>File.getCanonicalPath<\/em> and validating the prefix of the returned value.<\/p>\n<p>Another area to safeguard is in the way developers try to extract a filename from a content URI. Developers often use <em>Uri.getLastPathSegment(),<\/em> which returns the (URL) <em>decoded <\/em>value of the last path URI segment. An attacker can craft a URI with URL encoded characters within this segment, including characters used for path traversal. Using the returned value to cache a file can again render the application vulnerable to this type of attack.<\/p>\n<p>For end users, we recommend keeping mobile applications up to date through the Google Play Store (or other appropriate trusted source) to ensure that updates addressing known vulnerabilities are installed. Users should only install applications from trusted sources to avoid potentially malicious applications. We recommend users who accessed SMB or FTP shares through the Xiaomi app before updates to reset credentials and to investigate for any anomalous behavior. <a href=\"https:\/\/learn.microsoft.com\/microsoft-365\/security\/defender-endpoint\/microsoft-defender-endpoint-android?view=o365-worldwide\">Microsoft Defender for Endpoint on Android<\/a> can alert users and enterprises to malicious applications, and <a href=\"https:\/\/www.microsoft.com\/security\/business\/threat-protection\/microsoft-defender-vulnerability-management\">Microsoft Defender Vulnerability Management<\/a> can identify installed applications with known vulnerabilities.<\/p>\n<p><strong><em>Dimitrios Valsamaras<\/em><\/strong><\/p>\n<p><em>Microsoft Threat Intelligence<\/em><\/p>\n<h3 class=\"wp-block-heading\" id=\"references\">References<\/h3>\n<ul>\n<li><a href=\"https:\/\/www.blackhat.com\/asia-23\/briefings\/schedule\/index.html#dirty-stream-attack-turning-android-share-targets-into-attack-vectors-30234\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.blackhat.com\/asia-23\/briefings\/schedule\/index.html#dirty-stream-attack-turning-android-share-targets-into-attack-vectors-30234<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\/untrustworthy-contentprovider-provided-filename\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/privacy-and-security\/risks\/untrustworthy-contentprovider-provided-filename<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/reference\/androidx\/core\/content\/FileProvider\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/reference\/androidx\/core\/content\/FileProvider<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/guide\/topics\/manifest\/provider-element#gprmsn\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/guide\/topics\/manifest\/provider-element#gprmsn<\/a><\/li>\n<li><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.mi.android.globalFileexplorer\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/play.google.com\/store\/apps\/details?id=com.mi.android.globalFileexplorer<\/a><\/li>\n<li><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=cn.wps.moffice_eng\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/play.google.com\/store\/apps\/details?id=cn.wps.moffice_eng<\/a><\/li>\n<li><a href=\"https:\/\/googlesamples.github.io\/android-custom-lint-rules\/checks\/UnsafeDynamicallyLoadedCode.md.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/googlesamples.github.io\/android-custom-lint-rules\/checks\/UnsafeDynamicallyLoadedCode.md.html<\/a><\/li>\n<li><a href=\"https:\/\/androidrank.org\/application\/file_manager\/com.mi.android.globalFileexplorer\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/androidrank.org\/application\/file_manager\/com.mi.android.globalFileexplorer<\/a><\/li>\n<li><a href=\"https:\/\/cs.android.com\/android\/platform\/superproject\/+\/master:frameworks\/base\/core\/java\/android\/app\/SharedPreferencesImpl.java;l=150\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/cs.android.com\/android\/platform\/superproject\/+\/master:frameworks\/base\/core\/java\/android\/app\/SharedPreferencesImpl.java;l=150<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/privacy-and-security\/risks\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/privacy-and-security\/risks<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/studio\/write\/lint#gradle\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/studio\/write\/lint#gradle<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/google\/android-security-lints\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/google\/android-security-lints\/<\/a><\/li>\n<li><a href=\"https:\/\/codeql.github.com\/codeql-query-help\/java\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/codeql.github.com\/codeql-query-help\/java\/<\/a><\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\" id=\"learn-more\">Learn more<\/h3>\n<p>For the latest security research from the Microsoft Threat Intelligence community, check out the Microsoft Threat Intelligence Blog:\u00a0<a href=\"https:\/\/aka.ms\/threatintelblog\">https:\/\/aka.ms\/threatintelblog<\/a>.<\/p>\n<p>To get notified about new publications and to join discussions on social media, follow us on LinkedIn at <a href=\"https:\/\/www.linkedin.com\/showcase\/microsoft-threat-intelligence\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.linkedin.com\/showcase\/microsoft-threat-intelligence<\/a>, and on X (formerly Twitter) at\u00a0<a href=\"https:\/\/twitter.com\/MsftSecIntel\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/twitter.com\/MsftSecIntel<\/a>.<\/p>\n<p>To hear stories and insights from the Microsoft Threat Intelligence community about the ever-evolving threat landscape, listen to the Microsoft Threat Intelligence podcast: <a href=\"https:\/\/thecyberwire.com\/podcasts\/microsoft-threat-intelligence\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/thecyberwire.com\/podcasts\/microsoft-threat-intelligence<\/a>.<\/p>\n<p>The post <a href=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/2024\/05\/01\/dirty-stream-attack-discovering-and-mitigating-a-common-vulnerability-pattern-in-android-apps\/\">\u201cDirty stream\u201d attack: Discovering and mitigating a common vulnerability pattern in Android apps<\/a> appeared first on <a href=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\">Microsoft Security Blog<\/a>.<\/p>\n<p><a href=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/2024\/05\/01\/dirty-stream-attack-discovering-and-mitigating-a-common-vulnerability-pattern-in-android-apps\/\" target=\"bwo\" >https:\/\/blogs.technet.microsoft.com\/mmpc\/feed\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><strong>Credit to Author: Microsoft Threat Intelligence| Date: Wed, 01 May 2024 18:00:00 +0000<\/strong><\/p>\n<p>Microsoft discovered a vulnerability pattern in multiple popular Android applications that could enable a malicious application to overwrite files in the vulnerable application\u2019s internal data storage directory, which could lead to arbitrary code execution and token theft, among other impacts. We have shared our findings with Google\u2019s Android Application Security Research team, as well as the developers of apps found vulnerable to this issue. We anticipate that the vulnerability pattern could be found in other applications. We\u2019re sharing this research more broadly so developers and publishers can check their apps for similar issues, fix as appropriate, and prevent them from being introduced into new apps or releases. <\/p>\n<p>The post <a href=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\/2024\/05\/01\/dirty-stream-attack-discovering-and-mitigating-a-common-vulnerability-pattern-in-android-apps\/\">\u201cDirty stream\u201d attack: Discovering and mitigating a common vulnerability pattern in Android apps<\/a> appeared first on <a href=\"https:\/\/www.microsoft.com\/en-us\/security\/blog\">Microsoft Security Blog<\/a>.<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[10759,10378],"tags":[10462,21863,11682],"class_list":["post-24426","post","type-post","status-publish","format-standard","hentry","category-microsoft","category-security","tag-android","tag-credential-theft","tag-remote-code-execution"],"_links":{"self":[{"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/24426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/comments?post=24426"}],"version-history":[{"count":0,"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/24426\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/media?parent=24426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/categories?post=24426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/tags?post=24426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}