Class: WPScan::Model::Theme

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

Overview

WordPress Theme

Constant Summary

Constants inherited from WpItem

WpItem::READMES

Instance Attribute Summary collapse

Attributes inherited from WpItem

#blog, #detection_opts, #path_from_blog, #slug, #uri, #version_detection_opts

Instance Method Summary collapse

Methods inherited from WpItem

#classify, #directory_listing?, #error_log?, #head_and_get, #last_updated, #latest_version, #outdated?, #popular?, #potential_readme_filenames, #readme_url, #to_s, #url, #vulnerabilities, #vulnerable_to?

Methods included from Vulnerable

#vulnerable?

Constructor Details

#initialize(slug, blog, opts = {}) ⇒ Theme

See WpItem



11
12
13
14
15
16
17
18
19
20
21
22
# File 'app/models/theme.rb', line 11

def initialize(slug, blog, opts = {})
  super(slug, blog, opts)

  # To be used by #head_and_get
  # If custom wp-content, it will be replaced by blog#url
  @path_from_blog = "wp-content/themes/#{slug}/"

  @uri       = Addressable::URI.parse(blog.url(path_from_blog))
  @style_url = opts[:style_url] || url('style.css')

  parse_style
end

Instance Attribute Details

#authorObject (readonly)

Returns the value of attribute author.



7
8
9
# File 'app/models/theme.rb', line 7

def author
  @author
end

#author_uriObject (readonly)

Returns the value of attribute author_uri.



7
8
9
# File 'app/models/theme.rb', line 7

def author_uri
  @author_uri
end

#descriptionObject (readonly)

Returns the value of attribute description.



7
8
9
# File 'app/models/theme.rb', line 7

def description
  @description
end

#licenseObject (readonly)

Returns the value of attribute license.



7
8
9
# File 'app/models/theme.rb', line 7

def license
  @license
end

#license_uriObject (readonly)

Returns the value of attribute license_uri.



7
8
9
# File 'app/models/theme.rb', line 7

def license_uri
  @license_uri
end

#style_nameObject (readonly)

Returns the value of attribute style_name.



7
8
9
# File 'app/models/theme.rb', line 7

def style_name
  @style_name
end

#style_uriObject (readonly)

Returns the value of attribute style_uri.



7
8
9
# File 'app/models/theme.rb', line 7

def style_uri
  @style_uri
end

#style_urlObject (readonly)

Returns the value of attribute style_url.



7
8
9
# File 'app/models/theme.rb', line 7

def style_url
  @style_url
end

#tagsObject (readonly)

Returns the value of attribute tags.



7
8
9
# File 'app/models/theme.rb', line 7

def tags
  @tags
end

#templateObject (readonly)

Returns the value of attribute template.



7
8
9
# File 'app/models/theme.rb', line 7

def template
  @template
end

#text_domainObject (readonly)

Returns the value of attribute text_domain.



7
8
9
# File 'app/models/theme.rb', line 7

def text_domain
  @text_domain
end

Instance Method Details

#==(other) ⇒ Object



109
110
111
# File 'app/models/theme.rb', line 109

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

#db_dataHash

Returns:

  • (Hash)


32
33
34
# File 'app/models/theme.rb', line 32

def db_data
  @db_data ||= DB::VulnApi.theme_data(slug)
end

#metadataJSON

Retrieve the metadata from the vuln API if available (and a valid token is given), or the local metadata db otherwise

Returns:

  • (JSON)


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

def 
  @metadata ||= db_data.empty? ? DB::Theme.(slug) : db_data
end

#parent_themeTheme

Returns:



46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/models/theme.rb', line 46

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
  ).merge(version_detection: version_detection_opts)

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

#parent_themes(depth = 3) ⇒ Object

Parameters:

  • depth (Integer) (defaults to: 3)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/models/theme.rb', line 62

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



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/theme.rb', line 82

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)&.force_encoding('UTF-8'))
  end
end

#parse_style_tag(body, tag) ⇒ String

Parameters:

  • bofy (String)
  • tag (String)

Returns:

  • (String)


103
104
105
106
107
# File 'app/models/theme.rb', line 103

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

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

#style_bodyObject



78
79
80
# File 'app/models/theme.rb', line 78

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

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

Parameters:

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

Returns:

  • (Model::Version, false)


39
40
41
42
43
# File 'app/models/theme.rb', line 39

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

  @version
end