# Javascript injection exploit via pdf file request: # Info URL: http://www.webappsec.org/lists/websecurity/archive/2007-01/msg00005.html # More Info: http://www.gnucitizen.org/blog/danger-danger-danger/ # Exploit only requires that the Client click on a url of the form: # method://path/to/pdf/.pdf#somevar=javascript:some_script # Javascript is probably executed in the context of the user with rights to # the website where the pdf file sits. # NOTE 1: Some browsers, maybe all browsers, DO NOT SEND the internal link which # includes the javascript, so there is no way for the server to identify # potential threats. # The following code assumes that there is no reason to link internally to a # pdf document. # I don't know if there is a perfectly secure way of fixing this exploit from # the server side, but the theory is that it would be difficult for a javascript # program to figure out the ip address of the client. Most clients are behind firewalls, # so the external ip is not, or may not be easily available to javascript. # Otherwise, another potential solution is to use a hash function with a server side # secret to create a cookie/form var. This would then force the javascript exploit to # request the pdf file prior to rewriting the link. # NOTE 2: During a redirect, some browsers, maybe all browsers, KEEP THE INTERNAL LINK! # This means that the exploit is maintained even after a redirect to a safe url # So to handle this problem, a special page is returned with a clean url. # Users click on the link and will be able to access the pdf file normally. # INSTALLATION: # Place this file in your private tcl directory naming it # a-pdf-exploit-fix.tcl # In this directory there is probably a file named init.tcl. # At the top of this file place the following line, which will source the new # file: # source [file join [file dirname [info script]] a-pdf-exploit-fix.tcl] # Repeat this for each virtual server, then restart your aolserver nsd # process. # UPDATE: # This version uses a cookie instead of a query variable. # Query terms are passed through, although there is probably no reason for # them. # Cookies are only sent to the origin server and path, so a successful exploit # would require prefetch of the page from the client browser. ns_register_filter preauth GET /*.pdf ::pdfExploit::strip_pdf_javascript namespace eval ::pdfExploit { variable config set config(secret) "abcdefg" set server rmadilo } proc ::pdfExploit::safe_pdf_access_text {} { set url [ns_conn url] set location [ns_conn location] set query [ns_conn query] if {"$query" ne ""} { set query "?$query" } return "Your PDF file request is available by clicking here
${location}$url$query" } proc ::pdfExploit::createSecretHash { } { variable config foreach connVar {peeraddr url query location} { append hashText [ns_conn $connVar] } append hashText $config(secret) set secretHash [ns_sha1 $hashText] } proc ::pdfExploit::checkCookie { } { set secretHash [createSecretHash] ::cookie::getAll pdfExploit if {"$secretHash" ne "[::cookie::getByName pdfexploit "" pdfExploit]"} { ns_log Debug "No Match for checkCookie = '[::cookie::getByName pdfexploit "" pdfExploit]'" ::cookie::setCookie pdfexploit $secretHash -Path [file dirname [ns_conn url]] return 0 } else { return 1 } } proc ::pdfExploit::strip_url_pdf_javascript { args why } { set ip [ns_conn peeraddr] set original_url [ns_conn url] set end_of_good_url [expr [string first ".pdf" $original_url] + 3] set url [string range $original_url 0 $end_of_good_url] ns_log Debug "strip_url_pdf_javascript request for '$original_url'" ns_returnnotice 200 "PDF File Access" [safe_pdf_access_page ${url}?a=$ip] return filter_return } proc ::pdfExploit::strip_pdf_javascript { args why } { if {![checkCookie]} { ns_log Debug "strip_pdf_javascript redirect" ns_returnnotice 200 "PDF File Access" [safe_pdf_access_text] return filter_return } return filter_ok } ns_log Notice "sourced [info script]"