Skip to content

Conversation

@D3V41
Copy link
Contributor

@D3V41 D3V41 commented Jul 8, 2025

Status Quo

  • The getRealPath() method does not correctly validate the uri parameter and is returning incorrect results.

image

Changes

  • Fixed the getRealPath() method based on the values of ConvertToEdoc.realPath and ConvertToEdoc.contextPath.

  • Current values:

    • ConvertToEdoc.realPath: /home/vagrant/tomcat/apache-tomcat-9.0.41/webapps/oscar/
    • ConvertToEdoc.contextPath : /oscar
  • Based on these values, it appears that getRealPath() is intended to resolve the real path of the given uri within the oscar project directory. The implementation has been updated accordingly.

@D3V41 D3V41 marked this pull request as ready for review July 8, 2025 16:31
Copy link
Collaborator

@warrendennis warrendennis left a comment

Choose a reason for hiding this comment

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

More information needed. Please demonstrate where and how this fails, and how to test if it's fixed.

The intention of this method is to filter invalid relative paths from being executed in eForms. If a relative URI does not have a valid "real path" in the system, it will not be used See comment on line 517:
/*
* NO EXTERNAL LINKS. These are removed.
* eForms are often imported from unknown sources.
* Developers tend to use insecure CDN's, links to images, tracking tokens,
* and advertisements.
*/

@D3V41
Copy link
Contributor Author

D3V41 commented Jul 15, 2025

Code:

/*
* NO EXTERNAL LINKS. These are removed.
* eForms are often imported from unknown sources.
* Developers tend to use insecure CDN's, links to images, tracking tokens,
* and advertisements.
*/
if(path.startsWith("http") || path.startsWith("HTTP")) {
   element.remove();
}

// internal GET links are validated.
else if( path.contains("?") ) {
   // image or link paths with parameters
   parameters = path.split("\\?")[1];
}

else if(! path.isEmpty()) {
   // these are most likely relative context paths
   path = getRealPath( path );
   if(! path.isEmpty()) {
	potentialFilePaths.add(path);
   }
}

