# 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.
ns_register_filter preauth GET {/*.pdf#*} strip_url_pdf_javascript
ns_register_filter preauth GET /*.pdf strip_pdf_javascript
proc safe_pdf_access_page {url} {
set location [ns_conn location]
set host [ns_set iget [ns_conn headers] host]
set page_text "Your PDF file request is available by clicking here
${location}$url"
}
proc 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 strip_pdf_javascript { args why } {
set a [ns_queryget a]
set ip [ns_conn peeraddr]
if {"$a" ne "$ip"} {
ns_log Debug "strip_pdf_javascript redirect"
ns_returnnotice 200 "PDF File Access" [safe_pdf_access_page [ns_conn url]?a=$ip]
return filter_return
}
return filter_ok
}