source

핸들 바:부모의 "소유 속성"이 아니기 때문에 "출처" 속성을 확인하기 위한 액세스가 거부되었습니다.

ittop 2023. 5. 7. 11:49
반응형

핸들 바:부모의 "소유 속성"이 아니기 때문에 "출처" 속성을 확인하기 위한 액세스가 거부되었습니다.

핸들을 사용한 서버 측 렌더링과 함께 Nodejs 백엔드를 사용하고 있습니다. 를읽은후를 읽은 후에.doc키 "내용" 및 "발신인"을 포함하는 핸들 바의 개체 배열입니다. 제가 하만제가사고할려때하용지할때▁use▁i▁to▁▁however고를 사용하려고 할 때.#each": " 속성 "from을 확인하기 부모의 "소유 속성"이 아니므로 "발신자" 속성을 확인하기 위한 액세스가 거부되었습니다.

문서 배열에서 가져온 데이터를 .log() 콘솔에 넣으려고 했는데 모든 것이 정상인 것 같습니다.

쿼리 즉 쿼리입니다.
arguments.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}}

mongoose를 사용하는 경우 mongoose 대신 .lean()을 사용하여 json 개체를 가져오면 이 문제를 해결할 수 있습니다.

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

핸들 바에 대한 개발 종속성을 설치하여 이 문제를 해결합니다.

npm i -D handlebars@4.5.0

"우와 이것은 효과가 있었습니다, 그런데 왜 이런 일이 일어나는 걸까요?현재 익스프레스 앱에서 렌더 엔진으로 설정한 익스프레스 핸들 바(3.1.0)를 사용하고 있습니다." – Lee Boon Kong 1월 12일 14:13

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

자세한 내용은 여기에서 확인할 수 있습니다. https://www.npmjs.com/package/ @httpbars/allow-http-access

빠르고 더럽게 안전하지 않은 방법

용도(express-handlebars그리고.mongoose):

express-handlebars템플릿 함수에 전달할 런타임 규칙을 지정할 수 없습니다.이 패키지는 모델에 대한 프로토타입 검사를 비활성화하는 데 도움이 됩니다.

"서버에서 실행되는 템플리트를 완전히 제어할 수 있는 경우에만 이 작업을 수행합니다."

단계:

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

오늘 핸들 바에서 같은 경고가 표시되고 보기가 비어 있습니다.다음은 제가 수정한 방법입니다.

//  * 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자체 속성을 사용하여 렌더 함수에 전달하면 문제가 해결됩니다.

참고:

새 개체를 만들지 않으면 기밀 정보나 프로젝트의 보안을 손상시킬 수 있는 정보가 실수로 노출되기 쉽습니다. 데이터베이스에서 반환된 데이터를 매핑하고 필요한 정보만 보기에 전달하는 것이 좋습니다.

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

try npm 설치 핸들바 버전 4.5.3

npm 핸들바 설치@4.5.3

그것은 나에게 효과가 있었다.

이 문제를 해결하는 더 깨끗한 방법은 mongoose document .toJSON() 메서드를 사용하는 것입니다.

let data = dbName.find({})
  .exec(function(error, body) {
     //Some code
  });
    data = data.toJSON()
//use {{data}} on .hbs template

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

에서반데에서 새 Object 생성하기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")
});

는 사용중을 하고 있습니다.Angular version 8.0.2그리고.Node version 10.16.3테스트 사례를 실행하는 동안 아래 문제가 발생했습니다.

핸들 바:부모의 "소유 속성"이 아니므로 속성 "문"을 확인하기 위한 액세스가 거부되었습니다.

핸들 바:부모의 "소유 속성"이 아니므로 속성 "함수"를 확인하기 위한 액세스가 거부되었습니다.

문제를 디버깅하는 동안 다음과 같은 사실을 추가로 발견했습니다.package.json, "karma-coverage-istanbul-reporter": "2.0.1" 나러뿐인 그▁there▁but"istanbul-lib-report"다음 단계를 수행했습니다.

  1. 포장되어 있습니다.json 파일, 종속성에 "syslog-lib-report" 포함: "3.0.0"
  2. npm 설치 실행

그리고 그것은 제 문제를 해결했습니다 :) (이것이 누군가에게 도움이 되기를 바랍니다)

다음 코드를 추가하여 문제 해결...설치를 사용하기 전에 다음 명령으로 프로토타입을 허용합니다.문제가 있는 경우 댓글:

설치-모듈

npm install @handlebars/allow-prototype-access

패키지 가져오기

const Handlebars = require('handlebars')
const {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype- 
access')

뷰 엔진 설정

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

app.js(기본 레이아웃 경로)에 추가합니다.

app.engine('hbs', hbs.engine({
  extname: 'hbs',
  defaultLayout: 'layouts',
  layoutDir: __dirname + '/views/layouts',
  partialsDir:__dirname+'/views/partials/',
  runtimeOptions:{allowProtoPropertiesByDefault:true,
  allowedProtoMethodsByDefault:true}
}));

모든 hbs 버전에서 작동하는 이 문제에 대한 해결 방법이 있습니다. 이렇게 하고 데이터베이스를 페이지로 보냅니다.이것은 Handlbar 템플릿을 변경하지 않고 작동하며 최종적으로 0개의 취약성으로 진행할 수 있습니다.

var database=[];
for(var i=0;i<foundData.length;i++)
{
 database[i]=foundData[i].toObject();
}

나는 지도 기능을 추가했고 그것은 나에게 효과가 있었습니다.

    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.map(doc=>doc.toJSON())}**);
        req.session.errors = null;
        req.session.success = null;
      });

저는 몽구스를 사용하는데 이 기능으로 당신의 문제를 해결할 수 있습니다.

const confession=await Confession.find({}).lean();
res.render('index',{confession});

무엇이 나에게 정말 도움이 되고 나는 코드를 크게 바꿀 필요가 없었습니다.

runtimeOptions: {
    allowProtoPropertiesByDefault: true,
    allowProtoMethodsByDefault: true
  }

내 앱 엔진 내부, 전체 코드 ->

const handlebars = require('express-handlebars')
app.engine('hbs', handlebars.engine({extname: 'hbs', runtimeOptions: {
    allowProtoPropertiesByDefault: true,
    allowProtoMethodsByDefault: true
  },layoutsDir: __dirname + '/views/Layout', defaultLayout: 'defaultLayout'}))
app.set('view engine', 'hbs')

언급URL : https://stackoverflow.com/questions/59690923/handlebars-access-has-been-denied-to-resolve-the-property-from-because-it-is

반응형