Ручки: Доступ відмовлено у вирішенні ресурсу "з", оскільки це не "власна власність" його батька


15

Я використовую сервер Nodejs із візуалізацією на стороні сервера за допомогою рулі. Після зчитування docмасиву об’єктів з рульової панелі, який містить ключі "зміст" і "від". Однак, коли я намагаюся використовувати #eachдля перегляду через масив об'єктів, з'являється помилка "Ручки: Доступ заборонено для вирішення властивості" з ", тому що це не" власне властивість "свого батька".

Я намагався console.log () дані, які я отримав у масиві doc, і все здається нормальним.

З певної точки зору, це запит мангуста,
я додав об’єкт doc як ключ до аргументів res.render.

Confession.find()
  .sort({date: -1})
  .then(function(doc){
    for(var i=0; i < doc.length; i++){
      //Check whether sender is anonymous
      if (doc[i].from === "" || doc[i].from == null){
        doc[i].from = "Anonymous";
      }

      //Add an extra JSON Field for formatted date
      doc[i].formattedDate = formatTime(doc[i].date);
    }
    res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc});
    req.session.errors = null;
    req.session.success = null;
  });

Це частина файлу .hbs, яку я намагаюся провести через:

 {{#each confession}}
    <div class="uk-card uk-card-default uk-card-body uk-margin uk-align-center uk-width-1-2@m" >
        <div class="uk-text-bold">Message: </div>
        <div>{{this.content}}</div>
        <div>From: {{this.from}}</div>
        <div>Posted: {{this.formattedDate}}</div>
    </div>
    {{/each}}

Відповіді:


25

Я вирішую цю проблему, встановивши залежність від розробника для рульової панелі

npm i -D handlebars@4.5.0


Нічого це не спрацювало, чому це все-таки відбувається? На даний момент я використовую експрес-ручки (3.1.0), які я встановив як двигун візуалізації у своєму експрес-додатку.
Лі Бун Конг

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

Ну, проблема лежить між експрес-плагіном, який підтримує рульове управління, але як тільки руль 4.5.0 збережеться для використання в якості основного двигуна вашого фронту, будь ласка, повідомте мене, коментуючи це.
Мейсон

Це не працює. Все-таки отримайте те саме питання після того, як я виконаю npm i -D handlebars@4.5.0
Deepak Thakur

Правильна відповідь тут github.com/wycats/handlebars.js/isissue/1642
Deepak Thakur

12

Якщо використовується мангуста, цю проблему можна вирішити за допомогою .lean (), щоб отримати об’єкт json (замість мангуста):

dbName.find({}).lean()
  // execute query
  .exec(function(error, body) {
     //Some code
  });

3
Бог благословив тебе! ЖИТТЯ ЗБЕРІГАЙТЕ!
Нік Тоутік

1
Без проблем, радий, що це допомогло !!
Білле

2
хотілося б, щоб я міг підкреслити цю відповідь не раз .. ха-ха, дякую тобі!
Абдус

7

Сьогодні я маю те саме попередження з рульового керування, і вигляд порожній. Нижче описано, як я це зафіксував:

//  * USERS PAGE
// @description        users route
// @returns           ../views/users.hbs
router.get('/users', async (req, res) => {
  // get all items from db collection
  const collection = 'User'
  await dbFindAllDocs(collection) // <=> wrapper for Model.find() ...
    .then(documents => {
      // create context Object with 'usersDocuments' key
      const context = {
        usersDocuments: documents.map(document => {
          return {
            name: document.name,
            location: document.location
          }
        })
      }
      // rendering usersDocuments from context Object
      res.render('users', {
        usersDocuments: context.usersDocuments
      })
    })
    .catch(error => res.status(500).send(error))
})

файл users.hbs

<ul>
{{#each usersDocuments}}
<li>name: {{this.name}} location: {{this.location}}</li>
{{/each}}    
</ul>

Створення цілого нового об’єкта, названого contextз його власними властивостями, а потім перехід його у функцію візуалізації, виправить проблему ...

Примітка:

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


Дякую за вашу відповідь! Здається, краще створити новий об’єкт, щоб запобігти небажаному опроміненню даних.
Лі Бун Конг

Дякую за цю роботу.
GNETO DOMINIQUE

Хіба це не потребує 2x часу для візуалізації, підготувавши новий список із підготовленого списку?
mustafiz012

6

"Нічого це не спрацювало. Чому це все-таки відбувається? Зараз я використовую експрес-ручки (3.1.0), які я встановив як двигун візуалізації у своєму експрес-додатку." - Лі Бун Конг 12 січня о 14:13

"У минулому рульові панелі дозволяли б отримати доступ до методів прототипу та властивостей вхідного об'єкта з шаблону ... Від такої поведінки виникло декілька проблем із безпекою ... У handlebars@^4.6.0. Доступ до прототипу об'єкта має Якщо ви користуєтеся спеціальними класами в якості введення в руль, ваш код більше не працюватиме ... Цей пакет автоматично додає параметри виконання під час кожного виклику шаблону, відключаючи обмеження безпеки ... Якщо ваші користувачі пишуть шаблони, і ви виконуєте їх на своєму сервері, НЕ слід використовувати цей пакет, а шукати інші способи вирішення проблеми ...Я пропоную вам перетворити свої екземпляри класу в звичайні об’єкти JavaScript, перш ніж передати їх у функцію шаблону. Кожна власність або функція, до якої ви отримуєте доступ, повинна бути "власною властивістю" свого батьківського ". - README

Детальніше тут: https://www.npmjs.com/package/@handlebars/allow-prototype-access

МЕТОД ШВИДКОГО І БЕЗПЕЧНОГО ЗАБЕЗПЕЧЕННЯ

Використання ( express-handlebarsі mongoose):

express-handlebarsне дозволяє вказати параметри виконання для переходу до функції шаблону. Цей пакет може допомогти вам відключити перевірку прототипу для своїх моделей.

Msgstr "Зробіть це, лише якщо ви повністю контролюєте шаблони, які виконуються на сервері."

Кроки:

1 - Встановити залежність

npm i @handlebars/allow-prototype-access

2 - Використовуйте цей фрагмент як приклад, щоб переписати свій експрес-сервер

const express = require('express');
const mongoose = require('mongoose');
const Handlebars = require('handlebars');
const exphbs = require('express-handlebars');

// Import function exported by newly installed node modules.
const { allowInsecurePrototypeAccess } = require('@handlebars/allow-prototype->access');

const PORT = process.env.PORT || 3000;

const app = express();

const routes = require('./routes');

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static('public'));

// When connecting Handlebars to the Express app...
app.engine('handlebars', exphbs({
    defaultLayout: 'main',
    // ...implement newly added insecure prototype access
    handlebars: allowInsecurePrototypeAccess(Handlebars)
    })
);
app.set('view engine', 'handlebars');

app.use(routes);

const MONGODB_URI = process.env.MONGODB_URI || >'mongodb://localhost/dbName';

mongoose.connect(MONGODB_URI);

app.listen(PORT, function () {
  console.log('Listening on port: ' + PORT);
});

3 - Запусти сервер і займайся своїм щасливим танцем.


ДОВГІЙ БІЛЬШЕ БЕЗПЕЧНИЙ МЕТОД

Перш ніж передати об’єкт, повернутий за допомогою дзвінка AJAX, до шаблону Рулевих панелей, складіть його на новий об’єкт із кожним властивістю або функцією, до якої потрібно отримати доступ у своєму .hbsфайлі. Нижче ви можете побачити новий об’єкт, зроблений перед тим, як передати його до шаблону Руль.

const router = require("express").Router();
const db = require("../../models");

router.get("/", function (req, res) {
    db.Article.find({ saved: false })
        .sort({ date: -1 })
        .then(oldArticleObject => {
            const newArticleObject = {
                articles: oldArticleObject.map(data => {
                    return {
                        headline: data.headline,
                        summary: data.summary,
                        url: data.url,
                        date: data.date,
                        saved: data.saved
                    }
                })
            }
            res.render("home", {
                articles: newArticleObject.articles
            })
        })
        .catch(error => res.status(500).send(error));
});

Ваш запит мангуста

Виправте мене, якщо я помиляюся, але я думаю, що це може працювати для вашого запиту ...

Confession.find()
    .sort({ date: -1 })
    .then(function (oldDoc) {

        for (var i = 0; i < oldDoc.length; i++) {
            //Check whether sender is anonymous
            if (oldDoc[i].from === "" || oldDoc[i].from == null) {
                oldDoc[i].from = "Anonymous";
            }

            //Add an extra JSON Field for formatted date
            oldDoc[i].formattedDate = formatTime(oldDoc[i].date);
        }

        const newDoc = {
            doc: oldDoc.map(function (data) {
                return {
                    from: data.from,
                    formattedDate: data.formattedDate
                }
            })
        }

        res.render('index', { title: 'Confession Box', success: req.session.success, errors: req.session.errors, confession: newDoc.doc });
        req.session.errors = null;
        req.session.success = null;
    });

5

спробуйте npm встановити руль версії 4.5.3

npm встановити рукоятку@4.5.3

Це працювало для мене


Це має бути коментар
Арун Вінот

Наразі я використовував експрес-рулі, версія 3.1.0
Лі Бун Конг

Дякую, я спробував і те, і твою враження @ Мейсона спрацювало б, але я не впевнений, чому це відбувається.
Лі Бун Конг

3

Починаючи з версії 4.6.0 і далі, Руль забороняє за замовчуванням отримувати доступ до властивостей прототипу та методів контекстного об'єкта. Це пов’язано з проблемою безпеки, описаною тут: https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html

Зверніться до https://github.com/wycats/handlebars.js/isissue/1642

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

npm i @handlebars/allow-prototype-access

Якщо ви використовуєте експрес-ручки, то слід поступити так:

const 
    express = require('express'),
    _handlebars = require('handlebars'),
    expressHandlebars = require('express-handlebars'),
    {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype-access')

const app = express()

app.engine('handlebars', expressHandlebars({
    handlebars: allowInsecurePrototypeAccess(_handlebars)
}))
app.set('view engine', 'handlebars')

Спасибі це спрацювало. Тож ми маємо це робити кожного разу, коли нам доводиться користуватися експрес-ручками?
Yash Boura

2

У нещодавньому випуску Handlebars відбулася переломна зміна, яка викликала цю помилку.

Ви можете просто додати конфігурації, які вони пропонують у своїй документації, однак пам’ятайте, що залежно від вашої реалізації це може призвести до вразливості до атак XXS та RCE.

https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access

Confession.find()
  .sort({date: -1})
  .then(function(doc){
    for(var i=0; i < doc.length; i++){
      //Check whether sender is anonymous
      if (doc[i].from === "" || doc[i].from == null){
        doc[i].from = "Anonymous";
      }

      //Add an extra JSON Field for formatted date
      doc[i].formattedDate = formatTime(doc[i].date);
    }
    res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc}, {

      // Options to allow access to the properties and methods which as causing the error.

      allowProtoMethodsByDefault: true,
      allowProtoPropertiesByDefault: true

    });

    req.session.errors = null;
    req.session.success = null;
  });

А-а-а, ось тут я додаю варіанти, велике спасибі!
Лі Бун Конг

1
Це не спрацювало для мене. Очікувався зворотний виклик, а не об'єкт параметрів.
mrg95

0

Створення іншого нового об’єкта або масиву з даних, повернених в результаті find() , вирішить проблему. Дивіться нижче просту ілюстрацію

app.get("/",(req,res)=>{

 let com = require('./MODELCOM')    // loading model
 let source=fs.readFileSync(__dirname+"/views/template.hbs","utf-8");

 com.find((err,data)=>{
    // creation new array  using map
   let wanted = data.map(doc=>{
       return {
           name:doc.name,
           _id:doc._id
        }
   })

    let html= handlebar.compile(source);
  fs.writeFileSync(__dirname+"/views/reciever.html",html({communities:wanted}))
    res.sendFile(__dirname+"/views/reciever.html")
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.