Tay cầm: Quyền truy cập đã bị từ chối để giải quyết tài sản của Google từ vì vì đây không phải là tài sản của riêng


15

Tôi đang sử dụng một phụ trợ Nodejs với kết xuất phía máy chủ bằng cách sử dụng các tay cầm. Sau khi đọc một docloạt các đối tượng từ tay lái, trong đó có khóa "nội dung" và "từ". Tuy nhiên, khi tôi cố gắng sử dụng #eachđể lặp qua mảng các đối tượng, lỗi "Tay cầm: Truy cập đã bị từ chối để giải quyết thuộc tính" từ "vì nó không phải là" tài sản riêng "của cha mẹ" xuất hiện.

Tôi đã cố gắng để console.log () dữ liệu mà tôi đã tìm nạp trong mảng doc và mọi thứ có vẻ ổn.

Đối với một số phối cảnh, đây là truy vấn mongoose,
tôi đã thêm tài liệu đối tượng làm khóa trong các đối số 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;
  });

Đây là một phần của tệp .hbs tôi đang cố gắng lặp qua:

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

Câu trả lời:


25

tôi giải quyết vấn đề này bằng cách cài đặt một phụ thuộc dev cho các tay lái

npm i -D handlebars@4.5.0


Wow điều này làm việc, tại sao điều này xảy ra mặc dù? Tôi hiện đang sử dụng tay cầm tốc hành (3.1.0) mà tôi đặt làm công cụ kết xuất trong ứng dụng thể hiện của mình.
Lee Boon Kong

Tôi nghi ngờ điều này đã xảy ra trên phiên bản tay lái mới hơn do một số hạn chế, nhưng tôi không biết cách khắc phục những hạn chế này.
Lee Boon Kong

Chà, vấn đề nằm giữa plugin express hỗ trợ các tay cầm, nhưng một khi các tay cầm 4.5.0 được lưu để sử dụng làm công cụ chính của frontend của bạn, vui lòng cho tôi biết bằng cách nhận xét về điều này.
Mason

Đây không phải là làm việc. Vẫn gặp vấn đề tương tự sau khi tôi thực thi npm i -D handlebars@4.5.0
Deepak Thakur

Câu trả lời đúng là ở đây github.com/wycats/handlebars.js/issues/1642
Deepak Thakur

12

Nếu sử dụng cầy mangut, vấn đề này có thể được giải quyết bằng cách sử dụng .lean () để lấy đối tượng json (thay vì cầy mangut):

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

3
Chúa phù hộ bạn! CUỘC SỐNG KHÔNG BAO GIỜ!
Nick Thenick

1
Không có vấn đề, rất vui vì nó đã giúp !!
Billeh

2
ước gì tôi có thể nâng cao câu trả lời này hơn một lần .. haha ​​Cảm ơn bạn rất nhiều!
Abdus

7

Hôm nay tôi có cảnh báo tương tự từ tay lái và chế độ xem trống. Dưới đây là cách tôi sửa nó:

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

tập tin users.hbs

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

Tạo một đối tượng hoàn toàn mới có tên contextthuộc tính của riêng nó, sau đó chuyển nó vào chức năng kết xuất sẽ khắc phục sự cố ...

Ghi chú:

Khi chúng tôi không tạo Đối tượng mới, rất dễ vô tình để lộ thông tin bí mật hoặc thông tin có thể làm tổn hại đến bảo mật của máy bay phản lực, ánh xạ dữ liệu được trả về từ cơ sở dữ liệu và chỉ truyền những gì cần thiết vào chế độ xem có thể là một cách thực hành tốt ...


Cảm ơn rất nhiều cho câu trả lời của bạn! Có vẻ tốt hơn để tạo một đối tượng mới để ngăn chặn việc tiếp xúc dữ liệu không mong muốn.
Lee Boon Kong

Cảm ơn vì công việc này.
GNETO DOMINIITE

Nó không tiêu tốn gấp đôi thời gian để kết xuất bằng cách chuẩn bị danh sách mới từ danh sách đã chuẩn bị?
mustafiz012

6

"Wow điều này đã hoạt động, Tại sao điều này lại xảy ra? Tôi hiện đang sử dụng tay cầm tốc hành (3.1.0) mà tôi đặt làm công cụ kết xuất trong ứng dụng thể hiện của mình." - Lee Boon Kong ngày 12 tháng 1 lúc 14:13

