15
15
16
16
import static ch .qos .logback .core .CoreConstants .XML_PARSING ;
17
17
18
+ import java .io .ByteArrayInputStream ;
18
19
import java .io .IOException ;
19
20
import java .io .InputStream ;
20
21
import java .util .ArrayList ;
40
41
41
42
public class SaxEventRecorder extends DefaultHandler implements ContextAware {
42
43
44
+ // org.xml.sax.ext.LexicalHandler is an optional interface
43
45
final ContextAwareImpl contextAwareImpl ;
44
46
final ElementPath elementPath ;
45
47
List <SaxEvent > saxEventList = new ArrayList <SaxEvent >();
46
48
Locator locator ;
47
49
50
+
48
51
public SaxEventRecorder (Context context ) {
49
52
this (context , new ElementPath ());
50
53
}
51
54
55
+
52
56
public SaxEventRecorder (Context context , ElementPath elementPath ) {
53
57
contextAwareImpl = new ContextAwareImpl (context , this );
54
58
this .elementPath = elementPath ;
55
59
}
56
60
61
+ /**
62
+ * An implementation which disallows external DTDs
63
+ *
64
+ * @param publicId The public identifier, or null if none is
65
+ * available.
66
+ * @param systemId The system identifier provided in the XML
67
+ * document.
68
+ * @return
69
+ * @throws SAXException
70
+ * @throws IOException
71
+ * @since 1.5.13
72
+ */
73
+ @ Override
74
+ public InputSource resolveEntity (String publicId , String systemId ) throws SAXException , IOException {
75
+ addWarn ("Document Type Declaration (DOCTYPE) with external file reference is" );
76
+ addWarn ("disallowed to prevent Server-Side Request Forgery (SSRF) attacks." );
77
+ addWarn ("returning contents of SYSTEM " +systemId + " as a white space" );
78
+ return new InputSource (new ByteArrayInputStream (" " .getBytes ()));
79
+ }
80
+
57
81
final public void recordEvents (InputStream inputStream ) throws JoranException {
58
82
recordEvents (new InputSource (inputStream ));
59
83
}
60
84
61
85
public void recordEvents (InputSource inputSource ) throws JoranException {
62
86
SAXParser saxParser = buildSaxParser ();
63
87
try {
88
+ // the following sax property can be set in order to add 'this' as LexicalHandler to the saxParser
89
+ // However, this is not needed as long as resolveEntity() method is implemented as above
90
+ // saxParser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
91
+
64
92
saxParser .parse (inputSource , this );
93
+
65
94
return ;
66
95
} catch (IOException ie ) {
67
96
handleError ("I/O error occurred while parsing xml file" , ie );
@@ -83,7 +112,7 @@ private SAXParser buildSaxParser() throws JoranException {
83
112
try {
84
113
SAXParserFactory spf = SAXParserFactory .newInstance ();
85
114
spf .setValidating (false );
86
- // spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
115
+ //spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
87
116
// See LOGBACK-1465
88
117
spf .setFeature ("http://xml.org/sax/features/external-general-entities" , false );
89
118
spf .setFeature ("http://xml.org/sax/features/external-parameter-entities" , false );
@@ -93,11 +122,11 @@ private SAXParser buildSaxParser() throws JoranException {
93
122
String errMsg = "Error during SAX paser configuration. See https://logback.qos.ch/codes.html#saxParserConfiguration" ;
94
123
addError (errMsg , pce );
95
124
throw new JoranException (errMsg , pce );
96
- } catch (SAXException pce ) {
125
+ } catch (SAXException pce ) {
97
126
String errMsg = "Error during parser creation or parser configuration" ;
98
127
addError (errMsg , pce );
99
128
throw new JoranException (errMsg , pce );
100
- }
129
+ }
101
130
}
102
131
103
132
public void startDocument () {
@@ -116,7 +145,6 @@ protected boolean shouldIgnoreForElementPath(String tagName) {
116
145
}
117
146
118
147
public void startElement (String namespaceURI , String localName , String qName , Attributes atts ) {
119
-
120
148
String tagName = getTagName (localName , qName );
121
149
if (!shouldIgnoreForElementPath (tagName )) {
122
150
elementPath .push (tagName );
@@ -169,20 +197,17 @@ String getTagName(String localName, String qName) {
169
197
}
170
198
171
199
public void error (SAXParseException spe ) throws SAXException {
172
- addError (XML_PARSING + " - Parsing error on line " + spe .getLineNumber () + " and column "
173
- + spe .getColumnNumber ());
200
+ addError (XML_PARSING + " - Parsing error on line " + spe .getLineNumber () + " and column " + spe .getColumnNumber ());
174
201
addError (spe .toString ());
175
202
}
176
203
177
204
public void fatalError (SAXParseException spe ) throws SAXException {
178
- addError (XML_PARSING + " - Parsing fatal error on line " + spe .getLineNumber () + " and column "
179
- + spe .getColumnNumber ());
205
+ addError (XML_PARSING + " - Parsing fatal error on line " + spe .getLineNumber () + " and column " + spe .getColumnNumber ());
180
206
addError (spe .toString ());
181
207
}
182
208
183
209
public void warning (SAXParseException spe ) throws SAXException {
184
- addWarn (XML_PARSING + " - Parsing warning on line " + spe .getLineNumber () + " and column "
185
- + spe .getColumnNumber (), spe );
210
+ addWarn (XML_PARSING + " - Parsing warning on line " + spe .getLineNumber () + " and column " + spe .getColumnNumber (), spe );
186
211
}
187
212
188
213
public void addError (String msg ) {
0 commit comments