Skip to content

Commit a151fda

Browse files
bcolesurbanadventurer
authored andcommitted
[!] Bug fix: XML and MagicTree XML logging
[!] XML logging and MagicTree XML logging are now properly encoded [~] XML logging is now consistent: [~] plugin names and plugin result data types have their own nodes [~] plugin result data values are comma seperated [~] whatweb.xsl updated to reflect the changes to the XML logging format
1 parent 9d66f5d commit a151fda

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

lib/output.rb

+33-18
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,10 @@ def out(target, status, results)
250250
end
251251

252252
# XML Output #
253-
# Hey, do u actually use this XML output? Then I'd love to hear from you for suggestions, changes, etc.
254-
# Does it bother you that some types of output are joined by commas but other types aren't?
253+
# Does anyone use XML output?
254+
# We'd love to hear any suggestions you may have!
255+
# Does it bother you that some types of output are joined by commas
256+
# but other types aren't?
255257
class OutputXML < Output
256258
def initialize(f=STDOUT)
257259
super
@@ -269,6 +271,16 @@ def escape(t)
269271
text=t.to_s.dup
270272
# use sort_by so that & is before &quot;, etc.
271273
@substitutions.sort_by {|a,b| a=="&" ? 0 : 1 }.map{|from,to| text.gsub!(from,to) }
274+
275+
# Encode all special characters
276+
# More info: http://www.asciitable.com/
277+
r=/[^\x20-\x5A\x5E-\x7E]/
278+
279+
# based on code for CGI.escape
280+
text.gsub!(r) do |x|
281+
'%' + x.unpack('H2' * x.size).join('%').upcase
282+
end
283+
272284
text
273285
end
274286

@@ -277,11 +289,11 @@ def out(target, status, results)
277289
@f.puts "<target>"
278290
@f.puts "\t<uri>#{escape(target)}</uri>"
279291
@f.puts "\t<http-status>#{escape(status)}</http-status>"
280-
292+
281293
results.each do |plugin_name,plugin_results|
282294
@f.puts "\t<plugin>"
283295
@f.puts "\t\t<name>#{escape(plugin_name)}</name>"
284-
296+
285297
unless plugin_results.empty?
286298
# important info in brief mode is version, type and ?
287299
# what's the highest probability for the match?
@@ -301,28 +313,21 @@ def out(target, status, results)
301313
filepath = plugin_results.map {|x|
302314
x[:filepath] unless x[:filepath].class==Regexp}.flatten.compact.sort.uniq.join(",")
303315

304-
accounts = plugin_results.map {|x|
305-
x[:account] unless x[:account].class==Regexp }.flatten.compact.sort.uniq.to_a
316+
account = plugin_results.map {|x|
317+
x[:account] unless x[:account].class==Regexp}.flatten.compact.sort.uniq.join(",")
306318
modules = plugin_results.map {|x|
307-
x[:module] unless x[:module].class==Regexp}.flatten.compact.sort.uniq.to_a
308-
319+
x[:module] unless x[:module].class==Regexp}.flatten.compact.sort.uniq.join(",")
309320

