Skip to content

fix: resolve scorm assets at the exact requested path#114

Open
djoseph-apphelix wants to merge 1 commit into
overhangio:masterfrom
djoseph-apphelix:djoseph/fix-assets-proxy-path-resolution
Open

fix: resolve scorm assets at the exact requested path#114
djoseph-apphelix wants to merge 1 commit into
overhangio:masterfrom
djoseph-apphelix:djoseph/fix-assets-proxy-path-resolution

Conversation

@djoseph-apphelix
Copy link
Copy Markdown

Overview

Fix SCORM asset proxy resolution so asset requests prefer the exact requested path instead of resolving by basename only.

Previously, assets_proxy discarded the directory portion of the requested URL and recursively searched for the first file with the same basename. Packages containing duplicate filenames at different paths could therefore serve the wrong asset, causing runtime failures such as blank-page rendering in Articulate Rise exports with multiple scormdriver.js files.

Reported issue

Issue No:112

Details

  • Try the exact extracted asset path first.
  • Preserve the legacy basename fallback for compatibility when the exact path is not found.
  • Add validation for invalid asset paths:
    • empty paths
    • directory-only paths
    • path traversal via ..
    • URL-encoded traversal such as %2E%2E
    • absolute paths
    • Windows drive-style paths
    • null bytes
  • Return 400 Bad Request for invalid asset URLs instead of surfacing an unhandled exception.
  • Avoid reflecting rejected path input in the response body.
  • Add focused tests for exact-path resolution, fallback behavior, and invalid path rejection.

Notes

The basename fallback is intentionally preserved for backward compatibility, but exact-path lookup now handles normal requests first to avoid duplicate-basename collisions.

Invalid asset URLs now return 400 Bad Request. The pre-existing ScormError behavior for missing files found via find_file_path is unchanged in this PR.

Testing

python -m pytest openedxscorm/tests.py -k 'assets_proxy or clean_asset_path'

Result:

36 passed, 19 deselected

"""
cleaned = urllib.parse.unquote(self.clean_path(path))
if not cleaned or "\x00" in cleaned or cleaned.endswith(("/", OS_PATH_ALT_SEP)):
raise ScormError("Invalid asset path")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with the error, we should log what kind of path scorm is expecting. Similarly below.

try:
clean_suffix = self.clean_asset_path(suffix)
except ScormError:
logger.warning("Invalid asset path: %r", suffix)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger.warning("Invalid asset path: %r", suffix)
logger.error("Invalid asset path: %r", suffix)

Comment thread openedxscorm/tests.py
)
return block

@staticmethod
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the fact that you added tests. Thank you so much for this!

@ahmed-arb ahmed-arb moved this from Pending Triage to In review in Tutor project management May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

4 participants