Skip to content

Commit e787955

Browse files
authored
Merge pull request #30 from devcon5io/development
Development
2 parents a80cbc3 + a528238 commit e787955

3 files changed

Lines changed: 79 additions & 1 deletion

File tree

src/main/java/ch/devcon5/sonar/plugins/mutationanalysis/report/PitestReportParser.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Collections;
3636

3737
import ch.devcon5.sonar.plugins.mutationanalysis.model.Mutant;
38+
import com.ctc.wstx.exc.WstxParsingException;
3839
import org.slf4j.Logger;
3940
import org.slf4j.LoggerFactory;
4041

@@ -132,10 +133,11 @@ public Collection<Mutant> parseMutants(final Path report) throws IOException {
132133
*/
133134
Collection<Mutant> readMutants(final InputStream stream) throws XMLStreamException {
134135
final XMLInputFactory inf = XMLInputFactory.newInstance();
136+
inf.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
135137
final XMLStreamReader reader = inf.createXMLStreamReader(stream);
136138
try {
137139
return readMutants(reader);
138-
} catch (IllegalArgumentException e){
140+
} catch (IllegalArgumentException | WstxParsingException e){
139141
throw new XMLStreamException(e.getMessage(), reader.getLocation(),e);
140142
}
141143
}

src/test/java/ch/devcon5/sonar/plugins/mutationanalysis/report/PitestReportParserTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@
2121
package ch.devcon5.sonar.plugins.mutationanalysis.report;
2222

2323
import static org.junit.Assert.assertEquals;
24+
import static org.junit.Assert.assertNotEquals;
2425
import static org.junit.Assert.assertTrue;
2526

2627
import javax.xml.stream.XMLStreamException;
28+
import java.io.ByteArrayInputStream;
29+
import java.io.File;
2730
import java.io.IOException;
2831
import java.net.URISyntaxException;
32+
import java.nio.file.Files;
2933
import java.nio.file.Path;
3034
import java.nio.file.Paths;
3135
import java.util.Collection;
3236

3337
import ch.devcon5.sonar.plugins.mutationanalysis.model.Mutant;
3438
import ch.devcon5.sonar.plugins.mutationanalysis.model.MutationOperators;
39+
import org.apache.commons.io.IOUtils;
3540
import org.junit.Before;
3641
import org.junit.Rule;
3742
import org.junit.Test;
@@ -198,4 +203,29 @@ public void readMutants_brokenXml_exceptionWithDetails() throws Exception {
198203
subject.readMutants(getClass().getResourceAsStream("PitestReportParserTest_broken.xml"));
199204
}
200205

206+
207+
@Test(expected = XMLStreamException.class)
208+
public void readMutants_XXE_attack_entityNotReplaced() throws Exception {
209+
210+
//we prepare a secret file with content that should not be disclosed
211+
//this file acts as a placeholder for any file with sensitive information such as /etc/passwd
212+
final String expectedSecret = "MY_SECRET";
213+
File secretFile = folder.newFile("secret");
214+
Files.write(secretFile.toPath(), expectedSecret.getBytes("UTF-8"));
215+
216+
//we forge a pitest report that should be processed by the plugin parser
217+
//the attack is not hypothetical, especially in managed sonarqube instances where forged
218+
//pitest reports may reveal sensitve information in the sonarqube results
219+
String template = IOUtils.toString(getClass().getResourceAsStream("PitestReportParserTest_XXE.xml"));
220+
String xxeAttack = template.replace("$SECRET$", secretFile.toURI().toURL().toString());
221+
222+
Collection<Mutant> mutants = subject.readMutants(new ByteArrayInputStream(xxeAttack.getBytes("UTF-8")));
223+
224+
//this code should never be executed as the the processing of the xml should
225+
//already encounter an unresolvable entity (&xxe;), causing an exception
226+
Mutant mutant = mutants.iterator().next();
227+
String actualSecret = mutant.getMethodDescription();
228+
assertNotEquals(expectedSecret, actualSecret);
229+
}
230+
201231
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Mutation Analysis Plugin
4+
~ Copyright (C) 2015-2018 DevCon5 GmbH, Switzerland
5+
~ info@devcon5.ch
6+
~
7+
~ This program is free software; you can redistribute it and/or
8+
~ modify it under the terms of the GNU Lesser General Public
9+
~ License as published by the Free Software Foundation; either
10+
~ version 3 of the License, or (at your option) any later version.
11+
~
12+
~ This program is distributed in the hope that it will be useful,
13+
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
~ Lesser General Public License for more details.
16+
~
17+
~ You should have received a copy of the GNU Lesser General Public License
18+
~ along with this program; if not, write to the Free Software Foundation,
19+
~ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20+
-->
21+
<!DOCTYPE mutations [
22+
<!ELEMENT mutations ANY >
23+
<!ELEMENT mutation ANY >
24+
<!ATTLIST mutation detected CDATA "KILLED">
25+
<!ATTLIST mutation status CDATA "true">
26+
<!ELEMENT sourceFile ANY >
27+
<!ELEMENT mutatedClass ANY >
28+
<!ELEMENT mutatedMethod ANY >
29+
<!ELEMENT methodDescription ANY >
30+
<!ELEMENT lineNumber ANY >
31+
<!ELEMENT mutator ANY >
32+
<!ELEMENT index ANY >
33+
<!ELEMENT killingTest ANY >
34+
<!ENTITY xxe SYSTEM "$SECRET$" >]>
35+
<mutations>
36+
<mutation detected='true' status='KILLED'>
37+
<sourceFile>Mutant.java</sourceFile>
38+
<mutatedClass>ch.devcon5.sonar.plugins.mutationanalysis.model.Mutant</mutatedClass>
39+
<mutatedMethod>equals</mutatedMethod>
40+
<methodDescription>&xxe;</methodDescription>
41+
<lineNumber>162</lineNumber>
42+
<mutator>org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator</mutator>
43+
<index>5</index>
44+
<killingTest>ch.devcon5.sonar.plugins.mutationanalysis.model.MutantTest.testEquals_different_false(ch.devcon5.sonar.plugins.mutationanalysis.model.MutantTest)</killingTest>
45+
</mutation>
46+
</mutations>

0 commit comments

Comments
 (0)