Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fingerprint fallback when filename collision #793

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 8 additions & 22 deletions lib/sprockets/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,20 @@ def call(env)
full_path = Rack::Utils.unescape(env['PATH_INFO'].to_s.sub(/^\//, ''))
path = full_path

unless path.valid_encoding?
return bad_request_response(env)
end
return bad_request_response(env) unless path.valid_encoding?
return forbidden_response(env) if forbidden_request?(path)

asset = find_asset(path)

# Strip fingerprint
if fingerprint = path_fingerprint(path)
if asset.nil? && fingerprint = path_fingerprint(path)
path = path.sub("-#{fingerprint}", '')
end

# URLs containing a `".."` are rejected for security reasons.
if forbidden_request?(path)
return forbidden_response(env)
return forbidden_response(env) if forbidden_request?(path)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we should also repeat:

return bad_request_response(env) unless path.valid_encoding?

But the original code did not do this so I wasn't sure whether to add.

asset = find_asset(path)
end

if fingerprint
if_match = fingerprint
if_match = asset&.etag
elsif env['HTTP_IF_MATCH']
if_match = env['HTTP_IF_MATCH'][/"(\w+)"$/, 1]
end
Expand All @@ -72,18 +70,6 @@ def call(env)
if_none_match = env['HTTP_IF_NONE_MATCH'][/"(\w+)"$/, 1]
end

# Look up the asset.
asset = find_asset(path)

# Fallback to looking up the asset with the full path.
# This will make assets that are hashed with webpack or
# other js bundlers work consistently between production
# and development pipelines.
if asset.nil? && (asset = find_asset(full_path))
if_match = asset.etag if fingerprint
fingerprint = asset.etag
end

if asset.nil?
status = :not_found
elsif fingerprint && asset.etag != fingerprint
Expand Down