Skip to content

Path traversal via content provider DISPLAY_NAME and unvalidated Intent URIs #140

Description

@pubdev-research

Summary

The share_handler_android plugin (v0.0.11, Android) contains path traversal vulnerabilities (CWE-23) where file names obtained from content providers are used directly in
java.io.File constructors without sanitization. A malicious app sharing content via Intent.ACTION_SEND can supply a crafted DISPLAY_NAME containing path traversal sequences
(e.g., ../../) to write files outside the intended cache directory.

Affected Code

1. ShareHandlerPlugin.ktgetFileNameFromUri() (line 276–278) → attachmentForUri() (line 251)

The DISPLAY_NAME from a content provider is used directly as a file name:

// getFileNameFromUri() — line 276-278val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
if (nameIndex !=-1) {
fileName = c.getString(nameIndex)
}

Then used in a File constructor without sanitization:

// attachmentForUri() — line 251

 val newFile = File(applicationContext.cacheDir, fileName)
  1. FileDirectory.kt — getDataColumn() (line 100–103)

Same pattern — _display_name column is used directly:

 val columnIndex = cursor.getColumnIndexOrThrow(column) // "_display_name"
val fileName = cursor.getString(columnIndex)
targetFile = File(context.cacheDir, fileName)

The file content is then written to this path via FileOutputStream:

 context.contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(targetFile).use { fileOut ->
input.copyTo(fileOut)
}
}

Attack Scenario

  1. A malicious app registers as a share source
  2. User shares content from the malicious app to the victim app (which uses share_handler_android)
  3. The malicious app's content provider returns ../../shared_prefs/malicious.xml as DISPLAY_NAME
  4. share_handler_android writes the shared file to {cacheDir}/../../shared_prefs/malicious.xml, escaping the cache directory
  5. The attacker can overwrite app files within the writable scope

Suggested Fix

Sanitize file names before using them in File constructors:

// Option 1: Strip path separators

 val safeName = fileName.replace("/", "").replace("\\", "")

// Option 2: Use only the base name

 val safeName = File(fileName).name

// Option 3: Validate canonical path

 val targetFile = File(context.cacheDir, fileName)
if (!targetFile.canonicalPath.startsWith(context.cacheDir.canonicalPath)) {
throw SecurityException("Path traversal detected")
}

Both ShareHandlerPlugin.kt and FileDirectory.kt should be patched.

Environment

  • share_handler_android version: 0.0.11 (latest on pub.dev)
  • Platform: Android
  • Tested on Android emulator (API 34)

References

Offer

If you'd like, I can submit a pull request with the fix for both locations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions