fix(Authoring): Reject request if project is not valid JSON - #342
Open
eastagiletracker wants to merge 1 commit into
Open
Conversation
Validate the request body before it reaches disk. saveProject wrote the raw body to project.json first and only parsed it afterwards, so a malformed body replaced the stored unit with unparseable content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR proposes rejecting an authoring save request when the posted project content is not valid JSON, so a malformed body can no longer overwrite a unit's
project.jsonon disk (Fixes #320). We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/457. You can sign in with your GitHub ID to claim ownership of the project.The defect
AuthorAPIController.saveProjectwrites the request body to disk before anything parses it:The first parse of the body happens in
saveProjectToDatabase, two calls afterproject.jsonhas already been replaced. When an author posts content that is not valid JSON, the write succeeds, theJSONExceptionis swallowed by the surroundingcatch (Exception e), and the response iserrorSavingProject— so the author is told the save failed while the stored unit has in fact been replaced with unparseable content. The content cache was evicted on the line before, so the next read comes off the damaged file rather than from memory.The change
saveProjectnow parses the body first and returns before touching the cache or the file if it does not yield a JSON object. The guard sits after the existingcanAuthorProjectcheck, so the authorization behavior and its error code are unchanged.I kept the returned message code as the existing
errorSavingProjectrather than introducing a new one, deliberately:handleSaveProjectResponsein WISE-Client dispatches on exactlynotAllowedToEditThisProjectanderrorSavingProject, and a code outside that pair falls through both branches and would surface no message to the author at all. Reusing the existing code means the author-facing behavior is identical to today — the same "Error Saving Unit" banner — while the unit on disk survives.Validation is
new JSONObject(...), which is the same parse the downstream code already performs, so the guard accepts exactly the bodies the rest of the save path can handle. A JSON array is rejected along with malformed text, sincesaveProjectToDatabaseandgetMetadataFromProjectJSONStringboth require a top-level object.Reproducing it at current HEAD
On
developat 1958196, with the four new tests applied but the controller guard reverted:Each fails because the mocked
ProjectServiceis never asked to write anything, yet the controller callsevictProjectContentCacheandsaveProjectContentToDiskwith the malformed body. With the guard in place all four pass.Verification
The four tests cover malformed JSON, a top-level array, an empty body, and a null body. The full suite was run on a clean tree before the change and again after it, on JDK 17:
The identical set of pre-existing failures appears in both runs and is untouched by this change — the Hibernate DAO tests plus
WebSecurityConfigAuthorizationTest, which need a database this environment has none of (NoClassDefFoundError: Could not initialize class org.wise.portal.junit.AbstractTransactionalDbTests). No test that passed before this change fails after it, andAuthorAPIControllerTestgoes from 15 passing to 19.One note left deliberately out of scope:
createProjectwritesprojectJSONStringto a new unit'sproject.jsonon the same unvalidated path. Guarding it means either changing that endpoint'sStringreturn contract or throwing, so it seemed better left to your judgment than bundled in here.How this was managed
This work was tracked on a board imported from this repository's own issues and pull requests — 213 stories and 12 labels — with the fix carried by the story for this issue: fix(Authoring): Reject request if project is not valid JSON, on the board at https://eastagiletracker.com/projects/457.
If you'd rather not receive contributions like this, reply
no-more-prson this pull request and we won't open any further ones on your repositories.Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com