Skip to content
Permalink
Browse files Browse the repository at this point in the history
OO-5548: setup security of XStream by default
  • Loading branch information
lainsr committed Jun 21, 2021
1 parent 6b191a5 commit 3f219ac
Show file tree
Hide file tree
Showing 73 changed files with 2,868 additions and 151 deletions.
8 changes: 6 additions & 2 deletions src/main/java/de/bps/course/nodes/ChecklistCourseNode.java
Expand Up @@ -309,6 +309,7 @@ public void cleanupOnDelete(ICourse course) {
@Override
public void exportNode(File exportDirectory, ICourse course) {
XStream xstream = XStreamHelper.createXStreamInstance();
XStreamHelper.allowDefaultPackage(xstream);
ChecklistManager cm = ChecklistManager.getInstance();
Checklist checklist = loadOrCreateChecklist(course.getCourseEnvironment().getCoursePropertyManager());
Checklist copy = cm.copyChecklistInRAM(checklist);
Expand All @@ -328,13 +329,14 @@ public void importNode(File importDirectory, ICourse course, Identity owner, Org
}

XStream xstream = XStreamHelper.createXStreamInstance();
XStreamHelper.allowDefaultPackage(xstream);
Checklist checklist = (Checklist) xstream.fromXML(importContent);
if(checklist != null) {
checklist = ChecklistManager.getInstance().copyChecklist(checklist);
setChecklistKey(cpm, checklist.getKey());
}
}

@Override
public boolean archiveNodeData(Locale locale, ICourse course, ArchiveOptions options,
ZipOutputStream exportStream, String archivePath, String charset) {
Expand All @@ -344,7 +346,9 @@ public boolean archiveNodeData(Locale locale, ICourse course, ArchiveOptions opt
filename = ZipUtil.concat(archivePath, filename);

Checklist checklist = loadOrCreateChecklist(course.getCourseEnvironment().getCoursePropertyManager());
String exportContent = XStreamHelper.createXStreamInstance().toXML(checklist);
XStream xstream = XStreamHelper.createXStreamInstance();
XStreamHelper.allowDefaultPackage(xstream);
String exportContent = xstream.toXML(checklist);
try {
exportStream.putNextEntry(new ZipEntry(filename));
IOUtils.write(exportContent, exportStream, "UTF-8");
Expand Down
24 changes: 11 additions & 13 deletions src/main/java/de/bps/olat/portal/links/LinksPortlet.java
Expand Up @@ -79,6 +79,15 @@ public class LinksPortlet extends AbstractPortlet {
private static final String ELEM_LINK_TARGET = "Target";
private static final String ELEM_LINK_LANG = "Language";

private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xstream);
xstream.alias("LinksPortlet", Map.class);
xstream.alias(ELEM_LINK, PortletLink.class);
xstream.alias(ELEM_INSTITUTION, PortletInstitution.class);
xstream.aliasAttribute(PortletInstitution.class, ATTR_INSTITUTION_NAME, ATTR_INSTITUTION_NAME);
}

private static HashMap<String, PortletInstitution> content;

private static File fxConfXStreamFile;
Expand Down Expand Up @@ -155,24 +164,13 @@ private static void init() {
saveLinkList(content);
FileUtils.copyFileToFile(fxConfFile, new File(fxConfFile + ".bak"), true);
} else {
XStream xstream = XStreamHelper.createXStreamInstance();
xstream.alias("LinksPortlet", Map.class);
xstream.alias(ELEM_LINK, PortletLink.class);
xstream.alias(ELEM_INSTITUTION, PortletInstitution.class);
xstream.aliasAttribute(PortletInstitution.class, ATTR_INSTITUTION_NAME, ATTR_INSTITUTION_NAME);
content = (HashMap<String, PortletInstitution>) XStreamHelper.readObject(xstream, fxConfXStreamFile);
}
}

public static boolean saveLinkList(HashMap<String, PortletInstitution> portletMap){
XStream xstream = XStreamHelper.createXStreamInstance();
xstream.alias("LinksPortlet", Map.class);
xstream.alias(ELEM_LINK, PortletLink.class);
xstream.alias(ELEM_INSTITUTION, PortletInstitution.class);
xstream.aliasAttribute(PortletInstitution.class, ATTR_INSTITUTION_NAME, ATTR_INSTITUTION_NAME);
String output = xstream.toXML(portletMap);
public static boolean saveLinkList(Map<String, PortletInstitution> portletMap){
XStreamHelper.writeObject(xstream, fxConfXStreamFile, portletMap);
return (output.length() != 0);
return true;
}

public static PortletLink getLinkByIdentifier(String identifier){
Expand Down
Expand Up @@ -108,6 +108,7 @@ public boolean isUserInteractionRequired(UserRequest ureq) {
*/
public boolean changeEMail(WindowControl wControl) {
XStream xml = XStreamHelper.createXStreamInstance();
XStreamHelper.allowDefaultPackage(xml);
@SuppressWarnings("unchecked")
HashMap<String, String> mails = (HashMap<String, String>) xml.fromXML(tempKey.getEmailAddress());

Expand Down
Expand Up @@ -44,6 +44,7 @@ public class LandingPagesModule extends AbstractSpringModule {
private static final XStream rulesXStream;
static {
rulesXStream = XStreamHelper.createXStreamInstance();
XStreamHelper.allowDefaultPackage(rulesXStream);
rulesXStream.alias("rules", Rules.class);
rulesXStream.alias("rule", Rule.class);
}
Expand Down
Expand Up @@ -79,6 +79,7 @@ public class GlossaryItemManager {

private static final XStream xstreamReader = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xstreamReader);
xstreamReader.alias(XML_GLOSSARY_ITEM_NAME, GlossaryItem.class);
xstreamReader.alias(XML_REVISION_NAME, Revision.class);
}
Expand All @@ -102,6 +103,7 @@ protected void writeText(QuickWriter writer, String text) {
});

static {
XStreamHelper.allowDefaultPackage(xstreamReader);
xstreamWriter.alias(XML_GLOSSARY_ITEM_NAME, GlossaryItem.class);
xstreamWriter.alias(XML_REVISION_NAME, Revision.class);
}
Expand Down Expand Up @@ -229,7 +231,7 @@ public boolean isFolderContainingGlossary(VFSContainer folderContainingGlossary)
* @param glossaryFile
* @param glossaryItemArr
*/
private void saveToFile(VFSLeaf glossaryFile, List<GlossaryItem> glossaryItemArr) {
protected final void saveToFile(VFSLeaf glossaryFile, List<GlossaryItem> glossaryItemArr) {
// cdata-tags should be used instead of strings, overwrite writer.
glossaryItemArr = removeEmptyGlossaryItems(glossaryItemArr);
XStreamHelper.writeObject(xstreamWriter, glossaryFile, glossaryItemArr);
Expand Down Expand Up @@ -274,7 +276,7 @@ private void updateCacheForGlossary(VFSContainer glossaryFolder, List<GlossaryIt
* @return list with GlossaryItem's
*/
@SuppressWarnings("unchecked")
private List<GlossaryItem> loadGlossaryItemListFromFile(VFSLeaf glossaryFile) {
protected final List<GlossaryItem> loadGlossaryItemListFromFile(VFSLeaf glossaryFile) {
List<GlossaryItem> glossaryItemList = new ArrayList<>();
if (glossaryFile == null) { return new ArrayList<>(); }

Expand Down
Expand Up @@ -39,7 +39,6 @@ class DiscoveryXStream {

private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
XStream.setupDefaultSecurity(xstream);
Class<?>[] types = new Class[] {
DiscoveryImpl.class, NetZoneImpl.class, AppImpl.class, ActionImpl.class, ProofKeyImpl.class
};
Expand Down
Expand Up @@ -44,6 +44,7 @@ class LicenseXStreamHelper {

private static final XStream licenseXStream = XStreamHelper.createXStreamInstanceForDBObjects();
static {
XStreamHelper.allowDefaultPackage(licenseXStream);
licenseXStream.alias("license", LicenseImpl.class);
licenseXStream.alias("license", ResourceLicenseImpl.class);
licenseXStream.alias("licenseType", LicenseTypeImpl.class);
Expand Down
Expand Up @@ -50,6 +50,9 @@
public class PersistentTaskDAO {

private static XStream xstream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xstream);
}

@Autowired
private DB dbInstance;
Expand All @@ -61,7 +64,7 @@ public PersistentTask createTask(String name, Serializable task) {
ptask.setLastModified(currentDate);
ptask.setName(name);
ptask.setStatus(TaskStatus.newTask);
ptask.setTask(xstream.toXML(task));
ptask.setTask(toXML(task));
dbInstance.getCurrentEntityManager().persist(ptask);
return ptask;
}
Expand All @@ -78,7 +81,7 @@ public PersistentTask createTask(String name, Serializable task,
ptask.setResource(resource);
ptask.setResSubPath(resSubPath);
ptask.setStatus(TaskStatus.newTask);
ptask.setTask(xstream.toXML(task));
ptask.setTask(toXML(task));
dbInstance.getCurrentEntityManager().persist(ptask);
return ptask;
}
Expand Down Expand Up @@ -189,7 +192,7 @@ public PersistentTask updateTask(Task task, Serializable runnableTask, Identity
ptask.setScheduledDate(scheduledDate);
ptask.setStatus(TaskStatus.newTask);
ptask.setStatusBeforeEditStr(null);
ptask.setTask(xstream.toXML(runnableTask));
ptask.setTask(toXML(runnableTask));

ptask = dbInstance.getCurrentEntityManager().merge(ptask);
if(modifier != null) {
Expand Down Expand Up @@ -249,6 +252,11 @@ public void taskFailed(PersistentTask task) {
dbInstance.commit();
}


protected static String toXML(Serializable task) {
return xstream.toXML(task);
}

public Runnable deserializeTask(PersistentTask task) {
return (Runnable)xstream.fromXML(task.getTask());
}
Expand Down
Expand Up @@ -53,7 +53,6 @@ public class VFSXStream {
private static XStream mystream;
static {
mystream = XStreamHelper.createXStreamInstance();
XStream.setupDefaultSecurity(mystream);
Class<?>[] types = new Class[] {
VersionsFileImpl.class, RevisionFileImpl.class, VFSRevision.class,
VFSMetadata.class, VFSMetadataImpl.class, Identity.class, IdentityImpl.class,
Expand Down
Expand Up @@ -34,13 +34,20 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.thoughtworks.xstream.XStream;

/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
@Service("mapperDao")
public class MapperDAO {

private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xstream);
}

@Autowired
private DB dbInstance;

Expand All @@ -66,13 +73,21 @@ public PersistedMapper persistMapper(String sessionId, String mapperId, Serializ
}
m.setOriginalSessionId(sessionId);

String configuration = XStreamHelper.createXStreamInstance().toXML(mapper);
String configuration = xstream.toXML(mapper);
m.setXmlConfiguration(configuration);

dbInstance.getCurrentEntityManager().persist(m);
return m;
}

protected static String toXml(Object mapper) {
return xstream.toXML(mapper);
}

public static Object fromXML(String configuration) {
return xstream.fromXML(configuration);
}

/**
* Update a persisted mapper.
*
Expand All @@ -82,7 +97,7 @@ public PersistedMapper persistMapper(String sessionId, String mapperId, Serializ
* @return
*/
public boolean updateConfiguration(String mapperId, Serializable mapper, int expirationTime) {
String configuration = XStreamHelper.createXStreamInstance().toXML(mapper);
String configuration = xstream.toXML(mapper);
Date currentDate = new Date();
Date expirationDate = null;
if(expirationTime > 0) {
Expand Down Expand Up @@ -120,7 +135,7 @@ public Mapper retrieveMapperById(String mapperId) {
if(pm != null && StringHelper.containsNonWhitespace(pm.getXmlConfiguration())) {
String configuration = pm.getXmlConfiguration();

Object obj = XStreamHelper.createXStreamInstance().fromXML(configuration);
Object obj = xstream.fromXML(configuration);
if(obj instanceof Mapper) {
return (Mapper)obj;
}
Expand Down
Expand Up @@ -77,6 +77,7 @@ public class SiteDefinitions extends AbstractSpringModule {

private static final XStream xStream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xStream);
xStream.alias("coursesite", CourseSiteConfiguration.class);
xStream.alias("languageConfig", LanguageConfiguration.class);
xStream.alias("siteconfig", SiteConfiguration.class);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/olat/core/id/context/HistoryManager.java
Expand Up @@ -57,6 +57,9 @@ public class HistoryManager {
private static XStream historyReadStream = XStreamHelper.createXStreamInstance();
private static XStream historyWriteStream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(historyReadStream);
XStreamHelper.allowDefaultPackage(historyWriteStream);

//xstream config
historyReadStream.omitField(BusinessGroup.class, "type");
historyReadStream.omitField(BusinessGroup.class, "ownerGroup");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/olat/core/util/prefs/db/DbStorage.java
Expand Up @@ -57,6 +57,7 @@ public class DbStorage implements PreferencesStorage {

private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
XStreamHelper.allowDefaultPackage(xstream);
xstream.ignoreUnknownElements();
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/olat/core/util/xml/EnhancedXStream.java
Expand Up @@ -43,9 +43,9 @@
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class EnhancedXStream extends XStream {
class EnhancedXStream extends XStream {

public EnhancedXStream(boolean export) {
EnhancedXStream(boolean export) {
super();

if (export) {
Expand Down
33 changes: 25 additions & 8 deletions src/main/java/org/olat/core/util/xml/XStreamHelper.java
Expand Up @@ -36,6 +36,7 @@
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

Expand Down Expand Up @@ -82,10 +83,22 @@
* @author Felix Jost, Florian Gnaegi
*/
public class XStreamHelper {
private static final String ENCODING = "UTF-8";

private static XStream unconfiguredXStream = new XStream();
private static final String[] DEFAULT_PACKAGES = new String[] {
"org.olat.**",
"de.bps.**",
"at.ac.uibk.**",
"org.hibernate.**"
};
private static final XStream unconfiguredXStream = new XStream();
static {
XStream.setupDefaultSecurity(unconfiguredXStream);
allowDefaultPackage(unconfiguredXStream);
}

public static final void allowDefaultPackage(XStream xstream) {
xstream.allowTypesByWildcard(DEFAULT_PACKAGES);
}

/**
* Write a an object to an XML file. UTF-8 is used as encoding
Expand Down Expand Up @@ -228,7 +241,9 @@ public static Object readObject(File file) {
* writing to a configured XML mapping
*/
public static XStream createXStreamInstance() {
return new EnhancedXStream(false);
XStream xstream = new EnhancedXStream(false);
XStream.setupDefaultSecurity(xstream);
return xstream;
}

/**
Expand All @@ -238,7 +253,9 @@ public static XStream createXStreamInstance() {
* @return
*/
public static XStream createXStreamInstanceForDBObjects() {
return new EnhancedXStream(true);
XStream xstream = new EnhancedXStream(true);
XStream.setupDefaultSecurity(xstream);
return xstream;
}

/**
Expand Down Expand Up @@ -302,7 +319,7 @@ public static Object readObject(XStream xStream, VFSLeaf file) {
* @return
*/
public static Object readObject(XStream xStream, InputStream is) {
try(InputStreamReader isr = new InputStreamReader(is, ENCODING);) {
try(InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);) {
return xStream.fromXML(isr);
} catch (Exception e) {
throw new OLATRuntimeException(XStreamHelper.class,
Expand All @@ -318,7 +335,7 @@ public static Object readObject(XStream xStream, InputStream is) {
* @return
*/
public static Object readObject(XStream xStream, String xml) {
try(InputStream is = new ByteArrayInputStream(xml.getBytes(ENCODING))) {
try(InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
return readObject(xStream, is);
} catch (Exception e) {
throw new OLATRuntimeException(XStreamHelper.class,
Expand Down Expand Up @@ -377,9 +394,9 @@ public static void writeObject(XStream xStream, File file, Object obj) {
* the object to be serialized
*/
public static void writeObject(XStream xStream, OutputStream os, Object obj) {
try(OutputStreamWriter osw = new OutputStreamWriter(os, ENCODING)) {
try(OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
String data = xStream.toXML(obj);
data = "<?xml version=\"1.0\" encoding=\"" + ENCODING + "\"?>\n"
data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ data; // give a decent header with the encoding used
osw.write(data);
osw.flush();
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/olat/course/CourseXStreamAliases.java
Expand Up @@ -95,6 +95,9 @@ public class CourseXStreamAliases {
* @return
*/
static {
XStreamHelper.allowDefaultPackage(readXstream);
XStreamHelper.allowDefaultPackage(writeXstream);

//write XStream
writeXstream.alias("com.frentix.olat.course.nodes.ViteroCourseNode", ViteroCourseNode.class);
writeXstream.alias("BookSection", BookSectionImpl.class);
Expand Down

0 comments on commit 3f219ac

Please sign in to comment.