CVE-2024-29194 (TypeScript, published 2024-03-24T19:15Z)
Description: value: OneUptime is a solution for monitoring and managing online services. The vulnerability lies in the improper validation of client-side stored data within the web application. Specifically, the is_master_admin key, stored in the local storage of the browser, can be manipulated by an attacker. By changing this key from false to true, the application grants administrative privileges to the user, without proper server-side validation.  This has been patched in 7.0.1815.
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/OneUptime/oneuptime
Files changed:
CommonServer/Types/Database/ModelPermission.ts
Model/Models/BillingInvoice.ts
Model/Models/OnCallDutyPolicyEscalationRule.ts
Model/Models/OnCallDutyPolicyEscalationRuleSchedule.ts
Model/Models/OnCallDutyPolicyEscalationRuleTeam.ts
Model/Models/OnCallDutyPolicyEscalationRuleUser.ts
Model/Models/OnCallDutyPolicyExecutionLog.ts
Model/Models/OnCallDutyPolicyExecutionLogTimeline.ts
Model/Models/OnCallDutyPolicySchedule.ts
Model/Models/OnCallDutyPolicyScheduleLayer.ts
Model/Models/OnCallDutyPolicyScheduleLayerUser.ts
Model/Models/User.ts
Commit message: Add deletedByUserId property to several models


Vulnerable code:
    read: [
        Permission.CurrentUser,
        Permission.ProjectAdmin,
        Permission.ProjectOwner,
    ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],
        read: [
            Permission.CurrentUser,
            Permission.ProjectAdmin,
            Permission.ProjectOwner,
        ],

Fixed code:
import UserModel from 'Common/Models/UserModel';
            // add user scope if any

            query = await this.addUserScopeToQuery(modelType, query, props);

    private static async addUserScopeToQuery<TBaseModel extends BaseModel>(
        modelType: { new (): TBaseModel },
        query: Query<TBaseModel>,
        props: DatabaseCommonInteractionProps
    ): Promise<Query<TBaseModel>> {
        const model: BaseModel = new modelType();

        if (model instanceof UserModel) {
            if (props.userId) {
                (query as any)['_id'] = props.userId;
            } else if (!props.isRoot && !props.isMasterAdmin) {
                throw new NotAuthorizedException(
                    `You do not have permissions to query on - ${model.singularName}.`
                );
            }
        }

        return query;
    }


    @ColumnAccessControl({
        create: [],
        read: [],
        update: [],
    })
    @TableColumn({
        type: TableColumnType.ObjectID,
        title: 'Deleted by User ID',
        description:
            'User ID who deleted this object (if this object was deleted by a User)',
    })
    @Column({
        type: ColumnType.ObjectID,
        nullable: true,
        transformer: ObjectID.getDatabaseTransformer(),
    })
    public deletedByUserId?: ObjectID = undefined;




    @ColumnAccessControl({
        create: [],
        read: [],
        update: [],
    })
    @TableColumn({
        type: TableColumnType.ObjectID,
        title: 'Deleted by User ID',
        description:
            'User ID who deleted this object (if this object was deleted by a User)',
    })
    @Column({
        type: ColumnType.ObjectID,
        nullable: true,
        transformer: ObjectID.getDatabaseTransformer(),
    })
    public deletedByUserId?: ObjectID = undefined;

    @ColumnAccessControl({
        create: [],
        read: [],
        update: [],
    })
    @TableColumn({
        type: TableColumnType.ObjectID,
        title: 'Deleted by User ID',
        description:
            'User ID who deleted this object (if this object was deleted by a User)',
    })
    @Column({
        type: ColumnType.ObjectID,
        nullable: true,
        transformer: ObjectID.getDatabaseTransformer(),
    })
    public deletedByUserId?: ObjectID = undefined;

    @ColumnAccessControl({
        create: [],
        read: [],
        update: [],
    })
    @TableColumn({
        type: TableColumnType.ObjectID,
        title: 'Deleted by User ID',
        description:
            'User ID who deleted this object (if this object was deleted by a User)',
    })
    @Column({
        type: ColumnType.ObjectID,
        nullable: true,
        transformer: ObjectID.getDatabaseTransformer(),
    })
    public deletedByUserId?: ObjectID = undefined;

    

    @ColumnAccessControl({
        create: [],
        read: [],
        update: [],
    })
    @TableColumn({
        type: TableColumnType.ObjectID,
        title: 'Deleted by User ID',
        description:
            'User ID who deleted this object (if this object was deleted by a User)',
    })
    @Column({
        type: ColumnType.ObjectID,
        nullable: true,
        transformer: ObjectID.getDatabaseTransformer(),
    })
    public deletedByUserId?: ObjectID = undefined;

    

    
    
    read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],
        canReadOnRelationQuery: true,
        read: [Permission.CurrentUser],
        read: [Permission.CurrentUser],