Class: WPScan::Theme

Inherits:
WpItem show all
Defined in:
app/models/theme.rb

Overview

WordPress Theme

Constant Summary

Constants inherited from WpItem

WpItem::CHANGELOGS, WpItem::READMES

Instance Attribute Summary collapse

Attributes inherited from WpItem

#detection_opts, #name, #target, #uri

Instance Method Summary collapse

Methods inherited from WpItem

#changelog_url, #classify_name, #directory_listing?, #error_log?, #last_updated, #latest_version, #outdated?, #popular?, #readme_url, #to_s, #url, #vulnerabilities, #vulnerable_to?

Methods included from Vulnerable

#vulnerable?

Constructor Details

#initialize(name, target, opts = {}) ⇒ Theme

See WpItem



8
9
10
11
12
13
14
15
# File 'app/models/theme.rb', line 8

def initialize(name, target, opts = {})
  super(name, target, opts)

  @uri       = Addressable::URI.parse(target.url("wp-content/themes/#{name}/"))
  @style_url = opts[:style_url] || url('style.css')

  parse_style
end

Instance Attribute Details

#authorObject (readonly)

Returns the value of attribute author.



4
5
6
# File 'app/models/theme.rb', line 4

def author
  @author
end

#author_uriObject (readonly)

Returns the value of attribute author_uri.



4
5
6
# File 'app/models/theme.rb', line 4

def author_uri
  @author_uri
end

#descriptionObject (readonly)

Returns the value of attribute description.



4
5
6
# File 'app/models/theme.rb', line 4

def description
  @description
end

#licenseObject (readonly)

Returns the value of attribute license.



4
5
6
# File 'app/models/theme.rb', line 4

def license
  @license
end

#license_uriObject (readonly)

Returns the value of attribute license_uri.



4
5
6
# File 'app/models/theme.rb', line 4

def license_uri
  @license_uri
end

#style_nameObject (readonly)

Returns the value of attribute style_name.



4
5
6
# File 'app/models/theme.rb', line 4

def style_name
  @style_name
end

#style_uriObject (readonly)

Returns the value of attribute style_uri.



4
5
6
# File 'app/models/theme.rb', line 4

def style_uri
  @style_uri
end

#style_urlObject (readonly)

Returns the value of attribute style_url.



4
5
6
# File 'app/models/theme.rb', line 4

def style_url
  @style_url
end

#tagsObject (readonly)

Returns the value of attribute tags.



4
5
6
# File 'app/models/theme.rb', line 4

def tags
  @tags
end

#templateObject (readonly)

Returns the value of attribute template.



4
5
6
# File 'app/models/theme.rb', line 4

def template
  @template
end

#text_domainObject (readonly)

Returns the value of attribute text_domain.



4
5
6
# File 'app/models/theme.rb', line 4

def text_domain
  @text_domain
end

Instance Method Details

#==(other) ⇒ Object



95
96
97
# File 'app/models/theme.rb', line 95

def ==(other)
  super(other) && style_url == other.style_url
end

#db_dataJSON

Returns:

  • (JSON)


18
19
20
# File 'app/models/theme.rb', line 18

def db_data
  DB::Theme.db_data(name)
end

#parent_themeTheme

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/models/theme.rb', line 32

def parent_theme
  return unless template
  return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i

  opts = detection_opts.merge(
    style_url: url(Regexp.last_match[1]),
    found_by: 'Parent Themes (Passive Detection)',
    confidence: 100
  )

  self.class.new(template, target, opts)
end

#parent_themes(depth = 3) ⇒ Object

Parameters:

  • depth (Integer) (defaults to: 3)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/models/theme.rb', line 48

def parent_themes(depth = 3)
  theme  = self
  found  = []

  (1..depth).each do |_|
    parent = theme.parent_theme

    break unless parent

    found << parent
    theme = parent
  end

  found
end

#parse_styleObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/models/theme.rb', line 68

def parse_style
  {
    style_name: 'Theme Name',
    style_uri: 'Theme URI',
    author: 'Author',
    author_uri: 'Author URI',
    template: 'Template',
    description: 'Description',
    license: 'License',
    license_uri: 'License URI',
    tags: 'Tags',
    text_domain: 'Text Domain'
  }.each do |attribute, tag|
    instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
  end
end

#parse_style_tag(body, tag) ⇒ String

Parameters:

  • bofy (String)
  • tag (String)

Returns:

  • (String)


89
90
91
92
93
# File 'app/models/theme.rb', line 89

def parse_style_tag(body, tag)
  value = body[/^\s*#{Regexp.escape(tag)}:[\t ]*([^\r\n]+)/i, 1]

  value && !value.strip.empty? ? value.strip : nil
end

#style_bodyObject



64
65
66
# File 'app/models/theme.rb', line 64

def style_body
  @style_body ||= Browser.get(style_url).body
end

#version(opts = {}) ⇒ WPScan::Version, false

Parameters:

  • opts (Hash) (defaults to: {})

Returns:

  • (WPScan::Version, false)


25
26
27
28
29
# File 'app/models/theme.rb', line 25

def version(opts = {})
  @version = Finders::ThemeVersion::Base.find(self, detection_opts.merge(opts)) if @version.nil?

  @version
end