wpscan 3.4.5 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +21 -14
- data/app/app.rb +2 -0
- data/app/controllers.rb +2 -0
- data/app/controllers/aliases.rb +2 -0
- data/app/controllers/core.rb +6 -4
- data/app/controllers/custom_directories.rb +3 -1
- data/app/controllers/enumeration.rb +6 -0
- data/app/controllers/enumeration/cli_options.rb +2 -0
- data/app/controllers/enumeration/enum_methods.rb +2 -0
- data/app/controllers/main_theme.rb +2 -0
- data/app/controllers/password_attack.rb +6 -4
- data/app/controllers/wp_version.rb +2 -0
- data/app/finders.rb +2 -0
- data/app/finders/config_backups.rb +2 -0
- data/app/finders/config_backups/known_filenames.rb +4 -3
- data/app/finders/db_exports.rb +2 -0
- data/app/finders/db_exports/known_locations.rb +15 -3
- data/app/finders/interesting_findings.rb +2 -0
- data/app/finders/interesting_findings/backup_db.rb +5 -4
- data/app/finders/interesting_findings/debug_log.rb +3 -1
- data/app/finders/interesting_findings/duplicator_installer_log.rb +6 -5
- data/app/finders/interesting_findings/emergency_pwd_reset_script.rb +6 -4
- data/app/finders/interesting_findings/full_path_disclosure.rb +3 -1
- data/app/finders/interesting_findings/mu_plugins.rb +4 -2
- data/app/finders/interesting_findings/multisite.rb +3 -1
- data/app/finders/interesting_findings/readme.rb +8 -6
- data/app/finders/interesting_findings/registration.rb +3 -1
- data/app/finders/interesting_findings/tmm_db_migrate.rb +4 -2
- data/app/finders/interesting_findings/upload_directory_listing.rb +3 -1
- data/app/finders/interesting_findings/upload_sql_dump.rb +8 -10
- data/app/finders/interesting_findings/wp_cron.rb +3 -1
- data/app/finders/main_theme.rb +2 -0
- data/app/finders/main_theme/css_style.rb +3 -1
- data/app/finders/main_theme/urls_in_homepage.rb +3 -1
- data/app/finders/main_theme/woo_framework_meta_generator.rb +3 -1
- data/app/finders/medias.rb +2 -0
- data/app/finders/medias/attachment_brute_forcing.rb +3 -1
- data/app/finders/passwords.rb +2 -0
- data/app/finders/passwords/wp_login.rb +4 -1
- data/app/finders/passwords/xml_rpc.rb +2 -0
- data/app/finders/passwords/xml_rpc_multicall.rb +4 -2
- data/app/finders/plugin_version.rb +4 -2
- data/app/finders/plugin_version/readme.rb +9 -5
- data/app/finders/plugins.rb +2 -0
- data/app/finders/plugins/body_pattern.rb +3 -1
- data/app/finders/plugins/comment.rb +3 -1
- data/app/finders/plugins/config_parser.rb +3 -1
- data/app/finders/plugins/header_pattern.rb +3 -1
- data/app/finders/plugins/javascript_var.rb +3 -1
- data/app/finders/plugins/known_locations.rb +10 -8
- data/app/finders/plugins/query_parameter.rb +2 -0
- data/app/finders/plugins/urls_in_homepage.rb +3 -1
- data/app/finders/plugins/xpath.rb +3 -1
- data/app/finders/theme_version.rb +4 -2
- data/app/finders/theme_version/style.rb +3 -1
- data/app/finders/theme_version/woo_framework_meta_generator.rb +3 -1
- data/app/finders/themes.rb +2 -0
- data/app/finders/themes/known_locations.rb +12 -10
- data/app/finders/themes/urls_in_homepage.rb +3 -1
- data/app/finders/timthumb_version.rb +3 -1
- data/app/finders/timthumb_version/bad_request.rb +3 -1
- data/app/finders/timthumbs.rb +2 -0
- data/app/finders/timthumbs/known_locations.rb +12 -3
- data/app/finders/users.rb +2 -0
- data/app/finders/users/author_id_brute_forcing.rb +3 -1
- data/app/finders/users/author_posts.rb +3 -1
- data/app/finders/users/login_error_messages.rb +3 -1
- data/app/finders/users/oembed_api.rb +6 -4
- data/app/finders/users/rss_generator.rb +7 -5
- data/app/finders/users/wp_json_api.rb +16 -6
- data/app/finders/users/yoast_seo_author_sitemap.rb +6 -4
- data/app/finders/wp_items.rb +2 -0
- data/app/finders/wp_items/urls_in_homepage.rb +2 -0
- data/app/finders/wp_version.rb +2 -0
- data/app/finders/wp_version/atom_generator.rb +2 -0
- data/app/finders/wp_version/rdf_generator.rb +2 -0
- data/app/finders/wp_version/readme.rb +4 -2
- data/app/finders/wp_version/rss_generator.rb +2 -0
- data/app/finders/wp_version/unique_fingerprinting.rb +3 -1
- data/app/models.rb +8 -0
- data/app/models/config_backup.rb +6 -2
- data/app/models/db_export.rb +6 -2
- data/app/models/interesting_finding.rb +36 -32
- data/app/models/media.rb +6 -2
- data/app/models/plugin.rb +25 -17
- data/app/models/theme.rb +83 -75
- data/app/models/timthumb.rb +58 -54
- data/app/models/wp_item.rb +140 -128
- data/app/models/wp_version.rb +47 -44
- data/app/models/xml_rpc.rb +18 -14
- data/app/views/cli/wp_item.erb +0 -3
- data/app/views/json/wp_item.erb +0 -1
- data/bin/wpscan +1 -0
- data/lib/wpscan.rb +2 -0
- data/lib/wpscan/browser.rb +2 -0
- data/lib/wpscan/controller.rb +2 -0
- data/lib/wpscan/controllers.rb +2 -0
- data/lib/wpscan/db.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/base.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/plugin.rb +4 -5
- data/lib/wpscan/db/dynamic_finders/theme.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/wordpress.rb +2 -0
- data/lib/wpscan/db/fingerprints.rb +2 -0
- data/lib/wpscan/db/plugin.rb +2 -0
- data/lib/wpscan/db/plugins.rb +2 -0
- data/lib/wpscan/db/theme.rb +2 -0
- data/lib/wpscan/db/themes.rb +2 -0
- data/lib/wpscan/db/updater.rb +4 -2
- data/lib/wpscan/db/wp_item.rb +2 -0
- data/lib/wpscan/db/wp_items.rb +2 -0
- data/lib/wpscan/db/wp_version.rb +2 -0
- data/lib/wpscan/errors.rb +7 -1
- data/lib/wpscan/errors/http.rb +27 -23
- data/lib/wpscan/errors/update.rb +8 -4
- data/lib/wpscan/errors/wordpress.rb +24 -14
- data/lib/wpscan/errors/xmlrpc.rb +8 -4
- data/lib/wpscan/finders.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/finder.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/body_pattern.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/comment.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/finder.rb +4 -2
- data/lib/wpscan/finders/dynamic_finder/version/header_pattern.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/javascript_var.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/xpath.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/wp_item_version.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/wp_items/finder.rb +4 -2
- data/lib/wpscan/finders/dynamic_finder/wp_version.rb +4 -2
- data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +4 -2
- data/lib/wpscan/helper.rb +2 -0
- data/lib/wpscan/references.rb +2 -0
- data/lib/wpscan/target.rb +12 -1
- data/lib/wpscan/target/platform/wordpress.rb +15 -1
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +23 -3
- data/lib/wpscan/version.rb +3 -1
- data/lib/wpscan/vulnerability.rb +2 -0
- data/lib/wpscan/vulnerable.rb +2 -0
- metadata +35 -8
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WPScan
|
2
4
|
module Finders
|
3
5
|
module WpVersion
|
@@ -11,7 +13,7 @@ module WPScan
|
|
11
13
|
hydra.abort
|
12
14
|
progress_bar.finish
|
13
15
|
|
14
|
-
return
|
16
|
+
return Model::WpVersion.new(
|
15
17
|
version_number,
|
16
18
|
found_by: 'Unique Fingerprinting (Aggressive Detection)',
|
17
19
|
confidence: 100,
|
data/app/models.rb
CHANGED
data/app/models/config_backup.rb
CHANGED
data/app/models/db_export.rb
CHANGED
@@ -1,48 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WPScan
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
module Model
|
5
|
+
# Custom class to include the WPScan::References module
|
6
|
+
class InterestingFinding < CMSScanner::Model::InterestingFinding
|
7
|
+
include References
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
#
|
11
|
+
# Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent)
|
12
|
+
#
|
13
|
+
class BackupDB < InterestingFinding
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
class DebugLog < InterestingFinding
|
17
|
+
end
|
15
18
|
|
16
|
-
|
17
|
-
|
19
|
+
class DuplicatorInstallerLog < InterestingFinding
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
22
|
+
class EmergencyPwdResetScript < InterestingFinding
|
23
|
+
end
|
21
24
|
|
22
|
-
|
23
|
-
|
25
|
+
class FullPathDisclosure < InterestingFinding
|
26
|
+
end
|
24
27
|
|
25
|
-
|
26
|
-
|
28
|
+
class MuPlugins < InterestingFinding
|
29
|
+
end
|
27
30
|
|
28
|
-
|
29
|
-
|
31
|
+
class Multisite < InterestingFinding
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
34
|
+
class Readme < InterestingFinding
|
35
|
+
end
|
33
36
|
|
34
|
-
|
35
|
-
|
37
|
+
class Registration < InterestingFinding
|
38
|
+
end
|
36
39
|
|
37
|
-
|
38
|
-
|
40
|
+
class TmmDbMigrate < InterestingFinding
|
41
|
+
end
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
class UploadDirectoryListing < InterestingFinding
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
46
|
+
class UploadSQLDump < InterestingFinding
|
47
|
+
end
|
45
48
|
|
46
|
-
|
49
|
+
class WPCron < InterestingFinding
|
50
|
+
end
|
47
51
|
end
|
48
52
|
end
|
data/app/models/media.rb
CHANGED
data/app/models/plugin.rb
CHANGED
@@ -1,25 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WPScan
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Model
|
5
|
+
# WordPress Plugin
|
6
|
+
class Plugin < WpItem
|
7
|
+
# See WpItem
|
8
|
+
def initialize(slug, blog, opts = {})
|
9
|
+
super(slug, blog, opts)
|
7
10
|
|
8
|
-
|
9
|
-
|
11
|
+
# To be used by #head_and_get
|
12
|
+
# If custom wp-content, it will be replaced by blog#url
|
13
|
+
@path_from_blog = "wp-content/plugins/#{slug}/"
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
@uri = Addressable::URI.parse(blog.url(path_from_blog))
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [ JSON ]
|
19
|
+
def db_data
|
20
|
+
@db_data ||= DB::Plugin.db_data(slug)
|
21
|
+
end
|
15
22
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
# @param [ Hash ] opts
|
24
|
+
#
|
25
|
+
# @return [ Model::Version, false ]
|
26
|
+
def version(opts = {})
|
27
|
+
@version = Finders::PluginVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
21
28
|
|
22
|
-
|
29
|
+
@version
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
data/app/models/theme.rb
CHANGED
@@ -1,99 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WPScan
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
module Model
|
5
|
+
# WordPress Theme
|
6
|
+
class Theme < WpItem
|
7
|
+
attr_reader :style_url, :style_name, :style_uri, :author, :author_uri, :template, :description,
|
8
|
+
:license, :license_uri, :tags, :text_domain
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
# See WpItem
|
11
|
+
def initialize(slug, blog, opts = {})
|
12
|
+
super(slug, blog, opts)
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
# To be used by #head_and_get
|
15
|
+
# If custom wp-content, it will be replaced by blog#url
|
16
|
+
@path_from_blog = "wp-content/themes/#{slug}/"
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
@uri = Addressable::URI.parse(blog.url(path_from_blog))
|
19
|
+
@style_url = opts[:style_url] || url('style.css')
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
DB::Theme.db_data(slug)
|
20
|
-
end
|
21
|
+
parse_style
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
@version = Finders::ThemeVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
24
|
+
# @return [ JSON ]
|
25
|
+
def db_data
|
26
|
+
@db_data ||= DB::Theme.db_data(slug)
|
27
|
+
end
|
27
28
|
|
28
|
-
@
|
29
|
-
|
29
|
+
# @param [ Hash ] opts
|
30
|
+
#
|
31
|
+
# @return [ Model::Version, false ]
|
32
|
+
def version(opts = {})
|
33
|
+
@version = Finders::ThemeVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
return unless template
|
34
|
-
return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i
|
35
|
+
@version
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
).merge(version_detection: version_detection_opts)
|
38
|
+
# @return [ Theme ]
|
39
|
+
def parent_theme
|
40
|
+
return unless template
|
41
|
+
return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
opts = detection_opts.merge(
|
44
|
+
style_url: url(Regexp.last_match[1]),
|
45
|
+
found_by: 'Parent Themes (Passive Detection)',
|
46
|
+
confidence: 100
|
47
|
+
).merge(version_detection: version_detection_opts)
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
# @retun [ Array<Theme> ]
|
48
|
-
def parent_themes(depth = 3)
|
49
|
-
theme = self
|
50
|
-
found = []
|
49
|
+
self.class.new(template, blog, opts)
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
# @param [ Integer ] depth
|
53
|
+
#
|
54
|
+
# @retun [ Array<Theme> ]
|
55
|
+
def parent_themes(depth = 3)
|
56
|
+
theme = self
|
57
|
+
found = []
|
54
58
|
|
55
|
-
|
59
|
+
(1..depth).each do |_|
|
60
|
+
parent = theme.parent_theme
|
56
61
|
|
57
|
-
|
58
|
-
theme = parent
|
59
|
-
end
|
62
|
+
break unless parent
|
60
63
|
|
61
|
-
|
62
|
-
|
64
|
+
found << parent
|
65
|
+
theme = parent
|
66
|
+
end
|
63
67
|
|
64
|
-
|
65
|
-
|
66
|
-
end
|
68
|
+
found
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
style_name: 'Theme Name',
|
71
|
-
style_uri: 'Theme URI',
|
72
|
-
author: 'Author',
|
73
|
-
author_uri: 'Author URI',
|
74
|
-
template: 'Template',
|
75
|
-
description: 'Description',
|
76
|
-
license: 'License',
|
77
|
-
license_uri: 'License URI',
|
78
|
-
tags: 'Tags',
|
79
|
-
text_domain: 'Text Domain'
|
80
|
-
}.each do |attribute, tag|
|
81
|
-
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
|
71
|
+
def style_body
|
72
|
+
@style_body ||= Browser.get(style_url).body
|
82
73
|
end
|
83
|
-
end
|
84
74
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
75
|
+
def parse_style
|
76
|
+
{
|
77
|
+
style_name: 'Theme Name',
|
78
|
+
style_uri: 'Theme URI',
|
79
|
+
author: 'Author',
|
80
|
+
author_uri: 'Author URI',
|
81
|
+
template: 'Template',
|
82
|
+
description: 'Description',
|
83
|
+
license: 'License',
|
84
|
+
license_uri: 'License URI',
|
85
|
+
tags: 'Tags',
|
86
|
+
text_domain: 'Text Domain'
|
87
|
+
}.each do |attribute, tag|
|
88
|
+
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
|
89
|
+
end
|
90
|
+
end
|
91
91
|
|
92
|
-
|
93
|
-
|
92
|
+
# @param [ String ] bofy
|
93
|
+
# @param [ String ] tag
|
94
|
+
#
|
95
|
+
# @return [ String ]
|
96
|
+
def parse_style_tag(body, tag)
|
97
|
+
value = body[/^\s*#{Regexp.escape(tag)}:[\t ]*([^\r\n]+)/i, 1]
|
98
|
+
|
99
|
+
value && !value.strip.empty? ? value.strip : nil
|
100
|
+
end
|
94
101
|
|
95
|
-
|
96
|
-
|
102
|
+
def ==(other)
|
103
|
+
super(other) && style_url == other.style_url
|
104
|
+
end
|
97
105
|
end
|
98
106
|
end
|
99
107
|
end
|
data/app/models/timthumb.rb
CHANGED
@@ -1,71 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WPScan
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
module Model
|
5
|
+
# Timthumb
|
6
|
+
class Timthumb < InterestingFinding
|
7
|
+
include Vulnerable
|
5
8
|
|
6
|
-
|
9
|
+
attr_reader :version_detection_opts
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
# @param [ String ] url
|
12
|
+
# @param [ Hash ] opts
|
13
|
+
# @option opts [ Symbol ] :mode The mode to use to detect the version
|
14
|
+
def initialize(url, opts = {})
|
15
|
+
super(url, opts)
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
@version_detection_opts = opts[:version_detection] || {}
|
18
|
+
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
# @param [ Hash ] opts
|
21
|
+
#
|
22
|
+
# @return [ Model::Version, false ]
|
23
|
+
def version(opts = {})
|
24
|
+
@version = Finders::TimthumbVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
@version
|
27
|
+
end
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
# @return [ Array<Vulnerability> ]
|
30
|
+
def vulnerabilities
|
31
|
+
vulns = []
|
29
32
|
|
30
|
-
|
31
|
-
|
33
|
+
vulns << rce_webshot_vuln if version == false || version > '1.35' && version < '2.8.14' && webshot_enabled?
|
34
|
+
vulns << rce_132_vuln if version == false || version < '1.33'
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
vulns
|
37
|
+
end
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
# @return [ Vulnerability ] The RCE in the <= 1.32
|
40
|
+
def rce_132_vuln
|
41
|
+
Vulnerability.new(
|
42
|
+
'Timthumb <= 1.32 Remote Code Execution',
|
43
|
+
{ exploitdb: ['17602'] },
|
44
|
+
'RCE',
|
45
|
+
'1.33'
|
46
|
+
)
|
47
|
+
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
49
|
+
# @return [ Vulnerability ] The RCE due to the WebShot in the > 1.35 (or >= 2.0) and <= 2.8.13
|
50
|
+
def rce_webshot_vuln
|
51
|
+
Vulnerability.new(
|
52
|
+
'Timthumb <= 2.8.13 WebShot Remote Code Execution',
|
53
|
+
{
|
54
|
+
url: ['http://seclists.org/fulldisclosure/2014/Jun/117', 'https://github.com/wpscanteam/wpscan/issues/519'],
|
55
|
+
cve: '2014-4663'
|
56
|
+
},
|
57
|
+
'RCE',
|
58
|
+
'2.8.14'
|
59
|
+
)
|
60
|
+
end
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
# @return [ Boolean ]
|
63
|
+
def webshot_enabled?
|
64
|
+
res = Browser.get(url, params: { webshot: 1, src: "http://#{default_allowed_domains.sample}" })
|
62
65
|
|
63
|
-
|
64
|
-
|
66
|
+
res.body =~ /WEBSHOT_ENABLED == true/ ? false : true
|
67
|
+
end
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
# @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
|
70
|
+
def default_allowed_domains
|
71
|
+
%w[flickr.com picasa.com img.youtube.com upload.wikimedia.org]
|
72
|
+
end
|
69
73
|
end
|
70
74
|
end
|
71
75
|
end
|