321+
# Output results
310322
@f.puts "\t\t<certainty>#{escape(certainty)}</certainty>" if certainty and certainty < 100
311323
version.map {|x| @f.puts "\t\t<version>#{escape(x)}</version>" }
312324
os.map {|x| @f.puts "\t\t<os>#{escape(x)}</os>" }
313-
string.map {|x| @f.puts "\t\t<string>#{escape(x)}</string>" }
325+
string.map {|x| @f.puts "\t\t<string>#{escape(x)}</string>" }
314326
model.map {|x| @f.puts "\t\t<model>#{escape(x)}</model>" }
315327
firmware.map {|x| @f.puts "\t\t<firmware>#{escape(x)}</firmware>" }
316328
filepath.map {|x| @f.puts "\t\t<filepath>#{escape(x)}</filepath>" }
317-
318-
if accounts.size > 0
319-
accounts.map {|x| @f.puts "\t\t<account>#{escape(x)}</account>" }
320-
@f.puts "\t\t<accounts>\n" + accounts.map {|x| "\t\t\t<accounts>#{escape(x)}</accounts>" }.join("\n") + "\n\t\t</accounts>"
321-
end
322-
323-
if modules.size > 0
324-
@f.puts "\t\t<modules>\n" + modules.map {|x| "\t\t\t<module>#{escape(x)}</module>" }.join("\n") + "\n\t\t</modules>"
325-
end
329+
account.map {|x| @f.puts "\t\t<account>#{escape(x)}</account>" }
330+
modules.map {|x| @f.puts "\t\t<module>#{escape(x)}</module>" }
326331
end
327332
@f.puts "\t</plugin>"
328333
end
@@ -351,6 +356,16 @@ def escape(t)
351356
text=t.to_s.dup
352357
# use sort_by so that & is before &quot;, etc.
353358
@substitutions.sort_by {|a,b| a=="&" ? 0 : 1 }.map{|from,to| text.gsub!(from,to) }
359+
360+
# Encode all special characters
361+
# More info: http://www.asciitable.com/
362+
r=/[^\x20-\x5A\x5E-\x7E]/
363+
364+
# based on code for CGI.escape
365+
text.gsub!(r) do |x|
366+
'%' + x.unpack('H2' * x.size).join('%').upcase
367+
end
368+
354369
text
355370
end
356371

whatweb.xsl

+4-4
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ a{color:#000;}a:hover{color:#000;}a:visited{color:#000;}
6666
<xsl:if test="model"><tr bgcolor="#ccffcc"><td>Model: <xsl:value-of select="model"/></td></tr></xsl:if>
6767
<xsl:if test="firmware"><tr bgcolor="#ccffcc"><td>Firmware: <xsl:value-of select="firmware"/></td></tr></xsl:if>
6868
<xsl:if test="filepath"><tr bgcolor="#ccffcc"><td>Filepath: <xsl:value-of select="filepath"/></td></tr></xsl:if>
69-
<xsl:for-each select="accounts"><xsl:if test="account"><tr bgcolor="#ccffcc"><td>Account: <xsl:value-of select="account"/></td></tr></xsl:if></xsl:for-each>
70-
<xsl:for-each select="modules"><xsl:if test="module"><tr bgcolor="#ccffcc"><td>Module: <xsl:value-of select="module"/></td></tr></xsl:if></xsl:for-each>
69+
<xsl:if test="account"><tr bgcolor="#ccffcc"><td>Account: <xsl:value-of select="account"/></td></tr></xsl:if>
70+
<xsl:if test="module"><tr bgcolor="#ccffcc"><td>Module: <xsl:value-of select="module"/></td></tr></xsl:if>
7171
</td></tr>
7272
</xsl:when>
7373
<xsl:otherwise>
@@ -79,8 +79,8 @@ a{color:#000;}a:hover{color:#000;}a:visited{color:#000;}
7979
<xsl:if test="model"><tr bgcolor="#bbddbb"><td>Model: <xsl:value-of select="model"/></td></tr></xsl:if>
8080
<xsl:if test="firmware"><tr bgcolor="#bbddbb"><td>Firmware: <xsl:value-of select="firmware"/></td></tr></xsl:if>
8181
<xsl:if test="filepath"><tr bgcolor="#bbddbb"><td>Filepath: <xsl:value-of select="filepath"/></td></tr></xsl:if>
82-
<xsl:for-each select="accounts"><xsl:if test="account"><tr bgcolor="#bbddbb"><td>Account: <xsl:value-of select="account"/></td></tr></xsl:if></xsl:for-each>
83-
<xsl:for-each select="modules"><xsl:if test="module"><tr bgcolor="#bbddbb"><td>Module: <xsl:value-of select="module"/></td></tr></xsl:if></xsl:for-each>
82+
<xsl:if test="account"><tr bgcolor="#bbddbb"><td>Account: <xsl:value-of select="account"/></td></tr></xsl:if>
83+
<xsl:if test="module"><tr bgcolor="#bbddbb"><td>Module: <xsl:value-of select="module"/></td></tr></xsl:if>
8484
</td></tr>
8585
</xsl:otherwise>
8686
</xsl:choose>

0 commit comments

Comments
 (0)