Title: Secure my plugin
Last modified: November 13, 2019

---

# Secure my plugin

 *  Resolved [mortenamdk](https://wordpress.org/support/users/mortenamdk/)
 * (@mortenamdk)
 * [6 years, 7 months ago](https://wordpress.org/support/topic/secure-my-plugin/)
 * Hi there
 * I have some questions about nonce function.
    How do I make that, and how do I
   best secure I best the plugin.
 * Have made a plugin to make a top banner, where I have a insert update delete 
   function in ajax.
 * I have made my database like this:
 *     ```
       id int(10) unsigned NOT NULL AUTO_INCREMENT,
                 (hidden)_top_banner_name varchar(255) NOT NULL,
                 (hidden)_top_banner_name_color varchar(20) NOT NULL,
                 (hidden)_top_banner_name_top_height varchar(10) NOT NULL,
                 (hidden)_top_banner_name_top_text_line varchar(3) NOT NULL,
                 (hidden)_top_banner_name_top_start_date varchar(10) NOT NULL,
                 (hidden)_top_banner_name_top_stop_date varchar(10) NOT NULL,
                 (hidden)_top_banner_name_media varchar(255) NOT NULL,
                 (hidden)_image_attachment_id int(10) NOT NULL,
                 PRIMARY KEY  (<code>id</code>)
       ```
   
 * So there is no possibility of too many characters, but have i am not so good 
   to it, it is my first plugin i have made.
 * Here is some code to se my ajax handler:
 *     ```
       function ajax_(hidden)_insert_top_banner() {
   
           // The $_REQUEST contains all the data sent via ajax
           global $wpdb;
             $table_name = $wpdb->prefix . "topbanner";
           if ( isset($_REQUEST) ) {
   
               $(hidden)_top_banner_name                  = wp_kses_post($_REQUEST['(hidden)_top_banner_name']);
               $(hidden)_top_banner_name_color            = sanitize_hex_color($_REQUEST['(hidden)_top_banner_name_color']);
               $(hidden)_top_banner_name_top_text_line    = sanitize_text_field($_REQUEST['(hidden)_top_banner_name_top_text_line']);
               $(hidden)_top_banner_name_top_height       = sanitize_text_field($_REQUEST['(hidden)_top_banner_name_top_height']);
               $(hidden)_top_banner_name_top_start_date   = sanitize_text_field($_REQUEST['(hidden)_top_banner_name_top_start_date']);
               $(hidden)_top_banner_name_top_stop_date    = sanitize_text_field($_REQUEST['(hidden)_top_banner_name_top_stop_date']);
               $(hidden)_top_banner_name_media            = sanitize_text_field($_REQUEST['(hidden)_top_banner_name_media']);
               $(hidden)_image_attachment_id              = sanitize_text_field($_REQUEST['(hidden)_image_attachment_id']);
   
           $wpdb->query($wpdb->prepare(
           	"
           		INSERT INTO $table_name
                   ( (hidden)_top_banner_name, (hidden)_top_banner_name_color, (hidden)_top_banner_name_top_text_line, (hidden)_top_banner_name_top_height, (hidden)_top_banner_name_top_start_date, (hidden)_top_banner_name_top_stop_date, (hidden)_top_banner_name_media, (hidden)_image_attachment_id )
           		VALUES ( %s, %s, %s, %s, %s, %s, %s, %d )
           	",
               array(
                   $(hidden)_top_banner_name,
                   $(hidden)_top_banner_name_color,
                   $(hidden)_top_banner_name_top_text_line,
                   $(hidden)_top_banner_name_top_height,
                   $(hidden)_top_banner_name_top_start_date,
                   $(hidden)_top_banner_name_top_stop_date,
                   $(hidden)_top_banner_name_media,
                   $(hidden)_image_attachment_id
                   )
           )
   
           );
           }
   
           // Always die in functions echoing ajax content
          die();
       }
   
       add_action( 'wp_ajax_ajax_(hidden)_insert_top_banner', 'ajax_(hidden)_insert_top_banner' );
       ```
   
 * And here is the js:
 *     ```
       (function($) {
        $(document).on('click', '#insert_submit', function (e) {
          e.preventDefault();
              // We'll pass this variable to the PHP function example_ajax_request
              var (hidden)_top_banner_name = tinymce.get('(hidden)_top_banner_name').getContent();
              var (hidden)_top_banner_name_color = $('#(hidden)_top_banner_name_color').val();
              var (hidden)_top_banner_name_top_text_line = $('#(hidden)_top_banner_name_top_text_line').val();
              var (hidden)_top_banner_name_top_height = $('#(hidden)_top_banner_name_top_height').val();
              var (hidden)_top_banner_name_top_start_date = $('#(hidden)_top_banner_name_top_start_date').val();
              var (hidden)_top_banner_name_top_stop_date = $('#(hidden)_top_banner_name_top_stop_date').val();
              var (hidden)_top_banner_name_media = $('#(hidden)_top_banner_name_media').val();
              var (hidden)_image_attachment_id = $('#(hidden)_image_attachment_id').val();
              // This does the ajax request
              $.ajax({
                  url: (hidden)_ajax_obj.ajaxurl, // or example_ajax_obj.ajaxurl if using on frontend
                  data: {
                      'action': 'ajax_(hidden)_insert_top_banner',
                      '(hidden)_top_banner_name' : (hidden)_top_banner_name,
                      '(hidden)_top_banner_name_color' : (hidden)_top_banner_name_color,
                      '(hidden)_top_banner_name_top_text_line' : (hidden)_top_banner_name_top_text_line,
                      '(hidden)_top_banner_name_top_height' : (hidden)_top_banner_name_top_height,
                      '(hidden)_top_banner_name_top_start_date' : (hidden)_top_banner_name_top_start_date,
                      '(hidden)_top_banner_name_top_stop_date' : (hidden)_top_banner_name_top_stop_date,
                      '(hidden)_top_banner_name_media' : (hidden)_top_banner_name_media,
                      '(hidden)_image_attachment_id' : (hidden)_image_attachment_id,
                  },
                  success:function(data) {
                      // This outputs the result of the ajax request
                      console.log(data);
                  },
                  complete:function(data){
                      location.reload();
                  },
                  error: function(errorThrown){
                      console.log(errorThrown);
                  }
              });
   
          });
   
       })(jQuery);
       ```
   
 *     ```
       	wp_enqueue_script(
       		'(hidden)-ajax-script',
       		plugin_dir_url( __FILE__ ) . '/js/ajax_insert.js',
       		array('jquery')
       	);
       	// The wp_localize_script allows us to output the ajax_url path for our script to use.
       	wp_localize_script(
       		'(hidden)-ajax-script',
       		'(hidden)_ajax_obj',
       		array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) )
       	);
       ```
   
 * Best regards
    Morten
 * The page I need help with: _[[log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fwordpress.org%2Fsupport%2Ftopic%2Fsecure-my-plugin%2F%3Foutput_format%3Dmd&locale=en_US)
   to see the link]_

Viewing 3 replies - 1 through 3 (of 3 total)

 *  Moderator [Tellyworth](https://wordpress.org/support/users/tellyworth/)
 * (@tellyworth)
 * [6 years, 7 months ago](https://wordpress.org/support/topic/secure-my-plugin/#post-12130008)
 * This explains how to create a nonce and pass it to Javascript via `wp_localize_script()`:
 * [https://developer.wordpress.org/plugins/javascript/enqueuing/#nonce](https://developer.wordpress.org/plugins/javascript/enqueuing/#nonce)
 * Read the following sections also about Localize, Ajax Action and so on.
 * Also, it’s generally better to avoid creating a custom SQL table, and instead
   store your data in postmeta, custom post types, or options. WordPress already
   has built in post types for attachments that might suit your needs. You’ll find
   those things well documented in the [Plugin Handbook](https://developer.wordpress.org/plugins/).
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [6 years, 7 months ago](https://wordpress.org/support/topic/secure-my-plugin/#post-12134275)
 * Tellyworth’s link is a good reference (disclaimer: I contributed to the writing
   of the linked Ajax pages 🙂 ) There is an important note that covers those pages
   that kinda got lost on a different page:
 * > Note: This code snippet, and all examples on this page, are for illustrating
   > the use of AJAX. The code is not suitable for production environments because
   > related operations such as sanitization, security, error handling, and internationalization
   > have been intentionally omitted. Be sure to always address these important 
   > operations in your production code.
 * Checking the nonce and Ajax referrer is covered in the examples. When the DB 
   is being updated by handler code, you should likely be also verifying user capability.
   For example:
 *     ```
       if ( ! current_user_can('manage_options')) { echo 'Error. You do not have adequate user capability to do this'; exit; }
       //proceed with update
       ```
   
 * Sanitation and validation is broad topic as the solution depends on the nature
   of the data. See [https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress–wp-25536](https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress–wp-25536)
 * A little off topic, but I agree that the meta tables are generally preferable
   to a custom SQL table. Up to a point. If you are frequently making queries that
   involve complex meta data relationships which involve large amounts of data, 
   WP meta queries can be slow and inefficient and a custom table may be justified
   for efficiency and speed reasons.
 *  Thread Starter [mortenamdk](https://wordpress.org/support/users/mortenamdk/)
 * (@mortenamdk)
 * [6 years, 7 months ago](https://wordpress.org/support/topic/secure-my-plugin/#post-12134422)
 * Hello you two
 * Thanks for the answers, it helps me well on my way.
    And thank you bcworkz, for
   all that work in getting me on the right track with my project. I will at least
   do what I can to get the plugin secure with your help.
 * Thanks for now 🙂
 * Best regards
    Morten

Viewing 3 replies - 1 through 3 (of 3 total)

The topic ‘Secure my plugin’ is closed to new replies.

 * In: [Developing with WordPress](https://wordpress.org/support/forum/wp-advanced/)
 * 3 replies
 * 3 participants
 * Last reply from: [mortenamdk](https://wordpress.org/support/users/mortenamdk/)
 * Last activity: [6 years, 7 months ago](https://wordpress.org/support/topic/secure-my-plugin/#post-12134422)
 * Status: resolved

## Topics

### Topics with no replies

### Non-support topics

### Resolved topics

### Unresolved topics

### All topics
