Viewing 7 replies - 1 through 7 (of 7 total)
  • Thread Starter jondaley

    (@jondaley)

    Here is how I fixed one function.

    function kento_like_post_insert(){
        $postid = (int)$_POST['postid'];
        $votestatus = (int)$_POST['votestatus'];
        $userid = get_current_user_id();
        global $wpdb;
        $table = $wpdb->prefix . "kento_like_post_info";                                                                                                                                                                                              
    
        if($votestatus=="voted"){
            $wpdb->query($wpdb->prepare("DELETE FROM $table WHERE userid=%d AND postid=%d", $userid, $postid));
        }
        else if($votestatus=="notvoted"){
            $wpdb->query($wpdb->prepare("INSERT IGNORE INTO $table VALUES(%d, %d)", $postid, $userid));
        }                                                                                                                                                                                                                                             
    
        echo kento_like_post_who_voted($postid);
        echo "<div style='display:none'><span  id='has-vote-update'>".kento_like_post_has_vote($postid)."</span><div>";                                                                                                                               
    
        return true;
    }
    Thread Starter jondaley

    (@jondaley)

    Note that I fixed up some other parts that aren’t related to the exploit. The UPDATE query wasn’t valid, since your table doesn’t have a ‘count’ column, and it didn’t seem worth it to do the SELECT statement, and then decide what to do with the DELETE/INSERT statements, when you can run the DELETE and INSERT *IGNORE* (that’s the key part).

    Oh note, that I removed the id column from the table, since that also isn’t used, and just takes up space in the database. I made the unique id for the database both remaining fields, which is nice, since you don’t ever want a user to be able to vote twice on a post anyway.

    Thread Starter jondaley

    (@jondaley)

    Oops – the (int) on votestatus is bad, but it is okay to not be careful with that value, because you just check the contents of $votestatus with the if statement and not putting it into the database.

    Plugin Author PluginsPoint

    (@kentothemes)

    Many Thanks for your feedback

    Plugin Author PluginsPoint

    (@kentothemes)

    Hi jondaley!
    we have update plugin to 1.1
    Could you please take another review and give it feedback
    Many Thanks

    Thread Starter jondaley

    (@jondaley)

    That is better.

    There is a $postid = $postid, which I’m not sure what you think that is doing.

    The unused id column is still there in the database.

    Why do you hook with a nopriv ajax call, when you depend on the user being logged in?

    The basic idea of your plugin is good, and I’m using it on an active site, but I rewrote it because I didn’t need as much functionality, and made the code a lot simpler.

    Here is the javascript I use in the theme:

    jQuery('body').on('click', '.made_it > a', function(){
                            var $madeit = jQuery(this).parent();
                            jQuery.ajax({
                                    type: 'POST',
                                    url: admin_ajax_url,
                                    data: {action: "jondaley_like_post_insert", postid: $madeit.attr('postid')},
                                    success: function(data){
                                            $madeit.find('.count').html(data);
                                    }
                            });
                            return false;
                    });

    And here is the only file in the plugin directory:

    define('JONDALEY_LIKE_POST_PLUGIN_PATH', WP_PLUGIN_URL . '/' . plugin_basename( dirname(__FILE__) ) . '/' );
    
    register_activation_hook(__FILE__, jondaley_like_post_install());
    register_uninstall_hook(__FILE__, jondaley_like_post_drop());
    function jondaley_like_post_install() {
        global $wpdb;
            $sql = "CREATE TABLE IF NOT EXISTS " . $wpdb->prefix . "jondaley_like_post_info ".
                    "(UNIQUE KEY vote (postid, userid), ".
                    "postid  bigint(20) NOT NULL, ".
                    "userid  bigint(20) NOT NULL, ".
                    "like_date timestamp NOT NULL DEFAULT NOW())";
            $wpdb->query($sql);
    }
    
    function jondaley_like_post_drop() {
            if(get_option('jondaley_like_post_deletion') == 1){
                    global $wpdb;
                    $table = $wpdb->prefix . "jondaley_like_post_info";
                    $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'jondaley_like_post_info');
            }
    }
    
    function jondaley_like_post_get_vote($postid, $userid){
            $num_votes = 0;
    
            global $wpdb;
            $table = $wpdb->prefix . "jondaley_like_post_info";
    
            $results = $wpdb->get_results($wpdb->prepare("SELECT count(postid) AS count FROM $table WHERE postid=%d AND userid=%d", $postid, $userid), ARRAY_A);
            if(isset($results[0]['count']))
                    $num_votes = $results[0]['count'];
    
            return $num_votes;
    }
    
    function jondaley_like_post_get_votes($postid){
            global $wpdb;
            $table = $wpdb->prefix . "jondaley_like_post_info";
    
            $results = $wpdb->get_results($wpdb->prepare("SELECT count(postid) AS count FROM $table WHERE postid=%d", $postid), ARRAY_A);
            $count = $results[0]['count'];
            if(is_numeric($count))
                    return $count + 1;
            return 1;
    }
    
    // get avatars of 10 people who voted for this post
    function jondaley_like_post_who_voted($postid){
            global $wpdb;
            $avatars = '';
    
            $table = $wpdb->prefix . "jondaley_like_post_info";
            $result = $wpdb->get_results($wpdb->prepare("SELECT userid FROM $table WHERE postid=%d LIMIT 10", $postid), ARRAY_A);
            $total_user = $wpdb->num_rows;
            for($i=0; $i <$total_user ; $i++){
                    $avatars .= get_avatar($result[$i]['userid'], 100);
            }
            return $avatars;
    }
    
    // AJAX function, it's okay to access get_current_user_id() here
    function jondaley_like_post_insert(){
            $postid = (int)$_POST['postid'];
            if(!$postid)
                    die('Error');
    
            $userid = get_current_user_id();
        global $wpdb;
        $table = $wpdb->prefix . "jondaley_like_post_info";
    
            if(jondaley_like_post_get_vote($postid, $userid))
                    $wpdb->query($wpdb->prepare("DELETE FROM $table WHERE postid=%d AND userid=%d", $postid, $userid));
            else
                    $wpdb->query($wpdb->prepare("INSERT IGNORE INTO $table (postid, userid) VALUES(%d, %d)", $postid, $userid));
            print jondaley_like_post_get_votes($postid);
            die;
    }
    add_action('wp_ajax_jondaley_like_post_insert', 'jondaley_like_post_insert');

    So, you can see, a lot of it is the same (I don’t use the avatar, so I haven’t checked that).

    I did add a time field, because I need to be able to sort the likes by date, and show the most recent likes on the home page.

    Plugin Author PluginsPoint

    (@kentothemes)

    Great Thanks for your feedback
    id column could be used for sorting liker thumbnail ascending or descending order

    Adding date is appreciate and will added next version

    may be mistakenly omit $postid = (int)$postid; intended to verify is integer or not.

    Anyway i will for follow your helpful advice and implement next version

    Could you please change your star rate on current update.

    Best Wish for you.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘SQL exploit’ is closed to new replies.