# 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]"