"Trước đây, Tay cầm sẽ cho phép bạn truy cập các phương thức và thuộc tính nguyên mẫu của đối tượng đầu vào từ mẫu ... Nhiều vấn đề bảo mật đã xuất phát từ hành vi này ... Trong tay cầmbb @@ .4.6.0. Truy cập vào nguyên mẫu đối tượng Bây giờ, nếu bạn sử dụng các lớp tùy chỉnh làm đầu vào cho Tay cầm, mã của bạn sẽ không hoạt động nữa ... Gói này tự động thêm tùy chọn thời gian chạy cho mỗi cuộc gọi mẫu, vô hiệu hóa các hạn chế bảo mật ... Nếu người dùng của bạn đang viết các mẫu và bạn thực thi chúng trên máy chủ của mình, bạn KHÔNG nên sử dụng gói này mà nên tìm các cách khác để giải quyết vấn đề ...Tôi đề nghị bạn chuyển đổi các thể hiện lớp của mình thành các đối tượng JavaScript đơn giản trước khi chuyển chúng sang hàm mẫu. Mọi tài sản hoặc chức năng bạn truy cập, phải là "tài sản riêng" của cha mẹ. "- README

Thêm chi tiết tại đây: https://www.npmjs.com/package/@handlebars/allow-prototype-access

PHƯƠNG PHÁP BẢO HIỂM NHANH VÀ TRỰC TIẾP

Cách sử dụng ( express-handlebarsmongoose):

express-handlebarskhông cho phép bạn chỉ định các tùy chọn thời gian chạy để chuyển đến chức năng mẫu. Gói này có thể giúp bạn vô hiệu hóa kiểm tra nguyên mẫu cho các mô hình của bạn.

"Chỉ làm điều này, nếu bạn có toàn quyền kiểm soát các mẫu được thực thi trong máy chủ."

Các bước:

1 - Cài đặt phụ thuộc

npm i @handlebars/allow-prototype-access

2 - Sử dụng đoạn mã này làm ví dụ để viết lại máy chủ tốc hành của bạn

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 - Chạy máy chủ và thực hiện điệu nhảy hạnh phúc của bạn.


PHƯƠNG PHÁP AN TOÀN HƠN

Trước khi chuyển đối tượng được trả về bởi lệnh gọi AJAX của bạn đến mẫu Tay cầm, hãy ánh xạ nó vào một đối tượng mới với mỗi thuộc tính hoặc chức năng bạn cần truy cập trong .hbstệp của mình . Dưới đây bạn có thể thấy đối tượng mới được tạo trước khi chuyển nó vào mẫu Tay cầm.

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

Truy vấn cầy mangut của bạn

Chỉnh sửa cho tôi nếu tôi sai nhưng tôi nghĩ rằng điều này có thể làm việc cho truy vấn của bạn ...

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

dùng thử npm cài đặt tay cầm phiên bản 4.5.3

npm cài đặt handbars@4.5.3

Nó làm việc cho tôi


Đây phải là một bình luận
Arun Vinoth

Tôi hiện đang sử dụng tay lái tốc hành, phiên bản 3.1.0
Lee Boon Kong

Cảm ơn, tôi đã thử cả anwser của bạn và @ Mason sẽ hoạt động, nhưng tôi không chắc tại sao điều này lại xảy ra.
Lee Boon Kong

3

Bắt đầu từ phiên bản 4.6.0 trở đi, Tay lái cấm truy cập các thuộc tính nguyên mẫu và phương thức của đối tượng bối cảnh theo mặc định. Điều này có liên quan đến một vấn đề bảo mật được mô tả ở đây: https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html

Tham khảo https://github.com/wycats/handlebars.js/issues/1642

Nếu bạn chắc chắn rằng chỉ các nhà phát triển mới có quyền truy cập vào các mẫu, có thể cho phép truy cập nguyên mẫu bằng cách cài đặt gói sau:

npm i @handlebars/allow-prototype-access

Nếu bạn đang sử dụng tay lái nhanh, bạn nên tiến hành như sau:

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

Cảm ơn điều này đã làm việc. Vì vậy, chúng ta phải làm điều này mỗi khi chúng ta phải sử dụng tay lái nhanh?
Yash Boura

2

Có một sự thay đổi đột phá trong bản phát hành Tay cầm gần đây đã gây ra lỗi này.

Bạn chỉ có thể thêm các cấu hình mà họ đề xuất trong tài liệu của họ, tuy nhiên, hãy lưu ý, tùy thuộc vào bạn triển khai, điều này có thể dẫn đến lỗ hổng cho các cuộc tấn công XXS và RCE.

https://handlebarsjs.com/api-reference/r nb-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 vì vậy đó là nơi tôi thêm các tùy chọn, Cảm ơn rất nhiều!
Lee Boon Kong

1
Điều này đã không làm việc cho tôi. Một cuộc gọi lại đã được mong đợi, không phải là một đối tượng tùy chọn.
mrg95

0

Tạo một đối tượng hoặc mảng mới từ dữ liệu được trả về find() sẽ giải quyết vấn đề. Xem bên dưới một minh họa đơn giản

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")
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.