Thread: [htmltmpl] Suggestion on how to eliminate Cross-site-scripting (XSS) bugs for good.
Brought to you by:
samtregar
From: Shlomi F. <sh...@ig...> - 2006-10-17 10:26:32
|
Hi all! I am working on Yapcom ( http://yapcom.pti.co.il/ ) which is a Perl application that makes use of CGI::Application and HTML::Template. Now we had problems of Cross Site Scripting (XSS) in the past and I came up with this suggestion to hopefully eliminate them, that is based on the idea that it should be hard to output unescaped strings as is: The HTML::Template documentation for TMPL_VAR: http://search.cpan.org/~samtregar/HTML-Template-2.8/Template.pm#TMPL_VAR Reads: <<<< Optionally you can use the "ESCAPE=HTML" option in the tag to indicate that you want the value to be HTML-escaped before being returned from output (the old ESCAPE=1 syntax is still supported). This means that the ", <, >, and & characters get translated into ", <, > and & respectively. This is useful when you want to use a TMPL_VAR in a context where those characters would cause trouble. Example: >>>> Now what I want is to sub-class HTML::Template so we'll always have to use "ESCAPE=HTML". If we want to override it we'll need to do the following: 1. Wrap the string in a special object: <<<<< my $string_to_pass = "<h1>Hello</h1>"; my $string_to_pass_as_obj = YAPC::Template::PassThru->new($string_to_pass); >>>>> 2. Explicitly unlock the object: <<<<<< $string_to_pass_as_obj->unlock("unlock"); >>>>>> Note that unlock returns undef. 3. Add a special parameter to TMPL_VAR: <<<<<< <TMPL_VAR NAME="string_to_pass" PASSTHRU="1"> >>>>>> ----------------- If we pass a simple string then we can only use the TMPL_VAR with ESCAPE="HTML" added. We can also use ESCAPE="HTML" on an unlocked object. --------------------------- My question is: can this be already done with H::T? If not, I guess I'll work on a sub-class of H::T to do such a thing, unless someone can come up with a better idea. Regards, Shlomi Fish --------------------------------------------------------------------- Shlomi Fish sh...@ig... Homepage: http://www.shlomifish.org/ Chuck Norris wrote a complete Perl 6 implementation in a day but then destroyed all evidence with his bare hands, so no one will know his secrets. |
From: Alex K. <ka...@ra...> - 2006-10-17 12:05:32
|
* Shlomi Fish <sh...@ig...> [October 17 2006, 14:23]: > Now what I want is to sub-class HTML::Template so we'll always have to > use "ESCAPE=HTML". If we want to override it we'll need to do the following: There's `default_escape' option in recent HTML::Template. Is it not enough? -- Alex Kapranoff, $n=["1another7Perl213Just3hacker49"=~/\d|\D*/g]; $$n[0]={grep/\d/,@$n};print"@$n{1..4}\n" |
From: Michael P. <mp...@pl...> - 2006-10-17 13:04:13
|
Alex Kapranoff wrote: > * Shlomi Fish <sh...@ig...> [October 17 2006, 14:23]: >> Now what I want is to sub-class HTML::Template so we'll always have to >> use "ESCAPE=HTML". If we want to override it we'll need to do the following: > > There's `default_escape' option in recent HTML::Template. Is it not > enough? I think if you use default_escape => 'HTML' that would get him most of the way. But there should be a way to turn off escaping when you know the var will contain HTML. So maybe an escape="none" option? -- Michael Peters Developer Plus Three, LP |
From: Alex K. <ka...@ra...> - 2006-10-17 13:20:03
|
* Michael Peters <mp...@pl...> [October 17 2006, 17:01]: > Alex Kapranoff wrote: > > * Shlomi Fish <sh...@ig...> [October 17 2006, 14:23]: > >> Now what I want is to sub-class HTML::Template so we'll always have to > >> use "ESCAPE=HTML". If we want to override it we'll need to do the following: > > > > There's `default_escape' option in recent HTML::Template. Is it not > > enough? > > I think if you use default_escape => 'HTML' that would get him most of the way. > But there should be a way to turn off escaping when you know the var will > contain HTML. So maybe an escape="none" option? ESCAPE="0" works for now. -- Alex Kapranoff, $n=["1another7Perl213Just3hacker49"=~/\d|\D*/g]; $$n[0]={grep/\d/,@$n};print"@$n{1..4}\n" |
From: Michael P. <mp...@pl...> - 2006-10-17 13:55:08
|
Alex Kapranoff wrote: > ESCAPE="0" works for now. Well, there you go, I didn't even know you could do that. Shlomi, I think using default_escape and escpe=0 for the exceptions is a much cleaner way to go. -- Michael Peters Developer Plus Three, LP |
From: Tom H. <tom...@pu...> - 2006-10-17 15:24:45
|
Alex Kapranoff wrote: > * Michael Peters <mp...@pl...> [October 17 2006, 17:01]: >> Alex Kapranoff wrote: >>> * Shlomi Fish <sh...@ig...> [October 17 2006, 14:23]: >>>> Now what I want is to sub-class HTML::Template so we'll always have to >>>> use "ESCAPE=HTML". If we want to override it we'll need to do the following: >>> There's `default_escape' option in recent HTML::Template. Is it not >>> enough? >> I think if you use default_escape => 'HTML' that would get him most of the way. >> But there should be a way to turn off escaping when you know the var will >> contain HTML. So maybe an escape="none" option? > > ESCAPE="0" works for now. > Actually, I found that turning off escaping (ESCAPE="0") does not work if you specify a default escape. See http://rt.cpan.org/Public/Bug/Display.html?id=18274 for more details and a fix. ---Tom |
From: Sam T. <sa...@tr...> - 2006-11-15 21:01:35
|
On Tue, 17 Oct 2006, Tom Heady wrote: > Actually, I found that turning off escaping (ESCAPE="0") does not work > if you specify a default escape. > > See http://rt.cpan.org/Public/Bug/Display.html?id=18274 for more details > and a fix. I'll make sure this gets into the next release. I'm planning to put one out soon. -sam |
From: Tom H. <tom...@pu...> - 2006-11-17 00:55:47
|
Sam Tregar wrote: > On Tue, 17 Oct 2006, Tom Heady wrote: > >> Actually, I found that turning off escaping (ESCAPE="0") does not work >> if you specify a default escape. >> >> See http://rt.cpan.org/Public/Bug/Display.html?id=18274 for more details >> and a fix. > > I'll make sure this gets into the next release. I'm planning to put > one out soon. > Thanks Tom |
From: Shlomi F. <sh...@ig...> - 2006-10-25 16:05:24
|
On Tuesday 17 October 2006 14:08, Alex Kapranoff wrote: > * Shlomi Fish <sh...@ig...> [October 17 2006, 14:23]: > > Now what I want is to sub-class HTML::Template so we'll always have to > > use "ESCAPE=HTML". If we want to override it we'll need to do the > > following: > > There's `default_escape' option in recent HTML::Template. Is it not > enough? Having read the thread, I don't think that's enough for me. I want to still need to explicitly specify "ESCAPE=HTML" everywhere (without having a default escape), to have an exception raised on a non-escaped occurence, and to add an explicit unescaping (like "ESCAPE="0""). Anything less than that will make the transition to the new code harder, and more error-prone. So I guess I'm going to fire up my editor and write an HTML::Template sub-class. Regards, Shlomi Fish --------------------------------------------------------------------- Shlomi Fish sh...@ig... Homepage: http://www.shlomifish.org/ Chuck Norris wrote a complete Perl 6 implementation in a day but then destroyed all evidence with his bare hands, so no one will know his secrets. |
From: Jonathan L. <dat...@gm...> - 2006-10-25 23:07:28
|
Shlomi Fish wrote: > Having read the thread, I don't think that's enough for me. I want to still > need to explicitly specify "ESCAPE=HTML" everywhere (without having a default > escape), to have an exception raised on a non-escaped occurence, and to add > an explicit unescaping (like "ESCAPE="0""). Let me see if I've got this straight: you want to force the template writer to include "ESCAPE=something" in every TMPL_VAR, where "something" can be "HTML", "URL", or a value indicating "no escapes" (say, "TEXT"); failure to do so would cause a catchable error in your script when you try to evaluate the template. Right? > So I guess I'm going to fire up my editor and write an HTML::Template > sub-class. Probably. May I suggest a form for your subclass to take? Let "default_escape" contain two additional values: "TEXT" (which means the same as "0" above, and can also be used in 'ESCAPE=' to override the default with no escaping), and "NONE" (which throws an exception any time a TMPL_VAR lacks 'ESCAPE='). This will let you easily switch to an appropriate default_escape value once transition to the new code is complete. -- Jonathan "Dataweaver" Lang |
From: Shlomi F. <sh...@ig...> - 2006-11-15 19:22:36
|
On Thursday 26 October 2006 01:07, Jonathan Lang wrote: > Shlomi Fish wrote: > > Having read the thread, I don't think that's enough for me. I want to > > still need to explicitly specify "ESCAPE=HTML" everywhere (without having > > a default escape), to have an exception raised on a non-escaped > > occurence, and to add an explicit unescaping (like "ESCAPE="0""). > > Let me see if I've got this straight: you want to force the template > writer to include "ESCAPE=something" in every TMPL_VAR, where > "something" can be "HTML", "URL", or a value indicating "no escapes" > (say, "TEXT"); failure to do so would cause a catchable error in your > script when you try to evaluate the template. Right? > Yes. > > So I guess I'm going to fire up my editor and write an HTML::Template > > sub-class. > > Probably. May I suggest a form for your subclass to take? Let > "default_escape" contain two additional values: "TEXT" (which means > the same as "0" above, and can also be used in 'ESCAPE=' to override > the default with no escaping), and "NONE" (which throws an exception > any time a TMPL_VAR lacks 'ESCAPE='). This will let you easily switch > to an appropriate default_escape value once transition to the new code > is complete. OK. Regards, Shlomi Fish --------------------------------------------------------------------- Shlomi Fish sh...@ig... Homepage: http://www.shlomifish.org/ Chuck Norris wrote a complete Perl 6 implementation in a day but then destroyed all evidence with his bare hands, so no one will know his secrets. |
From: Mathew R. <mat...@ne...> - 2006-10-26 00:12:04
|
>> Having read the thread, I don't think that's enough for me. I want to still >> need to explicitly specify "ESCAPE=HTML" everywhere (without having a default >> escape), to have an exception raised on a non-escaped occurence, and to add >> an explicit unescaping (like "ESCAPE="0""). > > Let me see if I've got this straight: you want to force the template > writer to include "ESCAPE=something" in every TMPL_VAR, where > "something" can be "HTML", "URL", or a value indicating "no escapes" > (say, "TEXT"); failure to do so would cause a catchable error in your > script when you try to evaluate the template. Right? hmm... it doesn't sound right at all. Forcing the developer to remember to have to type ESCAPE=... for every TMPL_VAR is just not right. I personally forget to even use NAME=... and I just about never quote the value either due to laziness. The reality is that people are lazy/forgetful/efficient - the general idea in life is to make life easier, not harder. I'd suggest just to use the functionality as is. ie: set default_escape to whatever the default is; when no escape is necessary, then the developer will explicitly say so. >> So I guess I'm going to fire up my editor and write an HTML::Template >> sub-class. > > Probably. May I suggest a form for your subclass to take? Let > "default_escape" contain two additional values: "TEXT" (which means > the same as "0" above, and can also be used in 'ESCAPE=' to override > the default with no escaping), and "NONE" (which throws an exception > any time a TMPL_VAR lacks 'ESCAPE='). This will let you easily switch > to an appropriate default_escape value once transition to the new code > is complete. Please dont use "TEXT" to mean none - there is at least one filter that has been posted on this list which is for 'text' documents. ie: the filter is like the HTML filter, but also handles newlines & carriage returns, etc. How about "NONE" or "NO" or "0" to mean 'no escaping is necessary'. Also, "NONE" (as described above) should be "THROW" - the term is common in computer science, lets use it. Mathew |
From: Eric F. <er...@dm...> - 2006-10-26 16:37:10
|
Hi, This is pretty topical for me, but a little off topic for HTML::Template.. I was looking for a good example on how to do this filtering. In the Perl world I found HTML::StripScripts and it looked like a good idea at the time sort of thing, it just seemed too good/complex for me. Like the best way to do things, but I don't have time for that :) I found this example in PHP and was trying to convert it to perl, got most of it working, but the last part I am a little baffled about what it is really for.. http://quickwired.com/kallahar/smallprojects/php_xss_filter_function.php Below is my version of the above, which skips that last set of loops. I get what they do, but I don't get why or in what circumstance that filtering is needed and I am not really sure why he breaks the tags instead of just removing them, maybe it is more for illustration that live use? The $val test in the script is from one of the many examples on http://ha.ckers.org/xss.html On another note. I was very happy to find mod_security which I am testing out now. My first thought had been to do something with an Apache module, because this kind of filtering I think belongs on the web server level not the application level, that seems so much safer to me when you have a bunch of code sitting around from various people that can't all be audited and kept that way, but then once I started looking into this I found mod_security already does this and is extremely configurable. One thing I was wondering about, if anyone has compiled this with PCRE I would love to know how you did it. One possible issue mentioned on their site says doing the module compile that way prevents some issues with certain types of reg exp.. Thanks, Eric use strict; use warnings; use Data::Dumper; use Data::Translate; my $trns = new Data::Translate; ##sub RemoveXSS { #my $val = shift; my $val = q!<IMG SRC=@avascript:alert('XSS')>!; my $search = undef; print "$val\n"; $val =~ s/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/ /g; print "$val >>> $` $& $'\n\n\n"; $search = 'abcdefghijklmnopqrstuvwxyz'; $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $search .= '1234567890!@#$%^&*()'; $search .= '~`";:?+/={}[]-_|\'\\'; my @search_arr=split(//,$search); foreach my $char(@search_arr){ my $bob1 = $trns->d2h(ord($char)); my $bob2 = ord($char); print "$char -- $bob1 --- \n"; $val =~ s/(&#[x|X]0{0,8}$bob1);?/$char/gi; print "***$val***\n"; $val =~ s/(�{0,8}$bob2);?/$char/gi; ## with a ; (&#[x|X]0{0,8} print "***$val******\n\n"; } my @ra = qw(javascript vbscript expression applet meta xml blink link style script embed object iframe frame frameset ilayer layer bgsound title base onabort onactivate onafterprint onafterupdate onbeforeactivate onbeforecopy onbeforecut onbeforedeactivate onbeforeeditfocus onbeforepaste onbeforeprint onbeforeunload onbeforeupdate onblur onbounce oncellchange onchange onclick oncontextmenu oncontrolselect oncopy oncut ondataavailable ondatasetchanged ondatasetcomplete ondblclick ondeactivate ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop onerror onerrorupdate onfilterchange onfinish onfocus onfocusin onfocusout onhelp onkeydown onkeypress onkeyup onlayoutcomplete onload onlosecapture onmousedown onmouseenter onmouseleave onmousemove onmouseout onmouseover onmouseup onmousewheel onmove onmoveend onmovestart onpaste onpropertychange onreadystatechange onreset onresize onresizeend onresizestart onrowenter onrowexit onrowsdelete onrowsinserted onscroll onselect onselectionchange onselectstart onstart onstop onsubmit onunload); foreach my $badword(@ra){ $val =~ s/$badword/<x>/gi; } print "####$val#####"; ## should print <IMG SRC=@avasc<x>ript:alert('XSS')> At 05:12 PM 25/10/2006, Mathew Robertson wrote: > >> Having read the thread, I don't think that's enough for me. I want to > still > >> need to explicitly specify "ESCAPE=HTML" everywhere (without having a > default > >> escape), to have an exception raised on a non-escaped occurence, and > to add > >> an explicit unescaping (like "ESCAPE="0""). > > > > Let me see if I've got this straight: you want to force the template > > writer to include "ESCAPE=something" in every TMPL_VAR, where > > "something" can be "HTML", "URL", or a value indicating "no escapes" > > (say, "TEXT"); failure to do so would cause a catchable error in your > > script when you try to evaluate the template. Right? > >hmm... it doesn't sound right at all. Forcing the developer to >remember to have to type ESCAPE=... for every TMPL_VAR is just not >right. > >I personally forget to even use NAME=... and I just about never >quote the value either due to laziness. > >The reality is that people are lazy/forgetful/efficient - the >general idea in life is to make life easier, not harder. I'd >suggest just to use the functionality as is. ie: set default_escape >to whatever the default is; when no escape is necessary, then the >developer will explicitly say so. > > >> So I guess I'm going to fire up my editor and write an HTML::Template > >> sub-class. > > > > Probably. May I suggest a form for your subclass to take? Let > > "default_escape" contain two additional values: "TEXT" (which means > > the same as "0" above, and can also be used in 'ESCAPE=' to override > > the default with no escaping), and "NONE" (which throws an exception > > any time a TMPL_VAR lacks 'ESCAPE='). This will let you easily switch > > to an appropriate default_escape value once transition to the new code > > is complete. > >Please dont use "TEXT" to mean none - there is at least one filter >that has been posted on this list which is for 'text' documents. >ie: the filter is like the HTML filter, but also handles newlines & >carriage returns, etc. How about "NONE" or "NO" or "0" to mean 'no >escaping is necessary'. > >Also, "NONE" (as described above) should be "THROW" - the term is >common in computer science, lets use it. > >Mathew > >------------------------------------------------------------------------- >Using Tomcat but need to do more? Need to support web services, security? >Get stuff done quickly with pre-integrated technology to make your job easier >Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo >http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 >_______________________________________________ >Html-template-users mailing list >Htm...@li... >https://lists.sourceforge.net/lists/listinfo/html-template-users |
From: Dan H. <dan...@re...> - 2006-10-26 17:14:14
|
> From: htm...@li... [mailto:html- > tem...@li...] On Behalf Of Eric Frazier > > This is pretty topical for me, but a little off topic for HTML::Template.. > I was looking for a good example on how to do this filtering. In the Perl > world I found HTML::StripScripts > and it looked like a good idea at the time sort of thing, it just seemed > too good/complex for me. Like the best way to do things, but I don't have > time for that :) > Another option for santising input is HTML::Scrubber (http://search.cpan.org/dist/HTML-Scrubber/). I use it via the Data::FormValidator filter Data::FormValidator::Filters::HTMLScrubber to remove not just scripts but tags that I don't want users to supply (like "font"). Dan |
From: Shlomi F. <sh...@ig...> - 2006-11-15 19:26:39
|
On Thursday 26 October 2006 02:12, Mathew Robertson wrote: > >> Having read the thread, I don't think that's enough for me. I want to > >> still need to explicitly specify "ESCAPE=HTML" everywhere (without > >> having a default escape), to have an exception raised on a non-escaped > >> occurence, and to add an explicit unescaping (like "ESCAPE="0""). > > > > Let me see if I've got this straight: you want to force the template > > writer to include "ESCAPE=something" in every TMPL_VAR, where > > "something" can be "HTML", "URL", or a value indicating "no escapes" > > (say, "TEXT"); failure to do so would cause a catchable error in your > > script when you try to evaluate the template. Right? > > hmm... it doesn't sound right at all. Forcing the developer to > remember to have to type ESCAPE=... for every TMPL_VAR is just not > right. > > I personally forget to even use NAME=... and I just about never > quote the value either due to laziness. > > The reality is that people are lazy/forgetful/efficient - the > general idea in life is to make life easier, not harder. I'd > suggest just to use the functionality as is. ie: set default_escape > to whatever the default is; when no escape is necessary, then the > developer will explicitly say so. > In case you forget to do that, then perl will throw an exception and force you to add that. So you won't get something bad for your laziness/forgetfulness. Besides, this would be a sub-class of HTML::Template and no-one will be forced to use it. > >> So I guess I'm going to fire up my editor and write an HTML::Template > >> sub-class. > > > > Probably. May I suggest a form for your subclass to take? Let > > "default_escape" contain two additional values: "TEXT" (which means > > the same as "0" above, and can also be used in 'ESCAPE=' to override > > the default with no escaping), and "NONE" (which throws an exception > > any time a TMPL_VAR lacks 'ESCAPE='). This will let you easily switch > > to an appropriate default_escape value once transition to the new code > > is complete. > > Please dont use "TEXT" to mean none - there is at least one filter > that has been posted on this list which is for 'text' documents. > ie: the filter is like the HTML filter, but also handles newlines & > carriage returns, etc. How about "NONE" or "NO" or "0" to mean 'no > escaping is necessary'. > > Also, "NONE" (as described above) should be "THROW" - the term is > common in computer science, lets use it. > I'll use NONE. Regards, Shlomi Fish --------------------------------------------------------------------- Shlomi Fish sh...@ig... Homepage: http://www.shlomifish.org/ Chuck Norris wrote a complete Perl 6 implementation in a day but then destroyed all evidence with his bare hands, so no one will know his secrets. |