Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XXE vulnerability fix #178

Merged
merged 5 commits into from Aug 29, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next
XXE fix
  • Loading branch information
joniles committed Aug 29, 2020
commit c3e457f7a16facfe563eade82b0fa8736a8c96f9
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,6 +1,7 @@
# Changelog

## 8.1.4 (git master)
* XXE security vulnerability
* Import milestone constraints from Asta schedules (Contributed by Dave McKay)
* Handle elapsed durations in Asta schedules (Based on a contribution by Dave McKay)
* Correctly determine the constraint type for tasks with ALAP placement with or without predecessors when reading from from Asta schedules (Contributed by Dave McKay)
Expand Down
1 change: 1 addition & 0 deletions src/changes/changes.xml
Expand Up @@ -6,6 +6,7 @@
</properties>
<body>
<release date="git master" version="8.1.4">
<action dev="joniles" type="update">XXE security vulnerability</action>
<action dev="joniles" type="update">Import milestone constraints from Asta schedules (Contributed by Dave McKay)</action>
<action dev="joniles" type="update">Handle elapsed durations in Asta schedules (Based on a contribution by Dave McKay)</action>
<action dev="joniles" type="update">Correctly determine the constraint type for tasks with ALAP placement with or without predecessors when reading from from Asta schedules (Contributed by Dave McKay)</action>
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/net/sf/mpxj/common/UnmarshalHelper.java
@@ -0,0 +1,104 @@
/*
* file: UnmarshalHelper.java
* author: Jon Iles
* copyright: (c) Packwood Software 2020
* date: 29/08/2020
*/

/*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/

package net.sf.mpxj.common;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;

/**
* Utility methods wrapping JAXB unmarshal.
*/
public final class UnmarshalHelper
{
/**
* Unmarshal from an input stream.
*
* @param context JAXB context
* @param stream input stream
* @return Unmarshalled root node
*/
public static final Object unmarshal(JAXBContext context, InputStream stream) throws JAXBException, SAXException, ParserConfigurationException
{
return context.createUnmarshaller().unmarshal(new SAXSource(XmlReaderHelper.createXmlReader(), new InputSource(stream)));
}

/**
* Unmarshall from an input stream and apply a filter.
*
* @param context JAXB context
* @param stream input stream
* @param filter XMLFilter instance
* @return Unmarshalled root node
*/
public static final Object unmarshal(JAXBContext context, InputStream stream, XMLFilter filter) throws JAXBException, SAXException, ParserConfigurationException, IOException
{
return unmarshal(context, new InputSource(stream), filter, false);
}

/**
* Unmarshall from an input source and apply a filter, optionally ignore validation errors.
*
* @param context JAXB context
* @param source input source
* @param filter XMLFilter instance
* @param ignoreValidationErrors true if validation errors are ignored
* @return Unmarshalled root node
*/
public static final Object unmarshal(JAXBContext context, InputSource source, XMLFilter filter, boolean ignoreValidationErrors) throws JAXBException, SAXException, ParserConfigurationException, IOException
{
Unmarshaller unmarshaller = context.createUnmarshaller();

if (ignoreValidationErrors)
{
unmarshaller.setEventHandler(new ValidationEventHandler()
{
@Override public boolean handleEvent(ValidationEvent event)
{
return true;
}
});
}

UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
filter.setParent(XmlReaderHelper.createXmlReader());
filter.setContentHandler(unmarshallerHandler);
filter.parse(source);

return unmarshallerHandler.getResult();
}

}
51 changes: 51 additions & 0 deletions src/main/java/net/sf/mpxj/common/XmlReaderHelper.java
@@ -0,0 +1,51 @@
/*
* file: XmlReaderHelper.java
* author: Jon Iles
* copyright: (c) Packwood Software 2020
* date: 29/08/2020
*/

/*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/

package net.sf.mpxj.common;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
* Utility methods for working with XmlReader.
*/
public final class XmlReaderHelper
{
/**
* Create a new XmlReader instance.
*
* @return XmlReader instance
*/
public static final XMLReader createXmlReader() throws SAXException, ParserConfigurationException
{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setNamespaceAware(true);
SAXParser saxParser = factory.newSAXParser();
return saxParser.getXMLReader();
}
}
Expand Up @@ -25,7 +25,6 @@

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Expand All @@ -36,16 +35,9 @@

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;

