Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

validateRideLength accepts any Object.prototype key as a ride length

Đang mở Phù hợp với người mới
#1,089 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 7 ngày

@gangster đang làm issue này rồi.

Từ ngày 5/8/2026.

  • #1090 của @gangster — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
javascript
Lĩnh vực
backend, database

Hướng nghiên cứu

Bắt đầu trong app/models/calEventValidator.js tại validateRideLength và chạy bản tái hiện bằng node từ issue trong thư mục app. Kiểm tra việc xác thực own-property và hành vi của biến cục bộ đối với các giá trị thực và giá trị Prototype-Key được liệt kê. Hoàn tất khi các độ dài chuyến đi hợp lệ vẫn được chấp nhận, các khóa prototype bị từ chối và không có giá trị toàn cục nào được tạo.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

validateRideLength uses the in operator to check a submitted ride length against the known values. in walks the prototype chain, so alongside the four real lengths it also accepts every property inherited from Object.prototype — toString, constructor, hasOwnProperty, valueOf, __proto__ — and returns them unchanged, with no validation error.

Those values reach the database and are rendered back on the event page.

Reproducing

From the app directory:

node -e "
const { makeValidator, ErrorCollector } = require('./models/calEventValidator');
for (const v of ['0-3', 'bogus', 'toString', 'constructor', '__proto__']) {
  const errors = new ErrorCollector();
  const got = makeValidator({ ridelength: v }, errors).validateRideLength('ridelength');
  console.log(JSON.stringify(v).padEnd(15), '->', JSON.stringify(got));
}"

On main this prints:

"0-3"           -> "0-3"          (correct)
"bogus"         -> null           (correctly rejected)
"toString"      -> "toString"     (should be null)
"constructor"   -> "constructor"  (should be null)
"__proto__"     -> "__proto__"    (should be null)

hasOwnProperty and valueOf behave the same way. None of them record a validation error.

It reaches the database and the page

Posting an otherwise valid event to manage_event with ridelength: "constructor" (payload shape per CALENDAR_API.md) returns 200, and reading the event back through retrieve_event confirms it stored:

ridelength: "constructor"

EventDetails.vue renders the field directly:

rideLength() {
  if (this.evt.ridelength) {
    return `${this.evt.ridelength} miles`;
  }

so the event details page then displays "constructor miles".

Cause

app/models/calEventValidator.js:

validateRideLength(rideLength) {
  value = getString(rideLength);
  return (value in RideLength) ? value : null;
}

RideLength is an ordinary frozen object, so it still inherits from Object.prototype, and in finds those inherited keys.

A second, smaller problem in the same function

value is assigned without const/let, so it becomes an implicit global on every call — confirmed with globalThis.value === "0-3" after one call. It is harmless today only because this file is non-strict CommonJS; it would throw a ReferenceError under ESM or "use strict", which is where the rest of the project is heading.

Suggested fix

Use an own-property check, and declare the local:

-    validateRideLength(rideLength) {
-      value = getString(rideLength);
-      return (value in RideLength) ? value : null;
-    },
+    validateRideLength(field) {
+      const value = getString(field);
+      return Object.hasOwn(RideLength, value) ? value : null;
+    },

Severity

Low. The column is a varchar, and Vue escapes its output, so this is bad data rather than injection — an organizer can write arbitrary prototype-key strings into a public field on their own ride. Worth fixing because it is small, and because the same in-instead-of-own-property pattern is easy to copy into somewhere it matters more.

Not changed

Unlike the other validators, this one silently returns null for an unrecognised value rather than recording an error via errors.addError(field). That may well be deliberate — rejecting a bad ride length outright would fail the whole save — so I have left the behaviour alone. Flagging it in case it should be revisited separately.

Ngôn ngữ chính
JavaScript
Star
30
Fork
26
Merge trung bình
6 ngày 24 phút
Pull request đã merge (30 ngày)
6

Chuẩn bị môi trường

  • Có Dockerfile hoặc tệp Docker Compose
  • Không có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của shift-org/shift-docs

Tất cả issue của shift-org/shift-docs

Issue tương tự

Thêm issue về JavaScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.