There are three main conditions in the above code:

  1. External resource check – It removes any external links (e.g., starting with http or HTTP).
  2. Links with query parameters – The parameters are extracted for further validation within OscarDocument.
  3. Relative paths – Checks whether the resource is a relative context path (as indicated by // these are most likely relative context paths) and verifies if it is present in the /oscar directory.

✅ I’ve fixed the logic related to this third condition (getRealPath()).

To reproduce the issue on the main branch:

  1. Create an Annual form in the EChart

    • 1
  2. Attach the Annual form to a Consultation Request, then click Submit Consultation Request & Print Preview.

    • 2
    • 3
  3. Upload the following sample eForm, but replace the img path with a any valid image from the Image Library first:

    • 3 1
    •  <!DOCTYPE html>
       <html lang="en">
       <head>
           <title>Form with Image</title>
       </head>
       <body>
           <form action="#" method="post">
               <script src="${oscar_javascript_path}jquery/jquery-3.6.4.min.js"></script>
               <img src="${oscar_image_path}labreq3.png" alt="Sample Image">
           </form>
       </body>
       </html>
  4. Open the uploaded eForm in the EChart and click Save.

    • 4
  5. Query the eform_data table and observe the HTML. The <script> tag will have been stripped from the content:

    •  SELECT * FROM eform_data ed ORDER BY ed.fdid DESC;
      

Now it is fixed.

D3V41 pushed a commit to MagentaHealth/Open-O that referenced this pull request Sep 4, 2025
20240814-QA-1 branch

Approved-by: Keith Chung
@warrendennis
Copy link
Collaborator

warrendennis commented Sep 15, 2025

Not sure I follow.
Is the problem that the <script> tag is stripped from the eForm data? How is this related to a relative path not being resolved correctly?
${oscar_image_path}labreq3.png is not considered relative. Please demonstrate an actual relative link that is not being resolved.

@D3V41
Copy link
Contributor Author

D3V41 commented Sep 19, 2025

Sorry for the confusing explanation. I will try to explain the issue again:

The issue is in the method getRealPath(String uri):

private static String getRealPath(String uri) {
    String contextRealPath = "";
    
    logger.debug("Context path set to " + contextPath);
    
    if (ConvertToEdoc.contextPath != null && ConvertToEdoc.realPath != null) {
        logger.debug("Relative file path " + uri);
        contextRealPath = Paths.get(ConvertToEdoc.realPath, ConvertToEdoc.realPath).toAbsolutePath().toString();
    }

    logger.debug("Absolute file path " + contextRealPath);

    return contextRealPath;
}
  • This method is not validating the uri correctly.
  • If you check line 586 in ConvertToEdoc.java in the main branch, that line is creating the contextRealPath by adding two ConvertToEdoc.realPath variables, which is wrong and completely ignores the uri variable.
  • Instead, it should use uri to get the correct real path.
  • Because of this invalid validation, the getRealPath() method can potentially remove valid paths from eForm and form.

Now, before I explain the issue, I have to mention that two static class-level variables are being used in the getRealPath() method. Those variables are contextPath and realPath. These variables are only initialized when we generate the PDF of any form.

In this PR, I have initialized these variables correctly while saving the eForm (AddEFormAction.java, line 206).

Now, the issue:

  • Even after initializing the contextPath and realPath correctly, the getRealPath() method will still not return the correct real path because it is not resolving the absolute path of the uri correctly (contextRealPath = Paths.get(ConvertToEdoc.realPath, ConvertToEdoc.realPath).toAbsolutePath().toString();).
  • Because of this, for example, if we add this new eForm in the system:
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Form with Image</title>
</head>
<body>
    <form action="#" method="post">
        <script src="${oscar_javascript_path}jquery/jquery-3.6.4.min.js"></script>
        <img src="${oscar_image_path}labreq3.png" alt="Sample Image">
    </form>
</body>
</html>
  • Then open it from the patient’s eChart. This is how it appears in the browser inspector:
<form action="../eform/addEForm.do?efmfid=91&amp;efmdemographic_no=1&amp;efmprovider_no=999998&amp;eform_link=null" name="saveEForm" method="POST">
    <script src="/oscar/library/jquery/jquery-3.6.4.min.js"></script>
    <img src="../eform/displayImage.do?imagefile=labreq3.png" alt="Sample Image" />
    <input type="hidden" id="otherFaxInput" />
    <div id="eformPageSpacer" class="hidden-print DoNotPrint no-print" style="position: absolute; left: 0px; width: 100%; margin: 0px; padding: 0px; height: 1px;"></div>
    <input id="subject" name="subject" type="hidden" />
    <div id="attachDocumentList"></div>
    <input id="0.28pl1tnk8h5-" name="openosp-image-link" value='{"id":"","value":"../eform/displayImage.do?imagefile=labreq3.png"}' type="hidden" />
</form>
  • Try saving the eForm. This is how it will look in the database:
<!doctype html>
<html lang="en">
<head>
    <title>Form with Image</title>
</head>
<body>
    <form action="../eform/addEForm.do?efmfid=91&amp;efmdemographic_no=1&amp;efmprovider_no=999998&amp;eform_link=null" name="saveEForm" method="POST">
        <img src="../eform/displayImage.do?imagefile=labreq3.png" alt="Sample Image">
    </form>
</body>
</html>
  • You will notice that the line <script src="${oscar_javascript_path}jquery/jquery-3.6.4.min.js"></script>
    is removed because getRealPath() is returning the wrong path. For example, if the realPath variable value is /home/oscar/, the method will return /home/oscar/home/oscar/, which is wrong. Later, when other code performs validation, it will remove that particular <script/> tag because the src path is invalid.

To solve this issue, I have added the correct logic in the getRealPath() method.

Why is this issue not occurring very often?

  • Normally, when we save any eForm, Oscar tries to find the real path using getRealPath(), but it does not execute properly because the realPath and contextPath variables are not initialized at that time.
  • As a result, the getRealPath() skips validation due to this condition:
if (ConvertToEdoc.contextPath != null && ConvertToEdoc.realPath != null)
  • However, when we generate a PDF of any form, these variables are initialized by the saveAsTempPDF() method in ConvertToEdoc.java at line 219.
  • Since they are defined at the class level(ConvertToEdoc.java at line 79), if someone tries to save an eForm after generating a PDF, the getRealPath() method will run validation.
  • And then, because the method has the wrong logic, it causes the removal of that particular element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants