-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b112258
commit 33a0f91
Showing
4 changed files
with
103 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,42 @@ | ||
package com.esotericsoftware.yamlbeans; | ||
|
||
package com.esotericsoftware.yamlbeans; | ||
|
||
/** | ||
* SafeYamlConfig extends YamlConfig and hard codes the read anchor and read class tag flags to false. | ||
* When these flags are enabled, it is possible to perform a deserialization attack if the Yaml being parsed is from an | ||
* untrusted source. | ||
* Using SafeYamlConfig is the equivalent of using YamlConfig after setting | ||
* yamlConfig.readConfig.setAnchors(false); | ||
* yamlConfig.readConfig.setClassTags(false); | ||
* | ||
* It should be noted by setting these two values neither anchors or specifying class names are supported. | ||
* It is still possible to deserialize back to a specific object, but you need to specify the Class type in the code. | ||
* e.g | ||
* SafeYamlConfig yamlConfig = new SafeYamlConfig(); | ||
* YamlReader reader = new YamlReader(yamlData.toString(),yamlConfig); | ||
* Data data = reader.read(Data.class); | ||
* | ||
/** SafeYamlConfig extends YamlConfig and hard codes the read anchor and read class tag flags to false. When these flags are | ||
* enabled, it is possible to perform a deserialization attack if the Yaml being parsed is from an untrusted source. | ||
* <p> | ||
* Using SafeYamlConfig is the equivalent of using YamlConfig after setting: | ||
* | ||
* <pre> | ||
* yamlConfig.readConfig.setAnchors(false); | ||
* yamlConfig.readConfig.setClassTags(false); | ||
* </pre> | ||
* | ||
* It should be noted by setting these two values neither anchors or specifying class names are supported. It is still possible to | ||
* deserialize back to a specific object, but you need to specify the Class type in the code. For example: | ||
* | ||
* <pre> | ||
* SafeYamlConfig config = new SafeYamlConfig(); | ||
* YamlReader reader = new YamlReader(yamlData.toString(), config); | ||
* Data data = reader.read(Data.class); | ||
* </pre> | ||
*/ | ||
public class SafeYamlConfig extends YamlConfig { | ||
|
||
|
||
public SafeYamlConfig () { | ||
super(); | ||
super.readConfig = new SafeReadConfig(); | ||
} | ||
|
||
static public class SafeReadConfig extends ReadConfig { | ||
|
||
public SafeReadConfig(){ | ||
super.anchors = false; | ||
super.classTags = false; | ||
} | ||
|
||
@Override | ||
public void setClassTags(boolean classTags) { | ||
if(classTags) { | ||
throw new IllegalArgumentException("Class Tags cannot be enabled in SafeYamlConfig."); | ||
} | ||
} | ||
|
||
@Override | ||
public void setAnchors(boolean anchors) { | ||
if(anchors) { | ||
throw new IllegalArgumentException("Anchors cannot be enabled in SafeYamlConfig."); | ||
} | ||
} | ||
} | ||
|
||
public SafeYamlConfig () { | ||
super.readConfig = new SafeReadConfig(); | ||
} | ||
|
||
static public class SafeReadConfig extends ReadConfig { | ||
public SafeReadConfig () { | ||
super.anchors = false; | ||
super.classTags = false; | ||
} | ||
|
||
public void setClassTags (boolean classTags) { | ||
if (classTags) throw new IllegalArgumentException("Class Tags cannot be enabled in SafeYamlConfig."); | ||
} | ||
|
||
public void setAnchors (boolean anchors) { | ||
if (anchors) throw new IllegalArgumentException("Anchors cannot be enabled in SafeYamlConfig."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 59 additions & 69 deletions
128
test/com/esotericsoftware/yamlbeans/SafeYamlConfigTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,69 @@ | ||
|
||
package com.esotericsoftware.yamlbeans; | ||
|
||
import org.junit.Test; | ||
import static junit.framework.Assert.*; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static junit.framework.Assert.assertEquals; | ||
import static junit.framework.Assert.assertNull; | ||
import static junit.framework.Assert.assertTrue; | ||
import org.junit.Test; | ||
|
||
public class SafeYamlConfigTest { | ||
|
||
|
||
private static final String TESTOBJECT_TAG = "!com.esotericsoftware.yamlbeans.SafeYamlConfigTest$TestObject"; | ||
private static final String LINE_SEPARATOR = System.getProperty("line.separator"); | ||
|
||
|
||
@Test | ||
public void testDeserializationOfClassTag() throws YamlException { | ||
SafeYamlConfig yamlConfig = new SafeYamlConfig(); | ||
StringBuilder yamlData = new StringBuilder(); | ||
yamlData.append(TESTOBJECT_TAG).append(LINE_SEPARATOR) | ||
.append("a: test").append(LINE_SEPARATOR); | ||
YamlReader reader = new YamlReader(yamlData.toString(),yamlConfig); | ||
Object data = reader.read(); | ||
assertTrue(data instanceof HashMap); | ||
Map dataMap = (Map) data; | ||
assertTrue(dataMap.containsKey("a")); | ||
assertEquals("test",dataMap.get("a")); | ||
} | ||
|
||
|
||
|
||
@Test | ||
public void testIgnoreAnchor() throws YamlException { | ||
SafeYamlConfig yamlConfig = new SafeYamlConfig(); | ||
StringBuilder yamlData = new StringBuilder(); | ||
yamlData.append("oldest friend:").append(LINE_SEPARATOR) | ||
.append(" &1 !contact").append(LINE_SEPARATOR) | ||
.append(" name: Bob").append(LINE_SEPARATOR) | ||
.append(" age: 29").append(LINE_SEPARATOR) | ||
.append("best friend: *1").append(LINE_SEPARATOR); | ||
YamlReader reader = new YamlReader(yamlData.toString(),yamlConfig); | ||
Object data = reader.read(); | ||
assertTrue(data instanceof HashMap); | ||
Map dataMap = (Map) data; | ||
assertTrue(dataMap.containsKey("oldest friend")); | ||
Map old = (Map) dataMap.get("oldest friend"); | ||
assertTrue(old.containsKey("name")); | ||
assertEquals("Bob",old.get("name")); | ||
assertNull(dataMap.get("best friend")); | ||
} | ||
|
||
|
||
static class TestObject { | ||
private String a; | ||
public int age; | ||
public String name; | ||
public Object object; | ||
public List<Object> objects; | ||
|
||
private TestObject() { | ||
} | ||
|
||
public TestObject(String a) { | ||
this.a = a; | ||
} | ||
|
||
public String getA() { | ||
return a; | ||
} | ||
|
||
public void setA(String a) { | ||
this.a = a; | ||
} | ||
} | ||
private static final String TESTOBJECT_TAG = "!com.esotericsoftware.yamlbeans.SafeYamlConfigTest$TestObject"; | ||
private static final String LINE_SEPARATOR = System.getProperty("line.separator"); | ||
|
||
@Test | ||
public void testDeserializationOfClassTag () throws YamlException { | ||
SafeYamlConfig yamlConfig = new SafeYamlConfig(); | ||
StringBuilder yamlData = new StringBuilder(); | ||
yamlData.append(TESTOBJECT_TAG).append(LINE_SEPARATOR).append("a: test").append(LINE_SEPARATOR); | ||
YamlReader reader = new YamlReader(yamlData.toString(), yamlConfig); | ||
Object data = reader.read(); | ||
assertTrue(data instanceof HashMap); | ||
Map dataMap = (Map)data; | ||
assertTrue(dataMap.containsKey("a")); | ||
assertEquals("test", dataMap.get("a")); | ||
} | ||
|
||
@Test | ||
public void testIgnoreAnchor () throws YamlException { | ||
SafeYamlConfig yamlConfig = new SafeYamlConfig(); | ||
StringBuilder yamlData = new StringBuilder(); | ||
yamlData.append("oldest friend:").append(LINE_SEPARATOR).append(" &1 !contact").append(LINE_SEPARATOR) | ||
.append(" name: Bob").append(LINE_SEPARATOR).append(" age: 29").append(LINE_SEPARATOR).append("best friend: *1") | ||
.append(LINE_SEPARATOR); | ||
YamlReader reader = new YamlReader(yamlData.toString(), yamlConfig); | ||
Object data = reader.read(); | ||
assertTrue(data instanceof HashMap); | ||
Map dataMap = (Map)data; | ||
assertTrue(dataMap.containsKey("oldest friend")); | ||
Map old = (Map)dataMap.get("oldest friend"); | ||
assertTrue(old.containsKey("name")); | ||
assertEquals("Bob", old.get("name")); | ||
assertNull(dataMap.get("best friend")); | ||
} | ||
|
||
static class TestObject { | ||
private String a; | ||
public int age; | ||
public String name; | ||
public Object object; | ||
public List<Object> objects; | ||
|
||
private TestObject () { | ||
} | ||
|
||
public TestObject (String a) { | ||
this.a = a; | ||
} | ||
|
||
public String getA () { | ||
return a; | ||
} | ||
|
||
public void setA (String a) { | ||
this.a = a; | ||
} | ||
} | ||
} |