Manubri: è stato negato l'accesso per risolvere la proprietà "da" perché non è una "proprietà propria" del suo genitore


15

Sto usando un backend Nodejs con rendering sul lato server usando il manubrio. Dopo aver letto una docserie di oggetti dal manubrio, che contiene la chiave "contenuto" e "da". Tuttavia, quando provo a utilizzare il #eachciclo attraverso la matrice di oggetti, viene visualizzato l'errore "Manubrio: accesso negato per risolvere la proprietà" da "perché non si tratta di una" proprietà propria "del padre".

Ho provato a console.log () i dati che ho recuperato nell'array doc e tutto sembra a posto.

Per qualche prospettiva, questa è la query mongoose,
ho aggiunto l'oggetto doc come chiave all'interno degli argomenti 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;
  });

Questa è la parte del file .hbs che sto cercando di ripetere:

 {{#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}}

Risposte:


25

risolvo questo problema installando una dipendenza dev per il manubrio

npm i -D handlebars@4.5.0


Wow, ha funzionato, perché sta succedendo questo? Attualmente sto usando express-handlebars (3.1.0) che ho impostato come motore di rendering nella mia app express.
Lee Boon Kong,

Ho il sospetto che ciò stesse accadendo sulla versione più recente del manubrio a causa di alcune restrizioni, ma non so come lavorare su queste restrizioni.
Lee Boon Kong,

Bene, il problema si pone tra il plug-in express che supporta il manubrio, ma una volta salvato il manubrio 4.5.0 per utilizzarlo come motore principale del tuo frontend, fammelo sapere commentando questo.
Mason

Questo non sta funzionando. Ottengo ancora lo stesso problema dopo aver eseguito npm i -D handlebars@4.5.0
Deepak Thakur


13

Se si utilizza mongoose, questo problema può essere risolto usando .lean () per ottenere un oggetto json (invece di uno mongoose):

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

3
Dio ti benedica! SALVAVITA!
Nick Thenick,

1
Nessun problema, felice che abbia aiutato !!
Billeh

2
vorrei poter votare questa risposta più di una volta .. haha ​​Grazie mille!
Abdus,

7

Oggi ho lo stesso avvertimento dal manubrio e la vista è vuota. Di seguito è riportato come ho risolto questo problema:

//  * 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))
})

il file users.hbs

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

La creazione di un intero nuovo oggetto denominato contextcon le proprie proprietà e quindi lo passa nella funzione di rendering risolverà il problema ...

Nota:

Quando non creiamo un nuovo oggetto, è facile esporre accidentalmente informazioni riservate o informazioni che potrebbero compromettere la sicurezza del progetto, mappare i dati restituiti dal database e passare solo ciò che è necessario sulla vista potrebbe essere una buona pratica ...


Grazie mille per la tua risposta! Sembra meglio creare un nuovo oggetto per prevenire l'esposizione indesiderata dei dati.
Lee Boon Kong,

Grazie per questo lavoro.
GNETO DOMINIQUE,

Non richiede tempo 2x per il rendering preparando un nuovo elenco da un elenco preparato?
mustafiz012,

6

"Wow ha funzionato, perché sta succedendo questo? Attualmente sto usando express-handlebars (3.1.0) che ho impostato come motore di rendering nella mia app express." - Lee Boon Kong, 12 gennaio alle 14:13

"In passato, Handlebars ti consentiva di accedere ai metodi prototipo e alle proprietà dell'oggetto di input dal modello ... Molteplici problemi di sicurezza derivano da questo comportamento ... In handlebars@^4.6.0. L'accesso all'oggetto prototipo ha è stato completamente disabilitato. Ora, se usi le classi personalizzate come input per il manubrio, il tuo codice non funzionerà più ... Questo pacchetto aggiunge automaticamente opzioni di runtime a ciascuna chiamata del modello, disabilitando le restrizioni di sicurezza ... Se i tuoi utenti stanno scrivendo modelli e li esegui sul tuo server NON dovresti usare questo pacchetto, ma piuttosto trovare altri modi per risolvere il problema ...Ti suggerisco di convertire le tue istanze di classe in semplici oggetti JavaScript prima di passarle alla funzione template. Ogni proprietà o funzione a cui accedi deve essere una "proprietà propria" del suo genitore ". README

Maggiori dettagli qui: https://www.npmjs.com/package/@handlebars/allow-prototype-access

METODO DI INSECURA VELOCE E SPORCO

Utilizzo ( express-handlebarse mongoose):

express-handlebarsnon consente di specificare le opzioni di runtime da passare alla funzione template. Questo pacchetto può aiutarti a disabilitare i controlli prototipo per i tuoi modelli.

"Fallo solo se hai il pieno controllo dei modelli eseguiti nel server."

passi:

1 - Installa dipendenza

npm i @handlebars/allow-prototype-access

2 - Usa questo frammento come esempio per riscrivere il tuo server rapido

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 - Esegui il server e fai la tua danza felice.


METODO PIÙ SICURO PIÙ LUNGO

Prima di passare l'oggetto restituito dalla chiamata AJAX al modello Handlebars, mapparlo in un nuovo oggetto con ogni proprietà o funzione a cui è necessario accedere nel .hbsfile. Di seguito puoi vedere il nuovo oggetto creato prima di passarlo al modello Manubrio.

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));
});

La tua richiesta di mangusta

Correggimi se sbaglio, ma penso che potrebbe funzionare per la tua query ...

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

prova npm install manubri versione 4.5.3

npm install handlebars@4.5.3

Ha funzionato per me


Questo dovrebbe essere un commento
Arun Vinoth l'

Al momento stavo usando express-manubrio, versione 3.1.0
Lee Boon Kong

Grazie, ho provato sia la risposta di tuo figlio sia quella di Mason, ma non sono sicuro del perché accada.
Lee Boon Kong,

3

A partire dalla versione 4.6.0 in poi, il manubrio proibisce l'accesso alle proprietà e ai metodi del prototipo dell'oggetto di contesto per impostazione predefinita. Ciò è correlato a un problema di sicurezza descritto qui: https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html

Fare riferimento a https://github.com/wycats/handlebars.js/issues/1642

Se si è certi che solo gli sviluppatori hanno accesso ai modelli, è possibile consentire l'accesso al prototipo installando il seguente pacchetto:

npm i @handlebars/allow-prototype-access

Se si utilizza il manubrio express, procedere come segue:

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')

Grazie ha funzionato. Quindi dobbiamo farlo ogni volta che dobbiamo usare il manubrio express?
Yash Boura,

2

Si è verificato un cambiamento sostanziale nella recente versione di Handlebars che ha causato questo errore.

Puoi semplicemente aggiungere le configurazioni che suggeriscono nella loro documentazione, tuttavia tieni presente che, a seconda dell'implementazione, questo potrebbe portare la vulnerabilità agli attacchi XXS e 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;
  });

Ahhh, ecco dove aggiungo le opzioni, grazie mille!
Lee Boon Kong

1
Questo non ha funzionato per me. Era previsto un callback, non un oggetto opzioni.
Signor95

0

La creazione di un altro nuovo oggetto o matrice dai dati restituiti find() risolverà il problema. Vedi sotto una semplice illustrazione

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")
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.