Անվտանգության նկատառումներ
JSON:API մոդուլը նախատեսված է Drupal-ում Entity API, Field API և Typed Data API-ով սահմանված տվյալների մոդելը (բովանդակությունը) JSON:API սպեցիֆիկացիային համապատասխան API-ի միջոցով հասանելի դարձնելու համար՝ հնարավորություն տալով արտաքին համակարգերին փոխազդել Drupal-ի կառավարվող տվյալների (ենթակառույցների) հետ:
Այդ գործընթացում, այն հետևում է Drupal-ի բոլոր անվտանգության միջոցառումներին տվյալների համար՝
- Հարգվում է Entity Access-ը (ենթակառույցի մատչելիություն)։
- Հարգվում է Field Access-ը (դաշտի մատչելիություն)։
- Տվյալների փոփոխման ժամանակ հարգվում են վավերացման սահմանափակումները։
- Հարգվում է
internal
դրոշը (տես՝ փաստաթուղթ)։
Այլ կերպ ասած՝ JSON:API-ն չի շրջանցում գոյություն ունեցող անվտանգության որևէ միջոց, և սեփական լրացուցիչ շերտ չի ավելացնում. այն կրկին օգտագործում է Drupal-ի հիմքը:
Սխալները ենթակառույցների, դաշտերի և տվյալների տիպերի մեջ կարող են հանգեցնել անվտանգության խոցելիությունների
Այնուամենայնիվ, սխալներ կարող են լինել ենթակառույցների, դաշտերի, տվյալների տիպերի, ինչպես նաև դրանց մատչելիության հենարանների և վավերացման սահմանափակումների մեջ։ Սա հիմնականում պայմանավորված է Drupal-ի ժառանգությամբ՝ սկզբում չկային վավերացման սահմանափակումներ, միայն form validation callbacks։ API-first գաղափարը հիմնականում իրագործվել է Drupal-ի հիմնականում, սակայն երաշխավորված չէ ներդրված կամ հատուկ մոդուլների համար։
Այս սխալները կարող են հանգեցնել անվտանգության խոցելիությունների՝ ինչպես եղել է անցյալում։ Դրանք սահմանափակված չեն միայն JSON:API մոդուլով՝ օրինակ, նաև RESTful Web Services մոդուլը կամ ցանկացած PHP կոդ, որ փոխազդում է Entity API-ի հետ, ենթակա է դրանց։
Սակայն, քանի որ չարամիտ օգտվողը HTTP API-ին (ինչպիսին է JSON:API-ն կամ REST-ը) հեշտությամբ կարող է մուտք գործել, այս դեպքում անհրաժեշտ է ավելի մեծ զգուշություն։ Բացի այդ, JSON:API-ն (այլ HTTP API մոդուլներից տարբեր) մեկնարկից ունի մեծ API մակերես. բոլոր ոչ internal
ենթակառույցները հասանելի են դառնում ըստ լռելյայն (բնականաբար՝ Entity Access-ի հարգմամբ), ինչը հեշտացնում է մշակողի աշխատանքը։
Վեց անվտանգության նկատառում
1. Օգտագործեք միայն կայուն (stable) ներդրված մոդուլներ
Ենթակառույցների, դաշտերի և տվյալների տիպերի կողմից առաջացած անվտանգության խոցելիությունները արագ լուծվում են միայն Drupal.org-ում հրապարակված և անվտանգության խորհրդատվության քաղաքականության ներքո գտնվող կայուն մոդուլների համար։ Հատուկ (custom) և ոչ-կայուն ներդրված մոդուլները ընդգրկված չեն։ Եթե օգտագործում եք նման մոդուլներ, եղեք առավել զգույշ։
2. Ենթակառույցների և դաշտերի մատչելիության աուդիտ
Անկախ նրանից՝ օգտագործում եք JSON:API, թե այլ API մոդուլ, խորհուրդ է տրվում ստուգել ենթակառույցների և դաշտերի մատչելիությունը։ Սա հատկապես կարևոր է, եթե միացված են գրառման (write) հնարավորությունները։
3. Բացահայտեք միայն այն, ինչ ձեզ պետք է
Եթե որոշ ռեսուրսների տիպեր (ենթակառույցներ և bundle-ներ) պետք չեն բացել, նախապայման՝ դրանց մատչելիությունը արգելափակված լինի, կարող եք լրացուցիչ լիովին անջատել դրանք։ Դրա համար կա PHP API, որը կարող եք կիրառել ձեր մոդուլում կամ օգտվել JSON:API Extras մոդուլից, որն ունի UI ռեսուրսների և դաշտերի անջատման համար։ Սա ոչ միշտ է հնարավոր, սակայն եթե կայքի սեփականատերը նաև API հաճախորդների սեփականատերն է, կարող եք նվազեցնել API մակերեսը։
4. Միայն կարդալու ռեժիմ (Read-only mode)
Եթե ձեզ անհրաժեշտ է միայն տվյալների կարդալը, կարող եք միացնել JSON:API-ի read-only ռեժիմը՝ /admin/config/services/jsonapi
հասցեում։ Սա նվազեցնում է ռիսկը վավերացման սահմանափակումների և գրառման լոգիկայի դեռ չբացահայտված սխալներից։ Ժամանակակից decoupled Drupal նախագծերի մեծ մասը միայն կարդալու ֆունկցիոնալություն է պահանջում, այդ պատճառով read-only ռեժիմը լռելյայն միացված է (Drupal core-ի JSON:API-ում և ներդրված մոդուլի 2.4 և ավելի նոր տարբերակներում)։
5. Անվտանգություն՝ base path-ը թաքցնելու միջոցով (Security through obscurity)
JSON:API-ի բազային ուղին լռելյայն /jsonapi
է։ Կարող եք այն փոխել ինչ-որ նման բանի՝ /hidden/b69dhj027ooae/jsonapi
՝ ավտոմատացված հարձակումները նվազեցնելու համար։ Ստեղծեք sites/example.com/services.yml
(եթե չկա) և ավելացրեք․
parameters:
jsonapi.base_path: /hidden/b69dhj027ooae/jsonapi
6. Սահմանափակեք՝ որ entity bundle-ները կարող են ստեղծվել կամ խմբագրվել՝ որոշ ուղիներ հեռացնելով
Եթե անհրաժեշտ է, որ միայն որոշ bundle-ներ կարողանան ստեղծվել կամ փոփոխվել JSON:API-ով, կարող եք իրականացնել event subscriber՝ whitelist-ից դուրս բոլոր POST և PATCH ուղիները ջնջելու համար։ Սա գործելու է read-only ռեժիմի անջատումից հետո և router rebuild կարող է պահանջվել։
Ավելացրեք ծառայություն ձեր մոդուլի services.yml-ում․
services:
mymodule.route_subscriber:
class: Drupal\mymodule\Routing\JsonapiLimitingRouteSubscriber
tags:
- { name: event_subscriber }
Ստեղծեք event subscriber-ը։ Այս օրինակը նաև անհնար է դարձնում JSON:API-ով որևէ բովանդակության ջնջումը.
<?php
namespace Drupal\mymodule\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* JsonapiLimitingRouteSubscriber դաս։
*
* Ջնջում է բոլոր DELETE ուղիները JSON:API ռեսուրսներից՝ բովանդակությունը պաշտպանելու համար։
* Ջնջում է POST և PATCH ուղիները, բացի whitelist-ի ռեսուրսներից,
* որ վերջնական օգտագործողը կարող է ստեղծել կամ փոփոխել decoupled API-ով։
*/
class JsonapiLimitingRouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
$mutable_types = $this->mutableResourceTypes();
foreach ($collection as $name => $route) {
$defaults = $route->getDefaults();
if (!empty($defaults['_is_jsonapi']) && !empty($defaults['resource_type'])) {
$methods = $route->getMethods();
if (in_array('DELETE', $methods)) {
// Երբեք չենք ուզում ջնջել տվյալներ, միայն անջատել։
$collection->remove($name);
}
else {
$resource_type = $defaults['resource_type'];
if (empty($mutable_types[$resource_type])) {
if (in_array('POST', $methods) || in_array('PATCH', $methods)) {
$collection->remove($name);
}
}
}
}
}
}
/**
* Սահմանել whitelist-ում գտնվող (փոփոխելի) ռեսուրսի տիպերը API-ի համար։
*
* @return array
* Փոփոխելի jsonapi ռեսուրսի տիպերի ցուցակ՝ որպես բանալի։
*/
public function mutableResourceTypes(): array {
return [
'node--article' => TRUE,
'node--document' => TRUE,
'custom_entity--custom_entity' => TRUE,
];
}
}
Սահմանափակել մուտքը բոլոր JSON:API ուղիներին հավելյալ թույլտվությամբ
Եթե JSON:API-ն օգտագործվում է միայն ներքին ինտեգրացիաների, սահմանափակ API հաճախորդների կամ ոչ-հանրային օգտագործման համար, ցանկալի է, որ բոլոր JSON:API ուղիները հասանելի լինեն միայն որոշակի թույլտվություն ունեցող օգտվողներին։ Դրա համար route subscriber-ում ավելացրեք հետևյալը․
// Սահմանափակել մուտքը բոլոր jsonapi ուղիներին հավելյալ թույլտվությամբ։
foreach ($collection as $route) {
$defaults = $route->getDefaults();
if (!empty($defaults['_is_jsonapi'])) {
$route->setRequirement('_permission', 'FOO custom access jsonapi');
}
}
Այնուհետև ավելացրեք այդ թույլտվությունը FOO.permissions.yml-ում և տվեք այն միայն անհրաժեշտ դերերին։
Հոդվածը վերցված է Drupal Documentation-ից։