핸들 바 : "보낸 사람"속성이 부모의 "자신의 속성"이 아니기 때문에 속성을 해결하기위한 액세스가 거부되었습니다.


15

핸들 바를 사용하여 서버 측 렌더링과 함께 Nodejs 백엔드를 사용하고 있습니다. doc키 "content"및 "from"을 포함하는 핸들에서 객체 배열을 읽은 후 그러나 #each개체 배열을 반복하는 데 사용하려고하면 "핸들 바 : 속성이 부모의"자신의 속성 "이 아니기 때문에"from "속성을 해결하기 위해 액세스가 거부되었습니다"라는 오류가 나타납니다.

doc 배열에서 가져온 데이터를 console.log ()하려고 시도했지만 모든 것이 잘 보입니다.

어떤 관점에서, 이것은 몽구스 쿼리입니다
. 개체 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

핸들 바에 대한 dev 의존성을 설치 하여이 문제를 해결합니다.

npm i -D handlebars@4.5.0


와우 작동했습니다. 왜 이런 일이 발생합니까? 현재 Express 앱에서 렌더 엔진으로 설정 한 express-handlebars (3.1.0)를 사용하고 있습니다.
이 분 홍콩

일부 제한 사항으로 인해 최신 버전의 핸들 바에서이 문제가 발생한 것으로 생각되지만 이러한 제한 사항에 대한 작업 방법을 모르겠습니다.
이 분 홍콩

글쎄, 문제는 핸들 바를 지원하는 익스프레스 플러그인 사이에 있지만 핸들 4.5.0이 프론트 엔드의 주요 엔진으로 사용되도록 저장되면 친절하게 알려주세요.
메이슨

작동하지 않습니다. npm i -D handlebars@4.5.0을 실행 한 후에도 여전히 같은 문제가 발생합니다.
Deepak Thakur


12

몽구스를 사용하는 경우 .lean ()을 사용하여 몽구스 대신 json 객체를 가져 와서이 문제를 해결할 수 있습니다.

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

3
하나님의 축복이 있기를! 생명의 은인!
Nick Thenick

1
문제 없습니다. 기꺼이 도와 드리겠습니다 !!
Billeh

2
이 답변을 두 번 이상 공표 할 수 있기를 바랍니다. haha ​​정말 감사합니다!
Abdus

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 도미니크

준비된 목록에서 새 목록을 준비하여 렌더링하는 데 2 ​​배의 시간이 걸리지 않습니까?
mustafiz012

6

"이제 효과가 있었는데 왜 이런 일이 발생합니까? 저는 현재 Express 앱에서 렌더 엔진으로 설정 한 express-handlebars (3.1.0)를 사용하고 있습니다." –이 분 홍콩 1 월 12 일 14:13

"과거에 핸들 바를 사용하면 템플릿에서 입력 객체의 프로토 타입 방법 및 속성에 액세스 할 수있었습니다.이 동작으로 인해 여러 가지 보안 문제가 발생했습니다. handlebars@^4.6.0에서 객체 프로토 타입에 대한 액세스 권한은 다음과 같습니다. 이제 사용자 정의 클래스를 Handlebars에 대한 입력으로 사용하면 코드가 더 이상 작동하지 않습니다 ...이 패키지는 각 템플릿 호출에 런타임 옵션을 자동으로 추가하여 보안 제한을 비활성화합니다 ... 사용자가 작성중인 경우 템플릿을 서버에서 실행하면이 패키지를 사용하지 말고 문제를 해결할 수있는 다른 방법을 찾으십시오 ...클래스 인스턴스를 템플릿 함수로 전달하기 전에 일반 JavaScript 객체로 변환하는 것이 좋습니다. 액세스하는 모든 속성 또는 기능은 해당 부모의 "자체 속성"이어야합니다. "– README

자세한 내용은 여기 : https://www.npmjs.com/package/@handlebars/allow-prototype-access

신속하고 더러운 검사 방법

사용법 ( express-handlebarsmongoose) :

express-handlebars템플릿 기능에 전달할 런타임 옵션을 지정할 수 없습니다. 이 패키지를 사용하면 모델의 프로토 타입 검사를 비활성화 할 수 있습니다.

"서버에서 실행되는 템플릿을 완전히 제어 할 수있는 경우에만이 작업을 수행하십시오."

단계 :

1-설치 종속성

npm i @handlebars/allow-prototype-access

2-이 스 니펫을 예로 사용하여 Express 서버를 다시 작성하십시오.

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 호출에서 반환 된 객체를 Handlebars 템플릿으로 전달하기 전에 .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 install handlebars 버전 4.5.3을 사용해보십시오.

npm 설치 핸들 바 @ 4.5.3

그것은 나를 위해 일했다


이것은 코멘트 여야합니다
Arun Vinoth

저는 현재 고속 핸들 버전 3.1.0을 사용하고있었습니다
Lee Boon Kong

감사합니다, 당신과 @Mason의 답변이 모두 효과가 있었지만 왜 이런 일이 일어나고 있는지 잘 모르겠습니다.
이 분 홍콩

3

버전 4.6.0부터 핸들 바는 기본적으로 컨텍스트 오브젝트의 프로토 타입 특성 및 메소드에 액세스하는 것을 금지합니다. https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html에 설명 된 보안 문제와 관련이 있습니다.

https://github.com/wycats/handlebars.js/issues/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

최근에 릴리스 된 핸들 바 의 주요 변경 사항 으로 인해이 오류가 발생했습니다.

설명서에 제안 된 구성을 추가하기 만하면되지만 구현에 따라 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")
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.