How do I configure the "high_voltage" gem to serve static images?
I am trying to use the "high_voltage" gem to provide authentication around my pages (actually some completely independent sites with a static html / css tree). It works, but images are not loading. If I go to the image path, the original image code is returned as text, resulting in "ActionView :: WrongEncodingError in Pages # show". If I put the static html folder in / public, all images are loaded as expected. Apparently my PageController is trying template-like static images. How can I fix this?
I have overridden PageController as described here: https://github.com/thoughtbot/high_voltage#override
# in config/routes.rb
match "/pages/*id" => 'pages#show', :as => :page, :format => false
# in app/controller/pages_controller.rb
before_filter :authenticate_client!
layout :nil
def show
custom_authentication
super
end
...
I'm new to RoR, so any general help or suggestions are greatly appreciated.
EDIT: Here is the complete error message
ActionView::WrongEncodingError in Pages#show
Showing /home/robert/Coding/RailsPlayground/JoSchaefer/app/views/pages/myWebsite/images/test.png where line # raised:
Your template was not saved as valid UTF-8. Please either specify UTF-8 as the encoding for your template in your text editor, or mark the template with its encoding by inserting the following as the first line of the template:
# encoding: <name of correct encoding>.
The source of your template was:
PNG
IHDRKK , tEXtSoftwareAdobe ImageReadyq e<"iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5 Macintosh" xmpMM:InstanceID="xmp.iid:AF83234B3E0211E281788B850106876A" xmpMM:DocumentID="xmp.did:AF83234C3E0211E281788B850106876A"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:AF8323493E0211E281788B850106876A" stRef:documentID="xmp.did:AF83234A3E0211E281788B850106876A"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>|~
kIDATx [
TTe ; p ? :Y $Obb-m֖ V B{2 S g
O[[ G ) z< 4ꒉ 16 0 s v 3#0nr Μ9Ýo w } } ^ N dL X #G8V x e Ǐ= ɱ ` ? 64K T hl" a Z" dU5 /5 A {wkb غ C_/ w w , > _& 'CN2 ) ] V g ܨ7 -A w Ϧ> k& >EH 5 Z 9L i i 2T SӔ e F { J g < @ ;`X, v h h Qq pQ⫉IA + F%eTT ̬ i s 0 p k lb - G q Z x 0lՉ o$. yfM 9 q O ޫ/ %L R6 *j '- e hs R u j ֕ A s kɇ+ -y 6Ĝ 6xo C wOs Bxe 8D^* 2 r ^a H \5- I6 4 <[@ d ) e i!ӈ [ ; b& q Prh >GF@< mNT*' );r $y | - $ @ C U 8 ¶xeܳ r_@n$ d> $1YBv /މë d ʄ +" [ G Ɯ A
0J +. NB /n*r ̇ ' y y "
!\ poZ} 4 ? %V % D y || SG] gVU Y .{ K - |X ' %n D
- *` xU' n o5 > u h| > |@JD P @fF Մ' ! C 'f"s" ˻q} l?{ ] 2 2~ c rxN L c hc o !4 p Z θ)r W
, i k ߑ3 C *R ZB t9`=lG} qY f < ն8 $ 0 'l Ϸ { [. M!= ԣ ~# h ~ߞ EK& ٿ [?Z [ v#
Q<ؔ Sl n&-J0 8 e{ A VE d B r H ǰ b ' h* 5 =Y H\ ^ } 0 C n=X 4@ = K " $ >.f u hTo X * { k K -lk r ֠ _x pK ɏ˧ #; {{[ '2
Q iR * + g $ VM뱡 P sT d Ԍ k ;/ Xf X9 I 5Ih@h N `^ x t < ; '. 67w H 3Wgq5 0U* G ] >
vP w f)i "/ K O saG ) %] 9Ƌ
6i U' E (
" f5ٺ ` kpH 2 J Ϫ w 6B ! 8 \y -pqS . ~ 5q J 9Q ` FGz R DŸ s / W K , 0 o@ CW\;KCW u 9T j[M N [xielD $ e}O + |7 ¤ Iq ~NZR b_H蘃 8B # JY# S{`o ߯&,4 Ba u K 㤜 ZǓ n" / =_ mDU o\+ګ ? <'~-_?C qc m 7 + " I = js]f i )* @ Z1 ZG u/* D Ӑ I M (^pB &0 - đ꧟n+/ Jc o m =Z=ݛ ƈz Ɩfׂ 9 l % sN ^U R ĥO/M % W wL` >"'R Z _N;)
r - RU ]!1 ^1 "7" T 'N + JӰ0 {4T}]
R 0a u k( r8x<::̂'2 t D j 2 ʉ 9\_̆ QI-9 F ^$0 ,l6 v Z g) &j 6 6 - !TuJ > @ _H 9Ϭ G ;3 u \ w G C) P \ O ` D V< ? )z{ p % 3< %'
0#R?r sD " 3!D u/ $ _ JUe C u @ _R R J ; I 9 ^ ?ę f t \ vE*l(i )l b | D J5@! Ȩ w y 9 i </o N7l ` }Sp6ƵI Ⱥ C D n vc Kp m 7:} O>{| S \zj } w d\ '1` 8 F
!w
> ' D
13 M |G
U [_ E{ utzm Ϣ ݨEvǺ O jl 8)۟ 3 ! O|Ǜ xN%lX
0Cm U썜 ͊ y! +j
r%b r
!P1B ªA\ I /ꑻ $p"VA] Z T ĚGD !i ]<gˎ X X * G En #{ R } 7 H7I?; AH
5 T c Y &
qe8; ﶼ zaS :~ ύ n I < A (ޱg[ . o r Sγkݶ C - ߴv ˸ 8 By t zZ2 _ D ! H (6P \ D l? )
D r ņ4 m$3 => D-Fo P) " eB_ 'hQW tg) i 2nk k@?\=< b !B k[z`X H z r7 R? ͷ %D 7 b_i pDO*
m
9
Nut< { _ k& y! U TG { y 0S W ި2\} Ya E̲ 1 'fB ݔQ rw ( ܼW< 9 h Ը L C k 9.E 6y -y[ t l X l #X= x 옝 r #<j k w [>= { y> h p ۵F ^z
m 1.6 W a 9x 1dz ? q #G8 k z*&A xIEND B`
Extracted source (around line #):
Rails.root: /home/robert/Coding/RailsPlayground/JoSchaefer
Application Trace | Framework Trace | Full Trace
app/controllers/pages_controller.rb:7:in `show'
Request
Parameters:
{"id"=>"myWebsite/images/test.png"}
Show session dump
Show env dump
Response
Headers:
None
source to share
After looking at the source for "high_voltage", I was able to "fix" my problem simply by sending the source file:
# in /app/controllers/pages_controller.rb
def show
logger.debug "Current page is: #{current_page}"
custom_authentication current_page
send_file "app/views/#{current_page}", :disposition => 'inline'
# super
end
This is a super overlooked method HighVoltage::PagesController
:
# source of 'high_voltage' gem
# in app/controllers/high_voltage/pages_controller.rb
def show
render :template => current_page
end
I am aware of the security risk as current_page
derived from params[:id]
. However, it HighVoltage::PageFinder
seems to sanitize the given input:
# source of 'high_voltage' gem
# in lib/high_voltage/page_finder.rb
VALID_CHARACTERS = "a-zA-Z0-9~!@$%^&*()#`_+-=\"{}|[];',?".freeze
...
def clean_path
path = Pathname.new("/#{clean_id}")
path.cleanpath.to_s[1..-1]
end
def clean_id
@page_id.tr("^#{VALID_CHARACTERS}", '')
end
Going to http://localhost:3000/pages/../shouldNotBeAccessed.html
leads to http://localhost:3000/shouldNotBeAccessed.html
, and PagesController
never gets called, which is fine, but http://localhost:3000/pages/something/../somethingElse.html
calls PagesController
and the log gives me "Current page: pages / somethingElse.html" so that path traversal is possible, how long it takes in app / views / pages /. ., which is an acceptable way for me.
source to share
If you are using Rails 3.2 you are probably relying on the asset pipeline. The agreement is to place the images in the catalog of resources, which (by default) app/assets/images
, lib/assets/images
and vendor/assets/images
. Possible solutions: move your images or expand resource directories as described in this Rails tutorial .
EDIT: Extending resource directories in your case (add to yours application.rb
):
config.assets.paths << Rails.root.join("app","views","pages","myWebsite")
source to share