There have been reports of plugins that have started erasing their managed Custom Fields upon actions like comment submission. UTW was bitten, as was Jerome’s Keywords and some other plugins that use custom fields.
The problem was brought to light with the release of WordPress 2.1, but circumstances exist in older WP versions that would trigger these issues in some plugins.
The plugins are doing this:
- A plugin inserts a special form field into the post edit form
- The plugin monitors the form field by hooking into
edit_post
- When the form value is empty or doesn’t exist, the plugin assumes the user deleted what was in it, and procedes to delete all the custom values the plugin had stored for that post
The issue occurs because the plugins assume that every time edit_post
is triggered, their inserted form field will be included in $_POST
. This isn’t the case. edit_post
is called for requests that do not originate from the post edit form and for requests that are not initiated by a privileged user. Comment submission in WordPress 2.1 is one of these cases. Editing of a post in 2.1 (and earlier versions) via XML-RPC is another case.
Plugins cannot assume that the absence of a POST field means that POST field existed in an empty state, and plugins cannot assume that all calls to edit_post
are performed by privileged users.
Here are the two things that plugins must do:
- Verify that the user performing the action is authorized to perform the action by using the
current_user_can()
function or its siblings. - Verify intention of the user and the origination of the request by embedding a hidden form field with a nonce value, along with your usual custom field.
Here is an example:
function your_form_hook() { echo '<input type="text" name="your-plugin" id="your-plugin" value="' . your_get_value() . '" /> <input type="hidden" name="your-plugin-verify-key" id="your-plugin-verify-key" value="' . wp_create_nonce('your-plugin') . '" />'; } add_action('edit_form_advanced', 'your_form_hook'); function your_edit_post_hook($post_id) { // authorization if ( !current_user_can('edit_post', $post_id) ) return $post_id; // origination and intention if ( !wp_verify_nonce($_POST['your-plugin-verify-key'], 'your-plugin') ) return $post_id; your_update($post_id); // do the actual update here return $post_id; } add_action('edit_post', 'your_edit_post_hook');
This is a post aimed at plugin authors, so I’d appreciate it if we could save the comment space below for plugin authors who have questions about this topic. If a particular plugin you’re using is erasing Custom Fields, please contact its author directly.
Note: I’ve mentioned the edit_post
hook, but there are other similar hooks that the above also applies to. publish_post
and save_post
are two that come to mind.
Wow, well presented complex scenario!
What’s your_get_value() supposed to return?
OK, I guess your_get_value() was just an example of the plugin functionality. I thought it was part of the verification model.
Joshua,
Yes, all
your_*()
functions are user functions. For security reasons, when presenting a value in an HTMLvalue
attribute, you’d do something like runningattribute_escape()
on a postmeta value.Hi Mark,
So is there no way to pass extra form data using the XML-RPC API? I’m the author of Gengo, a multilingual plugin, and a number of people have expressed a wish to blog in multiple languages using the remote API. At the moment, because of the situation you describe above, the best I can do is set each remotely posted article as being written in the default language… Not a disaster, but not awesome… Though come to think of it, do you know of any remote authoring editors that can even send custom fields?
Anyway, nice to get official confirmation of this – thought I was going nuts!
Cheers,
Many thanks for this post! Yesterday I’ve released a tagging plugin which is based on Jerome’s Keywords (see Simple Tagging Plugin) and a user has reported about the issue of removing all tags when editing comments under WP 2.1. Now I’ve implemented your suggestion and it works like a charm 🙂
Sorry for an off-topic question, but can you please let me know which technique did you use to post the code snippet in this post? I’ve been struggling with WordPress.com’s posting thing which kills indentation, converts brackets, and does all sorts of other nasty things to code.
TIA.
Leonid,
I used <pre> and then manually encoded my entities, like &< for < and > for > See also " for " There are probably online tools that can do this for you.
Mark,
thanks. I think I’ll stay with editor screenshots for my WordPress Bits for a little while longer. It’s ugly, but it works. 🙂
Привет.
Продаю персональный сертификат WebMoney за $99.
Можете проверить: WMID 322973398779 Redfern
Всё чисто, не одной жалоб. Сделан на утерянные документы. Всё законно.
Если нужно, то есть сертификаты ещё.
Стучацо в личную почту на Вебмани.
Это не спам. Не пишите на мой WMID жалобы в арбитраж Вебмани.
Привет.
Продаю персональный сертификат WebMoney за $99.
Можете проверить: WMID 322973398779 Redfern
Всё чисто, не одной жалоб. Сделан на утерянные документы. Всё законно.
Если нужно, то есть сертификаты ещё.
Стучацо в личную почту на Вебмани.
Это не спам. Не пишите на мой WMID жалобы в арбитраж Вебмани.
Sorry 😦
Very interesting Read Mark, thanks.
Hii sir, this time i’m used blogspot to make some article, and now i would like to make article with wordpress platform. I search with google and i found this site. thanks for your info about wordpress. I think can add my knowledge about this platform
Thanks a lot, that was exactly what I needed! Worked out of the box.
Ha jol látom itt mindent lehet írni a keresorol, tudakozorol
Thank you very much! Just what I needed to keep my custom data from disappearing. 🙂
thank you for sharing thanks for this post