У яких контекстах плагіни відповідають за перевірку / санітизацію даних?


17

Я хочу переконатися, що всі дані в моїх плагінах / темах обробляються безпечно перед входом у базу даних та перед виведенням у браузер. Моя проблема полягає в тому, що існують ситуації, коли API обробляє санітарну обробку для вас - наприклад, під час збереження метаполя публікацій - та інші, коли автор плагіна / теми несе повну відповідальність за це - як, наприклад, під час збереження спеціальних налаштувань.

Що стосується цього питання, мене не хвилює перевірка даних на рівні домену - наприклад, перевірка того, чи є вікове поле у ​​формі від 0 до 120, чи адреса електронної пошти є дійсною. Мене хвилює лише безпека - наприклад, уникнення запитів SQL, щоб уникнути ін'єкції SQL під час збереження в базі даних, або санітарії даних, що виводяться в шаблони HTML, щоб уникнути XSS.

Для санітарії виводу я знаю, що вам завжди потрібно використовувати такі функції, як esc_html()і esc_attr()коли лунають змінні у шаблонах HTML. Але що робити з використанням тегів шаблонів ? Чи всі вони вже санітують вихід? Якщо так, то для якого контексту (загальний HTML, атрибути тегів тощо)? Деякі функції мають варіанти для різних контекстів (як the_title_attribute(), але більшість - ні.

Що стосується санітарії введення, я знаю, що мені потрібно користуватися $wpdb->prepare()під час вручну запитів, але що робити при використанні API налаштувань для створення сторінки налаштувань плагіна або збереження метаполів публікації для користувацького типу публікації?

Зараз я просто перекопую Core та читаю підручники щоразу, коли використовую функцію, щоб дізнатися, чи вона санітирується чи ні, але це схильне до помилок і займає багато часу. Я сподіваюся знайти якийсь вичерпний перелік усіх можливих ситуацій та незалежно від того, чи API обробляє це чи ні. наприклад,

API перевіряє / дезінфікує

  • Збереження мета публікації за допомогою update_postmeta()
  • Збереження мета користувача за допомогою update_user_meta()
  • Виведення назви посади - використовуйте контекстуально відповідний варіант the_title()
  • тощо

Ви повинні вручну перевірити / оздоровити

  • Збереження параметрів плагіна за допомогою API налаштувань. Передати зворотний виклик як третій параметр register_setting().
  • Прямі запити до бази даних: Загорніть запит $wpdb->prepare().
  • Виведення змінних у HTML. Використання esc_attr(), esc_html()і т.д.
  • тощо

Мені б також цікаво зрозуміти, чому API надає його в певних ситуаціях, але не в інших. Я припускаю, що це має щось спільне з невідомою природою даних, але я хотів би почути ґрунтовне пояснення.


Мені подобається це питання. У мене така ж думка, як і ви. Я думаю, якщо є такий перелік, коли ми повинні перевірити / санітувати вручну, це було б чудово. +1.
Ань Тран

1
@Rilwis, будь ласка, дивіться мою відповідь. Ви завжди повинні підтверджувати. Санітація складніша, оскільки "безпечна" залежить від контексту. Як правило, при використанні API WordPress з WordPress відомих даних ( the_title(), і the_permalink()т.д.) ви добре , але з одними даними ви не (наприклад get_post_meta()). Якщо ви сумніваєтесь, саніруйте себе - це не зашкодить.
Стівен Харріс

@StephenHarris: Я прочитав ваш коментар. Я це теж знаю. Але я маю таку ж думку, що і Іен Данн. Я думаю, що головна причина, яку він просить, - "зробити достатньо, ні більше, ні менше".
Anh Tran

1
Я насправді не проти помилятися на стороні обережності і робити занадто багато перевірки / санітарії, але я думаю, що є випадки, коли втеча від речей удвічі може бути проблемою.
Ян Данн

Відповіді:


15

Тут є два поняття:

  • перевірка - переконайтеся, що дані є дійсними , тобто ціле число - ціле число, дата - дата (у правильному форматі тощо). Це слід зробити безпосередньо перед збереженням даних.
  • санітація - зробити дату безпечною для її використання в поточному контексті (наприклад, уникнення SQL-запитів або уникнення HTML на виході).

Перевірка, майже повсюдно, залежить лише від вас . Ви знаєте, які дані ви запитуєте від користувача, і ви знаєте, які дані ви очікуєте - WordPress не робить. Перевірка буде виконуватися, наприклад, на save_postгачку перед збереженням її в базі даних update_post_meta, або це може бути зроблено шляхом визначення функції зворотного дзвінка в API налаштувань, що викликається перед тим, як WordPress зберігає дані.

Санітація дещо змішаніша. Маючи справу з даними, про які WordPress споконвічно знає (наприклад, плитка публікації), ви можете бути впевнені, що WordPress вже зробив ці дані безпечними. Однак "безпечний" залежить від контексту; те, що безпечно для використання на сторінці, не обов'язково є безпечним як атрибут елемента. Тому WordPress матимуть різні функції для різного контексту (наприклад the_title(), the_title_rss(), the_title_attribute()) - так що ви повинні використовувати правильний .

Здебільшого ваш плагін може мати справу з метаметами - або, можливо, даними про події зі спеціальної таблиці. WordPress не знає, що це за дані або для чого це, тому він точно не знає, як зробити їх безпечними. Це залежить від вас . Це особливо важливо при використанні esc_url(), esc_attr(), і esc_textarea()т.д. , щоб запобігти зловмисний введення від можливості вставляти код. Оскільки WordPress знає next_posts(), що припустимо надрукувати URL на сторінку, воно застосовується esc_url()- але, наприклад, з метаметалом поста, воно не знає, що воно зберігає URL - або що ви хочете зробити з ним (якщо друк esc_url(), якщо перенаправлення esc_url_raw(). Якщо в добротності - помиляйтесь на сторону обережності і втечі від цього самостійно - і робіть це якомога пізніше.

Нарешті - що робити із збереженням даних? Чи потрібно тоді це зробити безпечним? Як уже згадувалося вам зробити необхідно переконатися , що дані вірні. Але якщо з допомогою WordPress API ( wp_insert_post(), і update_post_meta()т.д.) , то вам не потрібно дезінфікувати дані - тому що при збереженні даних тільки дезінфікуючими ви повинні робити, щоб уникнути заяв SQL - і WordPress робить це. Якщо ви використовуєте прямі оператори SQL (скажімо, для читання / запису даних із спеціальної таблиці), тоді вам слід скористатися $wpdbкласом, який допоможе вам переоцінити запити.

Я написав цю публікацію в блозі про санітацію та валідацію даних, яка може виявитися корисною - в ній я розповідаю про те, що від вас очікується в цьому плані.


Гей Стефане, дякую за пояснення. Це допомогло мені трохи краще зрозуміти це, але те, що я насправді шукаю, - це такий собі вичерпний список, як приклад, який я наводив. Схоже, ваш підхід полягає в тому, щоб навчитись здогадуватися, чи поводиться WP з цим, чи помилитися на стороні обережності та завжди санітувати. Я почував би себе впевненіше, якби мав авторитетний і всебічний список, а не покладався на своє розуміння цього. Я також переживаю, що подвійне втеча може призвести до проблем.
Ян Данн

Я також просто оновив питання, щоб уточнити кілька речей.
Ян Данн

0

Не впевнений, що це ретельно, але з будь-яким плагіном або темою введення користувача повинно бути очищено. Операції з базою даних повинні здійснюватися за допомогою методів $ wpdb->. Усі дані $ _GET та $ _POST повинні бути дезінфіковані.

Це краща практика для програмування PHP, ніж WordPress.

Отже, на закінчення, якщо є функція WordPress, використовуйте її, якщо ні, саніруйте свої змінні та дані самі.

Якщо я був надто розпливчастим, будь ласка, поставте більш конкретний питання.


3
Я розумію, що це потрібно завжди санітувати, але питання полягає в тому, хто робить санітарію у кожній конкретній ситуації. Іноді WordPress робить це автоматично, а іноді доводиться робити це вручну. Я оновив питання, щоб спробувати зробити це більш зрозумілим.
Ян Данн

Навіть коли ви використовуєте update_user_meta (), вам все одно потрібно перевірити його, оскільки оновлені значення можуть надходити з викритої форми або з даних користувача. Якщо це значення, що надходить із сценарію, наприклад внутрішнього рішення, з циклу if / else, то не слід його санітувати.
Ciprian

1
Значення, яке ви update_user_meta()передаєте, передається через stripslashes_deep()і sanitize_meta()в update_metadata(), а потім $wpdb->prepare()у $wpdb->update(). Отже, я не думаю, що вам це потрібно санітувати. Я щось пропускаю?
Ян Данн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.