Skip to content

Commit

Permalink
Check for SRI/CORS links gjtorikian#47
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyalyo committed Mar 2, 2017
1 parent 979a467 commit 2e4f095
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 32 deletions.
1 change: 1 addition & 0 deletions bin/htmlproofer
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Mercenary.program(:htmlproofer) do |p|
p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
p.option 'check_img_http', '--check-img-http', 'Fails an image if it\'s marked as `http` (default: `false`).'
p.option 'check_opengraph', '--check-opengraph', 'Enables the Open Graph checker (default: `false`).'
p.option 'check_sri', '--check-sri', 'Check that `<link>` and `<script>` external resources do use SRI (default: `false`).'
p.option 'directory_index_file', '--directory-index-file', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
p.option 'disable_external', '--disable-external', 'If `true`, does not run the external link checker, which can take a lot of time (default: `false`)'
p.option 'empty_alt_ignore', '--empty-alt-ignore', 'If `true`, ignores images with empty alt tags'
Expand Down
12 changes: 11 additions & 1 deletion lib/html-proofer/check/scripts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,18 @@ def run
elsif !@script.exists?
add_issue("internal script #{@script.src} does not exist", line: line, content: content)
end
check_sri(line, content) if @script.check_sri?
end

external_urls
end

def check_sri(line, content)
if !defined? @script.integrity and !defined? @script.crossorigin
add_issue("SRI and CORS not provided in: #{@script.src}", line: line, content: content)
elsif !defined? @script.integrity
add_issue("Integrity is missing in: #{@script.src}", line: line, content: content)
elsif !defined? @script.crossorigin
add_issue("CORS not provided for external resource in: #{@script.src}", line: line, content: content)
end
end
end
63 changes: 32 additions & 31 deletions lib/html-proofer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,49 @@ module Configuration
require_relative 'version'

PROOFER_DEFAULTS = {
:allow_hash_href => false,
:alt_ignore => [],
:assume_extension => false,
:check_external_hash => false,
:check_favicon => false,
:check_html => false,
:check_img_http => false,
:check_opengraph => false,
:checks_to_ignore => [],
:directory_index_file => 'index.html',
:disable_external => false,
:empty_alt_ignore => false,
:enforce_https => false,
:error_sort => :path,
:extension => '.html',
:external_only => false,
:file_ignore => [],
:http_status_ignore => [],
:internal_domains => [],
:log_level => :info,
:only_4xx => false,
:url_ignore => [],
:url_swap => {}
:allow_hash_href => false,
:alt_ignore => [],
:assume_extension => false,
:check_external_hash => false,
:check_favicon => false,
:check_html => false,
:check_img_http => false,
:check_opengraph => false,
:check_sri => false,
:checks_to_ignore => [],
:directory_index_file => 'index.html',
:disable_external => false,
:empty_alt_ignore => false,
:enforce_https => false,
:error_sort => :path,
:extension => '.html',
:external_only => false,
:file_ignore => [],
:http_status_ignore => [],
:internal_domains => [],
:log_level => :info,
:only_4xx => false,
:url_ignore => [],
:url_swap => {}
}

TYPHOEUS_DEFAULTS = {
:followlocation => true,
:headers => {
'User-Agent' => "Mozilla/5.0 (compatible; HTML Proofer/#{HTMLProofer::VERSION}; +https://github.com/gjtorikian/html-proofer)"
}
:followlocation => true,
:headers => {
'User-Agent' => "Mozilla/5.0 (compatible; HTML Proofer/#{HTMLProofer::VERSION}; +https://github.com/gjtorikian/html-proofer)"
}
}

HYDRA_DEFAULTS = {
:max_concurrency => 50
:max_concurrency => 50
}

PARALLEL_DEFAULTS = {}

VALIDATION_DEFAULTS = {
:report_script_embeds => false,
:report_missing_names => false,
:report_invalid_tags => false
:report_script_embeds => false,
:report_missing_names => false,
:report_invalid_tags => false
}

CACHE_DEFAULTS = {}
Expand Down
4 changes: 4 additions & 0 deletions lib/html-proofer/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def check_img_http?
@check.options[:check_img_http]
end

def check_sri?
@check.options[:check_sri]
end

# path is external to the file
def external?
!internal?
Expand Down
7 changes: 7 additions & 0 deletions spec/html-proofer/fixtures/scripts/cors_not_provided.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<body>
<script
src="http://code.jquery.com"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<script
src="http://code.jquery.com"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<html>
<body>
<script
src="http://code.jquery.com"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<body>
<script
src="http://code.jquery.com"
crossorigin="anonymous"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions spec/html-proofer/scripts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,28 @@
proofer = run_proofer(file, :file, { :url_swap => { %r{^http://example.com} => "" } })
expect(proofer.failed_tests).to eq []
end

it 'SRI and CORS not provided' do
file = "#{FIXTURES_DIR}/scripts/integrity_and_cors_not_provided.html"
proofer = run_proofer(file, :file, {:check_sri => true})
expect(proofer.failed_tests.first).to match(%r{SRI and CORS not provided})
end

it 'SRI not provided' do
file = "#{FIXTURES_DIR}/scripts/cors_not_provided.html"
proofer = run_proofer(file, :file, {:check_sri => true})
expect(proofer.failed_tests.first).to match(%r{CORS not provided})
end

it 'CORS not provided' do
file = "#{FIXTURES_DIR}/scripts/integrity_not_provided.html"
proofer = run_proofer(file, :file, {:check_sri => true})
expect(proofer.failed_tests.first).to match(%r{Integrity is missing})
end

it 'SRI and CORS provided' do
file = "#{FIXTURES_DIR}/scripts/integrity_and_cors_provided.html"
proofer = run_proofer(file, :file, {:check_sri => true})
expect(proofer.failed_tests).to eq []
end
end

0 comments on commit 2e4f095

Please sign in to comment.