import net.sf.mpxj.DateRange;
import net.sf.mpxj.Duration;
Expand All @@ -65,6 +57,7 @@
import net.sf.mpxj.Task;
import net.sf.mpxj.TimeUnit;
import net.sf.mpxj.common.AlphanumComparator;
import net.sf.mpxj.common.UnmarshalHelper;
import net.sf.mpxj.conceptdraw.schema.Document;
import net.sf.mpxj.conceptdraw.schema.Document.Calendars.Calendar;
import net.sf.mpxj.conceptdraw.schema.Document.Calendars.Calendar.ExceptedDays.ExceptedDay;
Expand Down Expand Up @@ -99,6 +92,11 @@ public final class ConceptDrawProjectReader extends AbstractProjectReader
{
try
{
if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

m_projectFile = new ProjectFile();
m_eventManager = m_projectFile.getEventManager();
m_calendarMap = new HashMap<>();
Expand All @@ -113,23 +111,7 @@ public final class ConceptDrawProjectReader extends AbstractProjectReader

m_eventManager.addProjectListeners(m_projectListeners);

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();

if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

Unmarshaller unmarshaller = CONTEXT.createUnmarshaller();

XMLFilter filter = new NamespaceFilter();
filter.setParent(xmlReader);
UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
filter.setContentHandler(unmarshallerHandler);
filter.parse(new InputSource(new InputStreamReader(stream)));
Document cdp = (Document) unmarshallerHandler.getResult();
Document cdp = (Document) UnmarshalHelper.unmarshal(CONTEXT, stream, new NamespaceFilter());

readProjectProperties(cdp);
readCalendars(cdp);
Expand Down
26 changes: 7 additions & 19 deletions src/main/java/net/sf/mpxj/ganttdesigner/GanttDesignerReader.java
Expand Up @@ -31,15 +31,9 @@

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import net.sf.mpxj.ChildTaskContainer;
import net.sf.mpxj.Day;
Expand All @@ -54,6 +48,7 @@
import net.sf.mpxj.ProjectProperties;
import net.sf.mpxj.RelationType;
import net.sf.mpxj.Task;
import net.sf.mpxj.common.UnmarshalHelper;
import net.sf.mpxj.ganttdesigner.schema.Gantt;
import net.sf.mpxj.ganttdesigner.schema.GanttDesignerRemark;
import net.sf.mpxj.listener.ProjectListener;
Expand Down Expand Up @@ -83,6 +78,11 @@ public final class GanttDesignerReader extends AbstractProjectReader
{
try
{
if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

m_projectFile = new ProjectFile();
m_eventManager = m_projectFile.getEventManager();
m_taskMap = new HashMap<>();
Expand All @@ -95,19 +95,7 @@ public final class GanttDesignerReader extends AbstractProjectReader

m_eventManager.addProjectListeners(m_projectListeners);

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
SAXSource doc = new SAXSource(xmlReader, new InputSource(stream));

if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

Unmarshaller unmarshaller = CONTEXT.createUnmarshaller();

Gantt gantt = (Gantt) unmarshaller.unmarshal(doc);
Gantt gantt = (Gantt) UnmarshalHelper.unmarshal(CONTEXT, stream);

readProjectProperties(gantt);
readCalendar(gantt);
Expand Down
26 changes: 7 additions & 19 deletions src/main/java/net/sf/mpxj/ganttproject/GanttProjectReader.java
Expand Up @@ -37,15 +37,9 @@

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import net.sf.mpxj.ChildTaskContainer;
import net.sf.mpxj.ConstraintType;
Expand Down Expand Up @@ -76,6 +70,7 @@
import net.sf.mpxj.common.Pair;
import net.sf.mpxj.common.ResourceFieldLists;
import net.sf.mpxj.common.TaskFieldLists;
import net.sf.mpxj.common.UnmarshalHelper;
import net.sf.mpxj.ganttproject.schema.Allocation;
import net.sf.mpxj.ganttproject.schema.Allocations;
import net.sf.mpxj.ganttproject.schema.Calendars;
Expand Down Expand Up @@ -118,6 +113,11 @@ public final class GanttProjectReader extends AbstractProjectReader
{
try
{
if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

m_projectFile = new ProjectFile();
m_eventManager = m_projectFile.getEventManager();
m_resourcePropertyDefinitions = new HashMap<>();
Expand All @@ -137,19 +137,7 @@ public final class GanttProjectReader extends AbstractProjectReader

m_eventManager.addProjectListeners(m_projectListeners);

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
SAXSource doc = new SAXSource(xmlReader, new InputSource(stream));

if (CONTEXT == null)
{
throw CONTEXT_EXCEPTION;
}

Unmarshaller unmarshaller = CONTEXT.createUnmarshaller();

Project ganttProject = (Project) unmarshaller.unmarshal(doc);
Project ganttProject = (Project) UnmarshalHelper.unmarshal(CONTEXT, stream);

readProjectProperties(ganttProject);
readCalendars(ganttProject);
Expand Down