WP Manifestindependent plugin directory
manifest / users / wcm-avatar

(WCM) Avatar WP Registry grade D+. High-severity findings · 2 findingsWP RegistryHigh-severity findings · 2 findingsOpen the reportD+

A WordPress plugin to enable custom attachment uploads to be used as user avatars

★ 5stars
3.2kcomposer installs
0.3.6latest · 11 years ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/wecodemore/wcm-avatar/archive/refs/heads/master.zip

On Packagist as wcm/avatar:

composer require wcm/avatar
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

WordPress plugin that adds an attachment uploader to a users profile page in the admin UI. Also enables adding a front end attachment uploader to a themes template.

You can find the documentation in the wiki.

Releases

12 releases.

Tag
Published
0.3.6 latest
Oct 19, 2015 11 years ago
Oct 12, 2015 11 years ago
Oct 12, 2015 11 years ago
Oct 8, 2015 11 years ago
Oct 8, 2015 11 years ago
Oct 8, 2015 11 years ago
Aug 24, 2015 11 years ago
Aug 24, 2015 11 years ago
Aug 23, 2015 11 years ago
Aug 23, 2015 11 years ago
Aug 23, 2015 11 years ago
Aug 23, 2015 11 years ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

D+ grade

Security

(WCM) Avatar 0.3.6 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
0.3.6
Findings
2
Worst severity
high
Content hash
14851d84ecb6914cc2ca2108…

Findings

  • high Subscriber+ can force-delete any Media Library attachment via nonce-only AJAX handler

    missing_capability

    Bootstrap registers wp_ajax_{$key} (default action user_avatar) to AvatarFetchDeleteAjaxService::setup. The callback calls check_ajax_referer('user_avatar_nonce') then switches on $_POST['task']. For task=destroy it runs wp_delete_attachment(absint($_POST['att_id']), true) with no current_user_can('delete_post'), no ownership check, and no verification that the attachment is the current user's avatar. wp_delete_attachment does not enforce capabilities itself; core's own wp_ajax_delete_post does. The nonce is not an auth gate: AvatarScriptsService::setup runs on admin_enqueue_scripts for hook_suffix profile.php and user-edit.php with no capability test and localizes logoUploader._ajax_nonce = wp_create_nonce('user_avatar_nonce'). Every default role can load /wp-admin/profile.php, so a Subscriber (who cannot upload_files and never sees UploadView) still receives a valid nonce, then POSTs action=user_avatar&task=destroy&att_id=1,2,3… and wipes the library (original + image sizes removed from disk, attachment posts dropped). task=fetch is the same missing-cap path and returns wp_get_attachment_image HTML, basename, dimensions, and get_edit_post_link for any att_id. No wp_ajax_nopriv, so this is logged-in only. Upstream last tagged 0.3.6 in 2015; no patch in this tree.

    src/Services/AvatarFetchDeleteAjaxService.php:41-79

    Recommendation

    Before fetch or destroy, require current_user_can('upload_files') and current_user_can('delete_post', $att_id) (or edit_user / own profile for the user who owns the avatar). Restrict att_id to get_user_meta($user_id, 'user_avatar') for the current user unless the requester can edit_users. Do not localize the AJAX nonce on profile.php for roles that cannot upload. Stop force-deleting (second arg true) unless the user can delete_post unfiltered.

  • medium Any user who can upload files can bind the new attachment as another user's avatar

    missing_capability

    AvatarAddMetaService::setup is hooked to wp_generate_attachment_metadata (all uploads, not only the profile UI). If $_REQUEST contains user_id and screen_id in {profile, user-edit} (or the html-upload browser-uploader branch), it absint()s the request user_id and calls update_user_meta($user_id, $this->key, $att_id) plus add_post_meta($att_id, 'user_id', $user_id). There is no check that the uploader is that user, can edit_user($user_id), or that the request originated on a profile screen — AvatarRegisterMetaService only *adds* those multipart fields on profile/user-edit; an Author can attach the same fields to any async-upload.php / REST media POST. Default Author/Editor have upload_files but not edit_users. Observable: victim's get_avatar() is replaced site-wide because AvatarReplacementService (pre_get_avatar, enabled by default via wcm.avatar.enable_custom_avatar) renders that attachment ID. Image defacement / impersonation, not script XSS (wp_get_attachment_image). Subscriber cannot trigger this on a default install (no upload_files).

    src/Services/AvatarAddMetaService.php:41-84

    Recommendation

    Ignore request user_id unless it equals get_current_user_id() or the current user can edit_user($user_id). Prefer the server-side profile user (IS_PROFILE_PAGE / $GLOBALS['user_id'] after core's own caps) over client-supplied REQUEST fields. Do not honor screen_id from the client as authorization.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.