Skip to content

Add Write File Check to detect plugin directory writes#1137

Open
davidperezgar wants to merge 8 commits intotrunkfrom
665-check-asks-users-to-editwrite-to-plugin-use-uploads-folder
Open

Add Write File Check to detect plugin directory writes#1137
davidperezgar wants to merge 8 commits intotrunkfrom
665-check-asks-users-to-editwrite-to-plugin-use-uploads-folder

Conversation

@davidperezgar
Copy link
Copy Markdown
Member

@davidperezgar davidperezgar commented Dec 27, 2025

Fixes #665

Implements a new check to detect when plugins save data in the plugin folder.

Plugin folders are deleted when upgraded, so using them to store any data is problematic. This check helps developers identify these issues and directs them to use the uploads directory or database instead.

Changes Made

1. WriteFileSniff (PHPCS Sniff)

Created phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/WriteFileSniff.php:

  • Extends AbstractFunctionParameterSniff to detect file write functions
  • Monitors functions: fwrite, fputs, file_put_contents, touch, copy, rename, copy_dir, move_dir, unzip_file
  • Detects plugin directory indicators:
    • Constants: WP_PLUGIN_DIR, WP_PLUGIN_URL, PLUGINDIR, WPINC, WP_CONTENT_DIR, WP_CONTENT_URL
    • Functions: plugins_url(), plugin_dir_path(), plugin_dir_url()
    • Magic constants: __FILE__, __DIR__
  • Allows safe paths using wp_upload_dir(), wp_tempnam(), get_temp_dir()
  • Provides clear error messages with remediation guidance

2. Write_File_Check Class

Updated includes/Checker/Checks/Plugin_Repo/Write_File_Check.php:

  • Added proper description
  • Added documentation URL
  • Integrates the sniff into Plugin Check

3. Test Coverage

Test Plugins:

  • test-plugin-write-file-with-errors/: Contains 7 examples of incorrect usage
  • test-plugin-write-file-without-errors/: Contains examples of correct usage

PHPUnit Tests:

  • Write_File_Check_Tests.php: Tests the check class
  • WriteFileUnitTest.php and WriteFileUnitTest.inc: Tests the sniff directly

4. Configuration

  • Added PluginCheck.CodeAnalysis.WriteFile rule to phpcs-sniffs/PluginCheck/ruleset.xml

Limitations

The sniff uses static analysis and can only detect file write operations where the path is directly specified in the function call. It cannot detect:

  • Paths stored in variables before the function call
  • Dynamically constructed paths using complex logic
  • File writes through wrapper functions or classes

This limitation is acceptable as it catches the most common cases.

Related Resources

Acknowledgments

This check is based on the calls_write_file_warning detection logic from the internal plugin review scanner developed by @frantorres, which has been successfully identifying these issues during manual reviews. This implementation makes that same detection available to plugin developers as an automated check.

@davidperezgar davidperezgar linked an issue Dec 27, 2025 that may be closed by this pull request
@davidperezgar davidperezgar added this to the 1.9.0 milestone Dec 27, 2025
@davidperezgar davidperezgar modified the milestones: 1.9.0, 2.0.0 Mar 15, 2026
@davidperezgar davidperezgar marked this pull request as ready for review April 15, 2026 20:27
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 15, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: davidperezgar <davidperez@git.wordpress.org>
Co-authored-by: ernilambar <nilambar@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

/**
* Check to detect loading files from external sites.
*
* @since n.e.x.t.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @since n.e.x.t.
* @since 2.0.0

/**
* Returns an associative array of arguments to pass to PHPCS.
*
* @since 1.0.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @since 1.0.0
* @since 2.0.0

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Check: Asks users to edit/write to plugin (use uploads folder)

2 participants