Closed gmpetrov closed 1 year ago
Hi, thank you for the changes, although we have found some issues, please check this email thoroughly and get back to us when they have been fixed.
Offloading images, js, css, and other scripts to your servers or any remote service (like Google, MaxCDN, jQuery.com etc) is disallowed. When you call remote data you introduce an unnecessary dependency on another site. If the file you're calling isn't a part of WordPress Core, then you should include it -locally- in your plugin, not remotely. If the file IS included in WordPress core, please call that instead.
An exception to this rule is if your plugin is performing a service. We will permit this on a case by case basis. Since this can be confusing we have some examples of what are not permitted: Offloading jquery CSS files to Google - You should include the CSS in your plugin. Inserting an iframe with a help doc - A link, or including the docs in your plugin is preferred. Calling images from your own domain - They should be included in your plugin. Here are some examples of what we would permit: Calling font families from Google or their approved CDN (if GPL compatible) API calls back to your server to process possible spam comments (like Akismet) Offloading comments to your own servers (like Disqus) oEmbed calls to a service provider (like Twitter or YouTube) Please remove external dependencies from your plugin and, if possible, include all files within the plugin (that is not called remotely). If instead you feel you are providing a service, please re-write your readme.txt in a manner that explains the service, the servers being called, and if any account is needed to connect.
Example(s) from your plugin:
chaindesk.php:118 src='https://cdn.jsdelivr.net/npm/@databerry/chat-bubble@latest'
When you include POST/GET/REQUEST/FILE calls in your plugin, it's important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.
SANITIZE: Data that is input (either by a user or automatically) must be sanitized as soon as possible. This lessens the possibility of XSS vulnerabilities and MITM attacks where posted data is subverted.
VALIDATE: All data should be validated, no matter what. Even when you sanitize, remember that you don’t want someone putting in ‘dog’ when the only valid values are numbers.
ESCAPE: Data that is output must be escaped properly when it is echo'd, so it can't hijack admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data.
To help you with this, WordPress comes with a number of sanitization and escaping functions. You can read about those here:
https://developer.wordpress.org/apis/security/sanitizing/ https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. If you’re sanitizing email, use sanitize_email(), if you’re outputting HTML, use wp_kses_post(), and so on.
An easy mantra here is this:
Sanitize early Escape Late Always Validate
Clean everything, check everything, escape everything, and never trust the users to always have input sane data. After all, users come from all walks of life.
Example(s) from your plugin:
chaindesk.php:59 $http_callback = "http" . (($_SERVER['SERVER_PORT'] == 443) ? "s://" : "://") . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Hi, we can consider it a service which is allowed as long you meet some requirements.
We permit plugins to require the use of 3rd party (i.e. external) services, provided they are properly documented in a clear manner.
We require plugins that reach out to other services to disclose this, in clear and plain language, so users are aware of where data is being sent. This allows them to ensure that any legal issues with data transmissions are covered. This is true even if you are the 3rd party service.
In order to do so, you must update your readme to do the following:
clearly explain that your plugin is relying on a 3rd party as a service and under what circumstances provide a link to the service provide a link to the services’ a terms of use and/or privacy policies
Remember, this is for your own legal protection. Use of services must be upfront and well documented.
Example(s) from your plugin: chatbotgpt/chatbotgpt.php:125 src='https://cdn.jsdelivr.net/npm/@databerry/chat-bubble@latest'
In this situation you have to keep in mind that the provider of this script load is jsdelivr.net
And there are still some issues
Please note that we are sharing with you examples of code that have issues, but it is possible that there are more cases of those issues. We need you to check all the code to check if there are more occurrences of these issues.
If you need help checking that out or have any doubt, feel free to ask us before sending us a new version of the plugin, this will save both of us time and further reviews.
When you include POST/GET/REQUEST/FILE calls in your plugin, it's important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.
SANITIZE: Data that is input (either by a user or automatically) must be sanitized as soon as possible. This lessens the possibility of XSS vulnerabilities and MITM attacks where posted data is subverted.
VALIDATE: All data should be validated, no matter what. Even when you sanitize, remember that you don’t want someone putting in ‘dog’ when the only valid values are numbers.
ESCAPE: Data that is output must be escaped properly when it is echo'd, so it can't hijack admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data.
To help you with this, WordPress comes with a number of sanitization and escaping functions. You can read about those here:
https://developer.wordpress.org/apis/security/sanitizing/ https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. If you’re sanitizing email, use sanitize_email(), if you’re outputting HTML, use wp_kses_post(), and so on.
An easy mantra here is this:
Sanitize early Escape Late Always Validate
Clean everything, check everything, escape everything, and never trust the users to always have input sane data. After all, users come from all walks of life.
Example(s) from your plugin:
chatbotgpt/chatbotgpt.php:65 $http_callback = esc_url("http" . (($_SERVER['SERVER_PORT'] == 443) ? "s://" : "://") . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
Note that you need to sanitize early and using sanitizing functions, esc_url is a escaping function.
Much related to sanitizing everything, all variables that are echoed need to be escaped when they're echoed, so it can't hijack users or (worse) admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data, as well as some that will allow you to echo HTML safely.
At this time, we ask you escape all $-variables, options, and any sort of generated data when it is being echoed. That means you should not be escaping when you build a variable, but when you output it at the end. We call this 'escaping late.'
Besides protecting yourself from a possible XSS vulnerability, escaping late makes sure that you're keeping the future you safe. While today your code may be only outputted hardcoded content, that may not be true in the future. By taking the time to properly escape when you echo, you prevent a mistake in the future from becoming a critical security issue.
This remains true of options you've saved to the database. Even if you've properly sanitized when you saved, the tools for sanitizing and escaping aren't interchangeable. Sanitizing makes sure it's safe for processing and storing in the database. Escaping makes it safe to output.
Also keep in mind that sometimes a function is echoing when it should really be returning content instead. This is a common mistake when it comes to returning JSON encoded content. Very rarely is that actually something you should be echoing at all. Echoing is because it needs to be on the screen, read by a human. Returning (which is what you would do with an API) can be json encoded, though remember to sanitize when you save to that json object!
There are a number of options to secure all types of content (html, email, etc). Yes, even HTML needs to be properly escaped.
https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. There is pretty much an option for everything you could echo. Even echoing HTML safely.
Example(s) from your plugin:
chatbotgpt/chatbotgpt.php:130 echo $output;
The wordpress plugin has been refused by the wordpress team, the following items need to be adjusted before re-submitting the plugin
There are issues with your plugin code preventing it from being approved immediately. We have pended your submission in order to help you correct all issues so that it may be approved and published.
We ask you read this email in its entirety, address all listed issues, and reply to this email with your corrected code attached (or linked). You have three (3) months to make all corrections, before your plugin will be rejected. Even so, as long as you reply to this email, we will be able to continue with your review and eventually publish your code.
Remember in addition to code quality, security and functionality, we require all plugins adhere to our guidelines. If you have not yet, please read them:
https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/
We know it can be long, but you must follow the directions at the end as not doing so will result in your review being delayed. It is required for you to read and reply to these emails, and failure to do so will result in significant delays with your plugin being accepted.
Finally, should you at any time wish to alter your permalink (aka the plugin slug), you must explicitly tell us what you want it to be. Just changing the display name is not sufficient, and we require to you clearly state your desired permalink. Remember, permalinks cannot be altered after approval.
Be aware that you will not be able to submit another plugin while this one is being reviewed.
Including a docker files
We do not permit plugins to include zip files. It was probably an oversight, but please remove any and all files that are not from your plugin.
Please use wp_enqueue commands
Your plugin is not correctly including JS and/or CSS. You should be using the built in functions for this:
https://developer.wordpress.org/reference/functions/wp_enqueue_script/ https://developer.wordpress.org/reference/functions/wp_enqueue_style/
And remember you can use this function to add inline javascript:
https://developer.wordpress.org/reference/functions/wp_add_inline_script/
As of WordPress 5.7, you can pass attributes like async, nonce, and type by using new functions and filters:
https://make.wordpress.org/core/2021/02/23/introducing-script-attributes-related-functions-in-wordpress-5-7/
If you're trying to enqueue on the admin pages you'll want to use the admin enqueues
https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ https://developer.wordpress.org/reference/hooks/admin_print_scripts/ https://developer.wordpress.org/reference/hooks/admin_print_styles/
Example(s) from your plugin:
wordpress/databerry.php:60:<link rel="stylesheet" href="<?php echo plugins_url("assets/style.css", FILE );">
Calling files remotely
Offloading images, js, css, and other scripts to your servers or any remote service (like Google, MaxCDN, jQuery.com etc) is disallowed. When you call remote data you introduce an unnecessary dependency on another site. If the file you're calling isn't a part of WordPress Core, then you should include it -locally- in your plugin, not remotely. If the file IS included in WordPress core, please call that instead.
An exception to this rule is if your plugin is performing a service. We will permit this on a case by case basis. Since this can be confusing we have some examples of what are not permitted:
Offloading jquery CSS files to Google - You should include the CSS in your plugin. Inserting an iframe with a help doc - A link, or including the docs in your plugin is preferred. Calling images from your own domain - They should be included in your plugin.
Here are some examples of what we would permit:
Calling font families from Google or their approved CDN (if GPL compatible) API calls back to your server to process possible spam comments (like Akismet) Offloading comments to your own servers (like Disqus) oEmbed calls to a service provider (like Twitter or YouTube)
Please remove external dependencies from your plugin and, if possible, include all files within the plugin (that is not called remotely). If instead you feel you are providing a service, please re-write your readme.txt in a manner that explains the service, the servers being called, and if any account is needed to connect.
Example(s) from your plugin:
wordpress/databerry.php:113: src='https://cdn.jsdelivr.net/npm/@databerry/chat-bubble@latest'
Incorrect Stable Tag
In your readme, your 'Stable Tag' does not match the Plugin Version as indicated in your main plugin file.
ERROR: Readme Stable tag and header versions are different 4.7 != 0.21 readme.txt - Stable tag: 4.7 databerry.php - Version: 0.21
Your Stable Tag is meant to be the stable version of your plugin, not of WordPress. For your plugin to be properly downloaded from WordPress.org, those values need to be the same. If they're out of sync, your users won't get the right version of your code.
We recommend you use Semantic Versioning (aka SemVer) for managing versions:
https://en.wikipedia.org/wiki/Software_versioning https://semver.org/
Please note: While currently using the stable tag of trunk currently works in the Plugin Directory, it's not actually a supported or recommended method to indicate new versions and has been known to cause issues with automatic updates.
We ask you please properly use tags and increment them when you release new versions of your plugin, just like you update the plugin version in the main file. Having them match is the best way to be fully forward supporting.
Tested Up To Value is Out of Date, Invalid, or Missing
The tested up to value in your plugin is not set to the current version of WordPress. This means your plugin will not show up in searches, as we require plugins to be compatible and documented as tested up to the most recent version of WordPress.
Please update your readme to show that it is tested up to the most recent stable major version of WordPress. For example if WordPress said that version 99.0.1 was the current release, you would be able to set your value to 99.0 or 99.0.1, as 99.0.1 would be considered a minor release.
The following links will assist you in understanding WordPress's versioning and the latest version:
https://wordpress.org/download/ https://make.wordpress.org/core/handbook/about/release-cycle/version-numbering/
You cannot set it beyond the current version, as that will cause your plugin not to be available on searches. Also remember that WordPress has made late changes in releases, so claiming compatibility with an incomplete version is likely to land you in trouble.
From your readme file:
ERROR: Tested up: 4.8 < 6.2
Data Must be Sanitized, Escaped, and Validated
When you include POST/GET/REQUEST/FILE calls in your plugin, it's important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.
SANITIZE: Data that is input (either by a user or automatically) must be sanitized as soon as possible. This lessens the possibility of XSS vulnerabilities and MITM attacks where posted data is subverted.
VALIDATE: All data should be validated, no matter what. Even when you sanitize, remember that you don’t want someone putting in ‘dog’ when the only valid values are numbers.
ESCAPE: Data that is output must be escaped properly when it is echo'd, so it can't hijack admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data.
To help you with this, WordPress comes with a number of sanitization and escaping functions. You can read about those here:
https://developer.wordpress.org/apis/security/sanitizing/ https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. If you’re sanitizing email, use sanitize_email(), if you’re outputting HTML, use wp_kses_post(), and so on.
An easy mantra here is this:
Sanitize early Escape Late Always Validate
Clean everything, check everything, escape everything, and never trust the users to always have input sane data. After all, users come from all walks of life.
Example(s) from your plugin:
wordpress/databerry.php:41 update_option("agent_id", $_GET["agentId"]); wordpress/databerry.php:45 update_option("website_verify", $_GET["databerry_verify"]); wordpress/databerry.php:54 $http_callback = "http" . (($_SERVER['SERVER_PORT'] == 443) ? "s://" : "://") . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Variables and options must be escaped when echo'd
Much related to sanitizing everything, all variables that are echoed need to be escaped when they're echoed, so it can't hijack users or (worse) admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data, as well as some that will allow you to echo HTML safely.
At this time, we ask you escape all $-variables, options, and any sort of generated data when it is being echoed. That means you should not be escaping when you build a variable, but when you output it at the end. We call this 'escaping late.'
Besides protecting yourself from a possible XSS vulnerability, escaping late makes sure that you're keeping the future you safe. While today your code may be only outputted hardcoded content, that may not be true in the future. By taking the time to properly escape when you echo, you prevent a mistake in the future from becoming a critical security issue.
This remains true of options you've saved to the database. Even if you've properly sanitized when you saved, the tools for sanitizing and escaping aren't interchangeable. Sanitizing makes sure it's safe for processing and storing in the database. Escaping makes it safe to output.
Also keep in mind that sometimes a function is echoing when it should really be returning content instead. This is a common mistake when it comes to returning JSON encoded content. Very rarely is that actually something you should be echoing at all. Echoing is because it needs to be on the screen, read by a human. Returning (which is what you would do with an API) can be json encoded, though remember to sanitize when you save to that json object!
There are a number of options to secure all types of content (html, email, etc). Yes, even HTML needs to be properly escaped.
https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. There is pretty much an option for everything you could echo. Even echoing HTML safely.
Example(s) from your plugin:
wordpress/databerry.php:71 -----> echo $agent_id; wordpress/databerry.php:60 <link rel="stylesheet" href="<?php echo plugins_url("assets/style.css", FILE );?>"> wordpress/databerry.php:73 <?php _e('Reconfigure', 'databerry'); ?> -----> echo $add_to_databerry_link; wordpress/databerry.php:69 -----> echo $agent_id; wordpress/databerry.php:118 echo $output; wordpress/databerry.php:88 <?php _e('Connect with Databerry', 'databerry'); ?> -----> echo $add_to_databerry_link;
Generic function/class/define/namespace/option names
All plugins must have unique function names, namespaces, defines, class and option names. This prevents your plugin from conflicting with other plugins or themes. We need you to update your plugin to use more unique and distinct names.
A good way to do this is with a prefix. For example, if your plugin is called "Easy Custom Post Types" then you could use names like these: function ecpt_save_post() define( 'ECPT_LICENSE', true ); class ECPT_Admin{} namespace ECPT; update_option( 'ecpt_settings', $settings );
Don't try to use two (2) or three (3) letter prefixes anymore. We host nearly 100-thousand plugins on WordPress.org alone. There are tens of thousands more outside our servers. Believe us, you’re going to run into conflicts.
You also need to avoid the use of _ (double underscores), wp , or _ (single underscore) as a prefix. Those are reserved for WordPress itself. You can use them inside your classes, but not as stand-alone function.
Please remember, if you're using _n() or __() for translation, that's fine. We're only talking about functions you've created for your plugin, not the core functions from WordPress. In fact, those core features are why you need to not use those prefixes in your own plugin! You don't want to break WordPress for your users.
Related to this, using if (!function_exists('NAME')) { around all your functions and classes sounds like a great idea until you realize the fatal flaw. If something else has a function with the same name and their code loads first, your plugin will break. Using if-exists should be reserved for shared libraries only.
Remember: Good prefix names are unique and distinct to your plugin. This will help you and the next person in debugging, as well as prevent conflicts.
Analysis result:
This plugin is using the prefix "databerry" for 5 element(s).
Looks like there are 4 element(s) not using common prefixes.
wordpress/databerry.php:41 update_option("agent_id", $_GET["agentId"]); wordpress/databerry.php:45 update_option("website_verify", $_GET["databerry_verify"]); wordpress/databerry.php:24 function register_databerry_plugin_onboarding wordpress/databerry.php:34 function register_databerry_plugin_settings
Allowing Direct File Access to plugin files
Direct file access is when someone directly queries your file. This can be done by simply entering the complete path to the file in the URL bar of the browser but can also be done by doing a POST request directly to the file. For files that only contain a PHP class the risk of something funky happening when directly accessed is pretty small. For files that contain procedural code, functions and function calls, the chance of security risks is a lot bigger.
You can avoid this by putting this code at the top of all php files: if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
Example(s) from your plugin:
wordpress/databerry.php:16
Please note that due to the significant backlog the Plugin Review team is facing, we have only done a basic review of your plugin. Once the issues we shared above are fixed, we will do a more in-depth review that might surface other issues. In order to prevent further delays, we strongly urge you to review the guidelines again before you resubmit it.
If the corrections we requested in this initial review are not completed within 3 months (90 days), we will reject this submission in order to keep our queue manageable and you will need to resubmit the plugin from scratch.
Your next steps are:
Make all the corrections related to the issues we listed. Review your entire code following the guidelines to ensure there are no other related concerns. Attach your corrected plugin as a zip file OR provide a link to a public location (Dropbox, Github, etc) from where we can download the code. A direct link to the zip is best. Please do not send it using services where the download expires after a short period of time (such as WeTransfer-Free). Once we receive your updated code, we will re-review it from top down.
Be aware that if your zip contains javascript files, you may not be able to email it as many hosts block that in the interests of security. Keep in mind, all version control directories (like Github) will auto-generate a zip for you, so you do not need to upload a zip file to their systems. You can just link to the repository.
We again remind you that should you wish to alter your permalink (not the display name, the plugin slug), you must explicitly tell us what you want it to be. We require to you clearly state in the body of your email what your desired permalink is. Permalinks cannot be altered after approval, and we generally do not accept requests to rename should you fail to inform us during the review.
If you previously asked for a permalink change and got a reply that is has been processed, you’re all good! While these emails will still use the original display name, you don’t need to panic. If you did not get a reply that we processed the permalink, let us know immediately. While we have tried to make this review as exhaustive as possible we, like you, are humans and may have missed things. As such, we will re-review the entire plugin when you send it back to us. We appreciate your patience and understanding.
If you have questions, concerns, or need clarification, please reply to this email and just ask us.
-- WordPress Plugin Review Team | plugins@wordpress.org https://make.wordpress.org/plugins/ https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/ {#HS:2318482502-404809#}