CVE-2021-3852 (JavaScript, published 2022-01-12T11:15Z)
Description: value: growi is vulnerable to Authorization Bypass Through User-Controlled Key
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-639 \u2014 Authorization Bypass Through User-Controlled Key
The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.
Repository: https://github.com/weseek/growi
Files changed:
packages/app/src/client/services/CommentContainer.js
packages/app/src/components/PageComment/Comment.jsx
packages/app/src/server/models/comment.js
packages/app/src/server/routes/comment.js
Commit message: imprv: Permissions to operate comment (#4466)

* check author when updating and removing

* restrict to show controls when the user is not the author

Vulnerable code:
        page_id: pageId,
        revision_id: revisionId,
        author,
  checkPermissionToControlComment() {
    return this.props.appContainer.isAdmin || this.isCurrentUserEqualsToAuthor();
  }

              {this.checkPermissionToControlComment() && (
  commentSchema.statics.updateCommentsByPageId = function(comment, isMarkdown, commentId) {
    const Comment = this;

    return Comment.findOneAndUpdate(
      { _id: commentId },
      { $set: { comment, isMarkdown } },
    );

  };

   *                          comment_position:
   *                            $ref: '#/components/schemas/Comment/properties/commentPosition'
    const pageId = commentForm.page_id;
    const comment = commentForm.comment;
    const author = commentForm.author;
    if (comment === '') {
    if (author !== req.user.username) {
      return res.json(ApiResponse.error('Only the author can edit'));
    }

    // check whether accessible
    const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
    if (!isAccessible) {
      return res.json(ApiResponse.error('Current user is not accessible to this page.'));
    }

      updatedComment = await Comment.updateCommentsByPageId(comment, isMarkdown, commentId);

Fixed code:
        revision_id: revisionId,
              {this.isCurrentUserEqualsToAuthor() && (
   *                          comment_id:
   *                            $ref: '#/components/schemas/Comment/properties/_id'
    const commentStr = commentForm.comment;
    const revision = commentForm.revision_id;
    if (commentStr === '') {
      const comment = await Comment.findById(commentId).exec();

      if (comment == null) {
        throw new Error('This comment does not exist.');
      }

      // check whether accessible
      const pageId = comment.page;
      const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
      if (!isAccessible) {
        throw new Error('Current user is not accessible to this page.');
      }
      if (req.user.id !== comment.creator.toString()) {
        throw new Error('Current user is not operatable to this comment.');
      }

      updatedComment = await Comment.findOneAndUpdate(
        { _id: commentId },
        { $set: { comment: commentStr, isMarkdown, revision } },
      );
      if (req.user.id !== comment.creator.toString()) {
        throw new Error('Current user is not operatable to this comment.');
      }