--- a/add-custom-codes/add-custom-codes.php
+++ b/add-custom-codes/add-custom-codes.php
@@ -2,23 +2,17 @@
/**
* Plugin Name: Add Custom Codes - Insert Header, Footer, Custom Code Snippets
* Description: Light-weight plugin to add Custom PHP Functions, HTML, CSS, Javascript, Google Analytics, Search console verification tags and other custom code snippets to your Wordpress website.
- * Version: 4.80
+ * Version: 5.0
* Author: Saifudheen Mak
* Author URI: https://maktalseo.com
* License: GPL2
* Text Domain: add-custom-codes
*/
-// If this file was called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
-
- add_action( 'init', 'accodes_load_textdomain' );
-function accodes_load_textdomain() {
- load_plugin_textdomain( 'add-custom-codes', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
-}
-
+
/*----------------
plugin links 'Plugins' page
------------------*/
@@ -26,7 +20,7 @@
function accodes_action_links ( $actions ) {
$mylinks = array(
- '<a href="' . admin_url( 'edit.php?post_type=accodes_snippets&page=accodes-about' ) . '">Donate us</a>',
+ '<a href="' . esc_url( admin_url( 'edit.php?post_type=accodes_snippets&page=accodes-about' ) ) . '">Donate us</a>',
);
$actions = array_merge( $actions, $mylinks );
return $actions;
@@ -72,7 +66,7 @@
wp_register_style( 'accodes-css', plugins_url( 'add-custom-codes/assets/css/style43.css' ), '', '4.259' );
wp_enqueue_style( 'accodes-css' );
- wp_register_script('accodes-js', plugins_url('add-custom-codes/assets/js/scripts.js'), ['jquery', 'jquery-ui-autocomplete'], '4.79', true);
+ wp_register_script('accodes-js', plugins_url('add-custom-codes/assets/js/scripts.js'), ['jquery', 'jquery-ui-autocomplete'], '4.82', true);
wp_enqueue_script( 'accodes-js' );
// Fetch tags for autocomplete
@@ -106,7 +100,7 @@
function accodes_settings_page() {
- if (!current_user_can('administrator')) {
+ if (!current_user_can('manage_options')) {
wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'add-custom-codes'));
}
@@ -174,7 +168,7 @@
/*----------------
functions
---------------*/
-function get_current_page_id()
+function accodes_get_current_page_id()
{
global $post;
$current_page_id = false;
@@ -190,20 +184,20 @@
return $current_page_id;
}
-function get_current_taxonomy_id() {
- if (is_tax() || is_category() || is_tag()) {
- $term = get_queried_object();
- if (!empty($term) && !is_wp_error($term)) {
- return $term->term_id;
- }
- }
- return false;
+function accodes_get_current_taxonomy_id() {
+ if (is_tax() || is_category() || is_tag()) {
+ $term = get_queried_object();
+ if (!empty($term) && !is_wp_error($term)) {
+ return $term->term_id;
+ }
+ }
+ return false;
}
/*---------------------------------
output Global CSS
----------------*/
-function get_global_custom_css()
+function accodes_get_global_custom_css()
{
$accodes_global_css = '';
$options = get_option( 'custom-css-codes-input' );
@@ -215,19 +209,22 @@
}
-add_action( 'wp_head', 'accodes_css_output_header' );
function accodes_css_output_header() {
//check if global css to be added before footer
$css_on_footer = (bool) get_option('accodes_global_css_on_footer', false);
//put css in footer not ticked
if(!$css_on_footer)
{
- $accodes_global_css = get_global_custom_css();
- //escape
- echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css"> '.wp_strip_all_tags($accodes_global_css).' </style> <!-- End - Global CSS by Add Custom Codes -->';
+ $accodes_global_css = accodes_get_global_custom_css();
+ // Intentionally output admin-provided CSS without HTML-encoding so quotes stay intact.
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided CSS.
+ echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css">'. PHP_EOL . $accodes_global_css . PHP_EOL . '</style> <!-- End - Global CSS by Add Custom Codes -->';
}
}
+// Hook global CSS output into the head
+add_action( 'wp_head', 'accodes_css_output_header' );
+
add_action( 'wp_footer', 'accodes_css_output_footer' );
function accodes_css_output_footer() {
//check if global css to be added before footer
@@ -235,9 +232,10 @@
//put css in footer ticked
if($css_on_footer)
{
- $accodes_global_css = get_global_custom_css();
- //escape
- echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css"> '.wp_strip_all_tags($accodes_global_css).' </style> <!-- End - Global CSS by Add Custom Codes -->';
+ $accodes_global_css = accodes_get_global_custom_css();
+ // Intentionally output admin-provided CSS without HTML-encoding so quotes stay intact.
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided CSS.
+ echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css">'. PHP_EOL . $accodes_global_css . PHP_EOL . '</style> <!-- End - Global CSS by Add Custom Codes -->';
}
}
@@ -248,8 +246,8 @@
function accodes_header_output() {
$hide_global_header = '';
- $current_page_id = get_current_page_id();
- $current_taxonomy_id = get_current_taxonomy_id();
+ $current_page_id = accodes_get_current_page_id();
+ $current_taxonomy_id = accodes_get_current_taxonomy_id();
$global_header_codes ='';
$get_single_header_codes = '';
$single_header_codes = '';
@@ -306,7 +304,7 @@
if($output !='')
{
- //escape
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided header codes.
echo $output;
}
@@ -321,8 +319,8 @@
function accodes_footer_output() {
$hide_global_footer = '';
- $current_page_id = get_current_page_id();
- $current_taxonomy_id = get_current_taxonomy_id();
+ $current_page_id = accodes_get_current_page_id();
+ $current_taxonomy_id = accodes_get_current_taxonomy_id();
$global_footer_codes ='';
$single_footer_codes = '';
$taxonomy_footer_codes = '';
@@ -373,7 +371,7 @@
if($output !='')
{
- //escape
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided footer codes.
echo $output;
}
@@ -385,34 +383,39 @@
* Individual pages
* Create the meta boxes for Single post, page, product any other custom post type
------------------------------------*/
-function _accodes_create_metabox_single() {
+function accodes_create_metabox_single() {
$post_types = get_post_types( '', 'names' );
$post_types = array_merge( $post_types, array( 'post', 'page' ) );
+ $can_code = current_user_can('unfiltered_html') || current_user_can('manage_options');
+
foreach ( $post_types as $post_type ) {
if ($post_type === 'accodes_snippets') {
continue;
}
+ if (!$can_code) {
+ continue;
+ }
add_meta_box(
- '_accodes_metabox',
- 'Add Custom Codes by Mak',
- '_accodes_render_metabox',
- $post_type,
- 'normal',
- 'default'
- );
+ '_accodes_metabox',
+ 'Add Custom Codes by Mak',
+ 'accodes_render_metabox',
+ $post_type,
+ 'normal',
+ 'default'
+ );
}
}
-add_action( 'add_meta_boxes', '_accodes_create_metabox_single' );
+add_action( 'add_meta_boxes', 'accodes_create_metabox_single' );
/*-------------------------------
* Display Meta Boxes for Single
* ----------------------------*/
-function _accodes_render_metabox() {
+function accodes_render_metabox() {
// Variables
global $post; // Get the current post data
$header_script = get_post_meta( $post->ID, '_accodes_header_metabox', true ); // Get the saved values
@@ -429,13 +432,14 @@
/*-------------------------
* update data on post save - Single
---------------------------*/
-function _accodes_save_metabox_single( $post_id, $post ) {
+function accodes_save_metabox_single( $post_id, $post ) {
// Verify nonce for security
- if ( !isset($_POST['accodes_meta_nonce']) || !wp_verify_nonce($_POST['accodes_meta_nonce'], 'accodes_save_meta') ) {
- return $post_id;
- }
+ $acc_meta_nonce = isset($_POST['accodes_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_meta_nonce']) ) : '';
+ if ( !$acc_meta_nonce || !wp_verify_nonce($acc_meta_nonce, 'accodes_save_meta') ) {
+ return $post_id;
+ }
// Verify user has permission to edit post
if ( !current_user_can( 'edit_post', $post->ID )) {
@@ -458,18 +462,36 @@
- $allowed_html = [
- 'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
- 'style' => ['type' => []],
- 'meta' => ['name' => [], 'content' => [], 'charset' => []],
- 'link' => ['rel' => [], 'href' => [], 'type' => []],
- 'div' => ['class' => [], 'id' => [], 'style' => []],
- 'span' => ['class' => [], 'style' => []],
- 'p' => ['class' => [], 'style' => []],
- 'a' => ['href' => [], 'title' => [], 'target' => []],
- 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
- 'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
- ];
+ $privileged = current_user_can('unfiltered_html') || current_user_can('manage_options');
+ if ($privileged) {
+ $allowed_html = [
+ 'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
+ 'style' => ['type' => []],
+ 'meta' => ['name' => [], 'content' => [], 'charset' => []],
+ 'link' => ['rel' => [], 'href' => [], 'type' => []],
+ 'div' => ['class' => [], 'id' => [], 'style' => []],
+ 'span' => ['class' => [], 'style' => []],
+ 'p' => ['class' => [], 'style' => []],
+ 'a' => ['href' => [], 'title' => [], 'target' => []],
+ 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+ 'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
+ ];
+ } else {
+ // Restrictive for non-privileged users (no scripts/styles/iframes/meta/link)
+ $allowed_html = [
+ 'div' => ['class' => [], 'id' => [], 'style' => []],
+ 'span' => ['class' => [], 'style' => []],
+ 'p' => ['class' => [], 'style' => []],
+ 'a' => ['href' => [], 'title' => [], 'target' => []],
+ 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+ 'ul' => ['class' => [], 'style' => []],
+ 'ol' => ['class' => [], 'style' => []],
+ 'li' => ['class' => [], 'style' => []],
+ 'strong' => [],
+ 'em' => [],
+ 'br' => [],
+ ];
+ }
@@ -494,26 +516,28 @@
update_post_meta( $post->ID, 'accodes_hide_footer', $hide_footer );
}
-add_action( 'save_post', '_accodes_save_metabox_single', 10, 2 );
+add_action( 'save_post', 'accodes_save_metabox_single', 10, 2 );
/*
* single meta end
* -----------------------------------------------*/
-function get_current_term_id() {
- if (isset($_GET['tag_ID'])) {
- return intval($_GET['tag_ID']);
- }
- return 0;
+function accodes_get_current_term_id() {
+ // Prefer queried term object over direct access to $_GET['tag_ID']
+ $term = get_queried_object();
+ return ( $term && isset( $term->term_id ) ) ? absint( $term->term_id ) : 0;
}
// Register meta box
function accodes_render_taxonomy_meta_box() {
$taxonomies = get_taxonomies();
foreach ($taxonomies as $taxonomy) {
- add_action("{$taxonomy}_edit_form", function($tag) use ($taxonomy) {
- $term_id = get_current_term_id();
+ add_action("{$taxonomy}_edit_form", function($tag) use ($taxonomy) {
+ if (!current_user_can('unfiltered_html') && !current_user_can('manage_options')) {
+ return;
+ }
+ $term_id = isset($tag->term_id) ? (int) $tag->term_id : 0;
$header_script = get_term_meta( $term_id, '_accodes_header_metabox', true );
$footer_script = get_term_meta( $term_id, '_accodes_footer_metabox', true );
$hide_header = get_term_meta( $term_id, 'accodes_hide_header', true );
@@ -529,22 +553,44 @@
function accodes_save_taxonomy_meta_data($term_id) {
// Verify nonce for security
- if (!isset($_POST['accodes_tax_meta_nonce']) || !wp_verify_nonce($_POST['accodes_tax_meta_nonce'], 'accodes_save_tax_meta')) {
- return $term_id;
- }
-
- $allowed_html = [
- 'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
- 'style' => ['type' => []],
- 'meta' => ['name' => [], 'content' => [], 'charset' => []],
- 'link' => ['rel' => [], 'href' => [], 'type' => []],
- 'div' => ['class' => [], 'id' => [], 'style' => []],
- 'span' => ['class' => [], 'style' => []],
- 'p' => ['class' => [], 'style' => []],
- 'a' => ['href' => [], 'title' => [], 'target' => []],
- 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
- 'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
- ];
+ $tax_meta_nonce = isset($_POST['accodes_tax_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_tax_meta_nonce']) ) : '';
+ if (!$tax_meta_nonce || !wp_verify_nonce($tax_meta_nonce, 'accodes_save_tax_meta')) {
+ return $term_id;
+ }
+
+ if (!current_user_can('edit_term', $term_id)) {
+ return $term_id;
+ }
+
+ $privileged = current_user_can('unfiltered_html') || current_user_can('manage_options');
+ if ($privileged) {
+ $allowed_html = [
+ 'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
+ 'style' => ['type' => []],
+ 'meta' => ['name' => [], 'content' => [], 'charset' => []],
+ 'link' => ['rel' => [], 'href' => [], 'type' => []],
+ 'div' => ['class' => [], 'id' => [], 'style' => []],
+ 'span' => ['class' => [], 'style' => []],
+ 'p' => ['class' => [], 'style' => []],
+ 'a' => ['href' => [], 'title' => [], 'target' => []],
+ 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+ 'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
+ ];
+ } else {
+ $allowed_html = [
+ 'div' => ['class' => [], 'id' => [], 'style' => []],
+ 'span' => ['class' => [], 'style' => []],
+ 'p' => ['class' => [], 'style' => []],
+ 'a' => ['href' => [], 'title' => [], 'target' => []],
+ 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+ 'ul' => ['class' => [], 'style' => []],
+ 'ol' => ['class' => [], 'style' => []],
+ 'li' => ['class' => [], 'style' => []],
+ 'strong' => [],
+ 'em' => [],
+ 'br' => [],
+ ];
+ }
//get value of meta boxes
--- a/add-custom-codes/custom-snippets.php
+++ b/add-custom-codes/custom-snippets.php
@@ -1,4 +1,9 @@
<?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
//Register post type
function accodes_register_snippets_cpt() {
register_post_type('accodes_snippets', array(
@@ -19,8 +24,25 @@
),
'public' => false,
'show_ui' => true,
- 'show_in_menu' => true,
+ 'show_in_menu' => true,
+ // Restrict management of snippets to administrators (or roles with manage_options)
'capability_type' => 'post',
+ 'capabilities' => array(
+ 'edit_post' => 'manage_options',
+ 'read_post' => 'manage_options',
+ 'delete_post' => 'manage_options',
+ 'edit_posts' => 'manage_options',
+ 'edit_others_posts' => 'manage_options',
+ 'publish_posts' => 'manage_options',
+ 'read_private_posts' => 'manage_options',
+ 'create_posts' => 'manage_options',
+ 'delete_posts' => 'manage_options',
+ 'delete_private_posts' => 'manage_options',
+ 'delete_published_posts' => 'manage_options',
+ 'delete_others_posts' => 'manage_options',
+ 'edit_private_posts' => 'manage_options',
+ 'edit_published_posts' => 'manage_options',
+ ),
'supports' => array('title'),
'menu_icon' => plugins_url('add-custom-codes/assets/images/accodes-menu-icon.svg'),
'menu_position' => 60,
@@ -128,7 +150,7 @@
if ($active === '0' && $post->post_status !== 'publish') {
$active = '1';
}
- $notes = get_post_meta($post->ID, '_accodes_snippet_notes', true);
+ $notes = get_post_meta($post->ID, '_accodes_snippet_notes', true);
$tags_raw = get_post_meta($post->ID, '_accodes_snippet_tags', true);
$tags_array = $tags_raw ? explode(',', $tags_raw) : [];
@@ -148,8 +170,29 @@
</script>";
}
+ // Provide safe default templates only when empty
+ if (trim((string) $content) === '') {
+ switch ($language) {
+ case 'javascript':
+ $content = '/* Add your scripts here. You can remove example code */' . "n" . 'console.log("code loaded.");' . "n";
+ break;
+ case 'css':
+ $content = '/* Your CSS here */' . "n" . '.selector {' . "ntn}" . "n";
+ break;
+ case 'htmlmixed':
+ $content = '<!-- Add your HTML here. You can remove example code-->' . "n" . '<div></div>' . "n";
+ break;
+ case 'php':
+ default:
+ // No explicit PHP open/close tags; runner evaluates raw PHP body.
+ $content = '// Your PHP here' . "n";
+ break;
+ }
+ }
+
?>
<div class="postbox accodes-meta-wrapper">
+ <?php wp_nonce_field('accodes_save_snippet_meta', 'accodes_snippet_meta_nonce'); ?>
<div class="accodes-group above-accodes-tab">
<div class="accodes-group accodes-theme-toggle" style="display: flex; justify-content: flex-end; align-items: center;">
<label class="accodes-switch">
@@ -260,48 +303,100 @@
add_action('save_post', function ($post_id) {
if (get_post_type($post_id) !== 'accodes_snippets') return;
- $code = $_POST['accodes_code_editor'] ?? '';
- $language = $_POST['accodes_snippet_language'] ?? '';
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
+ if (wp_is_post_revision($post_id)) return;
+
+ $nonce = isset($_POST['accodes_snippet_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_meta_nonce']) ) : '';
+ if (!$nonce || !wp_verify_nonce( $nonce, 'accodes_save_snippet_meta')) return;
+ if (!current_user_can('edit_post', $post_id)) return;
+
+ // Raw code is stored by design; validated on execution and escaped on output where applicable.
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+ $code = isset($_POST['accodes_code_editor']) ? wp_unslash($_POST['accodes_code_editor']) : '';
+ $language = isset($_POST['accodes_snippet_language']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_language']) ) : '';
$active = isset($_POST['accodes_snippet_active']) ? '1' : '0';
// Save core meta
- update_post_meta($post_id, '_accodes_code', wp_unslash($code));
- update_post_meta($post_id, '_accodes_snippet_language', sanitize_text_field($language));
- update_post_meta($post_id, '_accodes_snippet_location', sanitize_text_field($_POST['accodes_snippet_location'] ?? ''));
- update_post_meta($post_id, '_accodes_snippet_notes', sanitize_textarea_field($_POST['accodes_snippet_notes'] ?? ''));
+ update_post_meta($post_id, '_accodes_code', $code);
+ update_post_meta($post_id, '_accodes_snippet_language', $language);
+ $location = isset($_POST['accodes_snippet_location']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_location']) ) : '';
+ $notes = isset($_POST['accodes_snippet_notes']) ? sanitize_textarea_field( wp_unslash($_POST['accodes_snippet_notes']) ) : '';
+ update_post_meta($post_id, '_accodes_snippet_location', $location);
+ update_post_meta($post_id, '_accodes_snippet_notes', $notes);
update_post_meta($post_id, '_accodes_snippet_active', $active);
// Save tags
- if (isset($_POST['accodes_tags']) && is_array($_POST['accodes_tags'])) {
- $tags = array_map('sanitize_text_field', $_POST['accodes_tags']);
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Collected then sanitized per-item below
+ $raw_tags_input = isset($_POST['accodes_tags']) ? wp_unslash($_POST['accodes_tags']) : null;
+ if (is_array($raw_tags_input)) {
+ $raw_tags = array_map('strval', $raw_tags_input);
+ $tags = array_map('sanitize_text_field', $raw_tags);
wp_set_post_terms($post_id, $tags, 'accodes_tag');
}
if ($language === 'php') {
delete_post_meta($post_id, '_accodes_snippet_error'); // clear old errors
}
+ // Clear cached snippet lists for all locations when a snippet is saved.
+ if ( function_exists( 'set_transient' ) ) {
+ $locations = [ 'site', 'admin', 'frontend', 'shortcode', 'head', 'footer' ];
+ foreach ( $locations as $loc ) {
+ delete_transient( 'accodes_snippet_ids_' . md5( (string) $loc ) );
+ }
+ }
});
function accodes_inject_snippets($location) {
- $args = [
- 'post_type' => 'accodes_snippets',
- 'post_status' => 'publish',
- 'posts_per_page' => -1,
- 'meta_query' => [
- [
- 'key' => '_accodes_snippet_active',
- 'value' => '1',
+ // Use a short-lived transient to cache snippet IDs per location and avoid expensive meta_query on every request.
+ $cache_key = 'accodes_snippet_ids_' . md5( (string) $location );
+ $ids = get_transient( $cache_key );
+ if ( false === $ids ) {
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Results are cached in a transient to avoid running this meta_query on every request.
+ $query_args = [
+ 'post_type' => 'accodes_snippets',
+ 'post_status' => 'publish',
+ 'posts_per_page' => -1,
+ 'fields' => 'ids', // only IDs to keep the query light
+ 'no_found_rows' => true,
+ 'meta_query' => [
+ [
+ 'key' => '_accodes_snippet_active',
+ 'value' => '1',
+ ],
+ [
+ 'key' => '_accodes_snippet_location',
+ 'value' => $location,
+ ],
],
- [
- 'key' => '_accodes_snippet_location',
- 'value' => $location,
- ]
- ],
- ];
+ ];
- $snippets = get_posts($args);
+ $ids = get_posts( $query_args );
+ if ( ! is_array( $ids ) ) {
+ $ids = [];
+ }
+ // Cache for 5 minutes
+ set_transient( $cache_key, $ids, 5 * MINUTE_IN_SECONDS );
+ }
+
+ if ( empty( $ids ) ) {
+ return;
+ }
+
+ // Fetch posts by IDs preserving order
+ $snippets = get_posts([
+ 'post_type' => 'accodes_snippets',
+ 'post_status' => 'publish',
+ 'posts_per_page' => count( $ids ),
+ 'post__in' => $ids,
+ 'orderby' => 'post__in',
+ 'no_found_rows' => true,
+ ]);
foreach ($snippets as $snippet) {
+ // Only run snippets created by users with administrative capability
+ if (!user_can((int) $snippet->post_author, 'manage_options')) {
+ continue;
+ }
$language = get_post_meta($snippet->ID, '_accodes_snippet_language', true);
$code = get_post_meta($snippet->ID, '_accodes_code', true);
@@ -312,9 +407,10 @@
if (!is_admin()) {
$cleaned = preg_replace('/^s*<?(php)?/', '', trim($code));
try {
- eval($cleaned);
- delete_post_meta($snippet->ID, '_accodes_snippet_error'); // clear old errors
- } catch (Throwable $e) {
+ // phpcs:ignore WordPress.Security.EvalDetected -- Intentionally executing admin-authored PHP snippets; access is restricted to administrators (snippet authors must have 'manage_options').
+ eval( $cleaned );
+ delete_post_meta( $snippet->ID, '_accodes_snippet_error' ); // clear old errors
+ } catch ( Throwable $e ) {
// Auto-deactivate the snippet
update_post_meta($snippet->ID, '_accodes_snippet_active', '0');
// Log error
@@ -328,15 +424,19 @@
break;
case 'css':
- echo "<style>n" . trim($code) . "n</style>n";
+ // Intentionally output admin-authored CSS without HTML-encoding so quotes stay intact.
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored CSS; restricted to manage_options.
+ echo "<style>n" . trim( (string) $code ) . "n</style>n";
break;
case 'javascript':
- echo "<script>n" . trim($code) . "n</script>n";
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored JS for a code injection plugin; restricted to manage_options.
+ echo "<script>n" . trim( (string) $code ) . "n</script>n";
break;
case 'htmlmixed':
default:
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored HTML; restricted to manage_options and sanitized for non-privileged.
echo $code;
break;
}
@@ -377,7 +477,7 @@
break;
}
- echo $badge;
+ echo wp_kses( $badge, [ 'span' => [ 'class' => [] ] ] );
}
if ($column === 'accodes_health') {
$error = get_post_meta($post_id, '_accodes_snippet_error', true);
@@ -389,10 +489,10 @@
}
if ($column === 'accodes_status') {
$active = get_post_meta($post_id, '_accodes_snippet_active', true);
- $checked = $active == '1' ? 'checked' : '';
+ $is_checked = ($active === '1');
echo '
<label class="accodes-switch">
- <input type="checkbox" data-id="' . $post_id . '" class="accodes-toggle-snippet" ' . $checked . '>
+ <input type="checkbox" data-id="' . esc_attr( (string) $post_id ) . '" class="accodes-toggle-snippet"' . ( $is_checked ? ' checked="checked"' : '' ) . '>
<span class="slider"></span>
</label>
';
@@ -408,10 +508,14 @@
add_action('wp_ajax_accodes_toggle_snippet_status', function () {
check_ajax_referer('accodes_toggle_snippet');
- $post_id = intval($_POST['post_id'] ?? 0);
- $active = $_POST['active'] === '1' ? '1' : '0';
+ $post_id = isset($_POST['post_id']) ? intval( wp_unslash($_POST['post_id']) ) : 0;
+ $active_raw = isset($_POST['active']) ? sanitize_text_field( wp_unslash($_POST['active']) ) : null;
+ $active = ($active_raw === '1') ? '1' : '0';
if ($post_id && get_post_type($post_id) === 'accodes_snippets') {
+ if (!current_user_can('edit_post', $post_id)) {
+ wp_send_json_error(['message' => 'Permission denied'], 403);
+ }
update_post_meta($post_id, '_accodes_snippet_active', $active);
wp_send_json_success(['status' => $active]);
}
@@ -427,6 +531,9 @@
if (!$post_id || get_post_type($post_id) !== 'accodes_snippets') return '';
+ $snippet = get_post($post_id);
+ if (!$snippet || !user_can((int) $snippet->post_author, 'manage_options')) return '';
+
$location = get_post_meta($post_id, '_accodes_snippet_location', true);
$active = get_post_meta($post_id, '_accodes_snippet_active', true);
$content = get_post_meta($post_id, '_accodes_code', true);
--- a/add-custom-codes/deactivate/deactivate.php
+++ b/add-custom-codes/deactivate/deactivate.php
@@ -1,5 +1,8 @@
<?php
-
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
add_action('admin_enqueue_scripts', 'accodes_enqueue_deactivation_feedback');
function accodes_enqueue_deactivation_feedback($hook) {
if ($hook !== 'plugins.php') {
--- a/add-custom-codes/global-form.php
+++ b/add-custom-codes/global-form.php
@@ -4,9 +4,11 @@
exit;
}
?>
-<?php if (isset($_GET['settings-updated'])) : ?>
+<?php
+// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- value comes from Settings API redirect after a verified save.
+if ( isset( $_GET['settings-updated'] ) && sanitize_text_field( wp_unslash( $_GET['settings-updated'] ) ) ) : ?>
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Changes saved! Please clear your cache if the changes are not reflected on the website.', 'add-custom-codes'); ?></p></div>
-<?php endif ?>
+<?php endif; ?>
<div class="wrap">
<h2><?php esc_html_e( 'Add Custom Codes by Mak', 'add-custom-codes' ) ?></h2>
@@ -18,21 +20,21 @@
<?php do_settings_sections( 'accodes-settings-group' ); ?>
<?php
- $global_css = "";
- $global_css = get_option('custom-css-codes-input');
+ $accodes_global_css = "";
+ $accodes_global_css = get_option('custom-css-codes-input');
?>
<p><label for="custom-css-codes-input" class="accodes-label green-label"><?php esc_html_e( 'Custom CSS (Global)', 'add-custom-codes' ) ?></label><br/>
You can add custom css (global) codes below. DO NOT INCLUDE <em><style></em> and <em></style></em> tags:</p>
- <textarea class="codemirror-accodes-css" id="custom-css-codes-input" name="custom-css-codes-input"><?php echo esc_attr( $global_css ); ?></textarea>
+ <textarea class="codemirror-accodes-css" id="custom-css-codes-input" name="custom-css-codes-input"><?php echo esc_attr( $accodes_global_css ); ?></textarea>
<?php
// $css_on_footer ='';
- $css_on_footer = get_option('accodes_global_css_on_footer', false);
+ $accodes_css_on_footer = get_option('accodes_global_css_on_footer', false);
?>
<p>
<label for="accodes_global_css_on_footer" class="accodes-checkbox-label">
- <input type="checkbox" <?php echo checked( $css_on_footer, 1, false ); ?>
- name="accodes_global_css_on_footer" id="accodes_global_css_on_footer" value="1"/>
+ <input type="checkbox" <?php echo checked( $accodes_css_on_footer, 1, false ); ?>
+ name="accodes_global_css_on_footer" id="accodes_global_css_on_footer" value="1"/>
Insert Custom CSS before <em></body></em> of website.
</label><br/>
By default, the plugin adds Custom CSS before <em></head></em> section of your website.
--- a/add-custom-codes/includes/about-accodes.php
+++ b/add-custom-codes/includes/about-accodes.php
@@ -1,3 +1,11 @@
+<?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
+?>
<div class="accodes-about-wrap">
<div class="accodes-card">
--- a/add-custom-codes/includes/import-export.php
+++ b/add-custom-codes/includes/import-export.php
@@ -1,12 +1,20 @@
<?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
// Export Snippets Handler
add_action('admin_post_accodes_export_snippets', function () {
if (!current_user_can('manage_options')) {
wp_die('Permission denied');
}
- $export_scope = $_POST['export_scope'] ?? 'all';
- $exclude_drafts = isset($_POST['exclude_drafts']);
+ check_admin_referer('accodes_export_snippets', 'accodes_export_nonce');
+
+ $export_scope = isset( $_POST['export_scope'] ) ? sanitize_text_field( wp_unslash( $_POST['export_scope'] ) ) : 'all';
+ $exclude_drafts = isset( $_POST['exclude_drafts'] );
$args = [
'post_type' => 'accodes_snippets',
@@ -57,16 +65,39 @@
wp_die('Permission denied');
}
- if (!isset($_FILES['accodes_import_file']) || $_FILES['accodes_import_file']['error'] !== UPLOAD_ERR_OK) {
- wp_redirect(admin_url('admin.php?page=accodes-import-export&import=failed'));
+ check_admin_referer('accodes_import_snippets', 'accodes_import_nonce');
+
+ // Validate uploaded file array indexes before use. Rely on the upload error index and
+ // `wp_handle_upload()` to safely move and validate the uploaded file.
+ if ( empty( $_FILES['accodes_import_file'] ) || ! isset( $_FILES['accodes_import_file']['error'] ) || $_FILES['accodes_import_file']['error'] !== UPLOAD_ERR_OK ) {
+ wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=failed') ) );
+ exit;
+ }
+
+ // Move uploaded file into WordPress uploads directory for safe handling.
+ require_once ABSPATH . 'wp-admin/includes/file.php';
+ $overrides = [
+ 'test_form' => false,
+ 'mimes' => [ 'json' => 'application/json', 'txt' => 'text/plain' ],
+ ];
+ $move = wp_handle_upload( $_FILES['accodes_import_file'], $overrides );
+ if ( isset( $move['error'] ) || empty( $move['file'] ) ) {
+ wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=failed') ) );
exit;
}
- $json = file_get_contents($_FILES['accodes_import_file']['tmp_name']);
+ $file_path = $move['file'];
+ $json = file_get_contents( $file_path );
+ // Clean up the moved file after reading.
+ if ( function_exists( 'wp_delete_file' ) ) {
+ wp_delete_file( $file_path );
+ } else {
+ @unlink( $file_path );
+ }
$snippets = json_decode($json, true);
if (!is_array($snippets)) {
- wp_redirect(admin_url('admin.php?page=accodes-import-export&import=invalid'));
+ wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=invalid') ) );
exit;
}
@@ -90,16 +121,18 @@
}
}
- wp_redirect(admin_url('admin.php?page=accodes-import-export&import=success&count=' . $imported_count));
+ wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=success&count=' . (int) $imported_count) ) );
exit;
});
function accodes_import_export_page_callback() {
- $status = $_GET['import'] ?? '';
- $count = intval($_GET['count'] ?? 0);
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- values come from redirect parameters after verified handlers
+ $status = isset( $_GET['import'] ) ? sanitize_text_field( wp_unslash( $_GET['import'] ) ) : '';
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $count = isset( $_GET['count'] ) ? intval( wp_unslash( $_GET['count'] ) ) : 0;
if ($status === 'success') {
- echo '<div class="notice notice-success is-dismissible"><p>Import completed! (' . $count . ' snippets)</p></div>';
+ echo '<div class="notice notice-success is-dismissible"><p>Import completed! (' . esc_html( (string) $count ) . ' snippets)</p></div>';
} elseif ($status === 'failed') {
echo '<div class="notice notice-error is-dismissible"><p>File upload failed. Please try again.</p></div>';
} elseif ($status === 'invalid') {
@@ -113,8 +146,9 @@
?>
<div class="accodes-export-box white-import-export">
<h2>Export Snippets</h2>
- <form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
+ <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
<input type="hidden" name="action" value="accodes_export_snippets">
+ <?php wp_nonce_field('accodes_export_snippets', 'accodes_export_nonce'); ?>
<p><strong>Which snippets to export?</strong></p>
<label><input type="radio" name="export_scope" value="all" checked> Export All Snippets</label><br>
<label><input type="radio" name="export_scope" value="active"> Export only Active Snippets</label>
@@ -125,8 +159,9 @@
<hr/>
<div class="accodes-import-box white-import-export">
<h2>Import Snippets</h2>
- <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" enctype="multipart/form-data">
+ <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="accodes_import_snippets">
+ <?php wp_nonce_field('accodes_import_snippets', 'accodes_import_nonce'); ?>
<input type="file" name="accodes_import_file" accept=".json" required>
<button class="button">Import Now</button>
</form>
--- a/add-custom-codes/taxonomy-meta.php
+++ b/add-custom-codes/taxonomy-meta.php
@@ -5,12 +5,12 @@
}
?>
-<?php $taxonomy_obj = get_taxonomy($taxonomy);
-if ($taxonomy_obj) {
- $taxonomy_name = $taxonomy_obj->labels->singular_name;
+<?php $accodes_taxonomy_obj = get_taxonomy( $taxonomy );
+if ( $accodes_taxonomy_obj ) {
+ $accodes_taxonomy_name = $accodes_taxonomy_obj->labels->singular_name;
} ?>
<div class="acc-ind-col-1 accodes-taxonomy-edit">
- <?php echo "<h4>Add custom codes to this ".esc_html($taxonomy_name)."</h4>"; ?>
+ <?php echo "<h4>Add custom codes to this ".esc_html( $accodes_taxonomy_name )."</h4>"; ?>
<?php wp_nonce_field('accodes_save_tax_meta', 'accodes_tax_meta_nonce'); ?>
<fieldset class="accodes_ind_field">