Skip to content

Commit

Permalink
added a sessionID check to all our .cgi scripts so that they can only be
Browse files Browse the repository at this point in the history
executed within an valid WebUI login. This fixes #11, thus
CVE-2019-18938.
  • Loading branch information
jens-maus committed Nov 4, 2020
1 parent 6db39b1 commit 49895b0
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 82 deletions.
37 changes: 22 additions & 15 deletions www/backup.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,28 @@
#
###

#set datum [clock seconds]
#set datum [clock format $datum -format {%d-%m-%Y}]
load tclrega.so
source querystring.tcl
source session.tcl

# Backup ausführen
set backup "/etc/config/addons/email/backup.sh"
exec $backup
puts "Content-Type: text/plain; charset=iso-8859-1"
puts ""

# Ausgabe des Backups
after 2000
if { [file exists "/etc/config/addons/email/email-backup.tar.gz"] } {
puts "Content-Type: text/plain"
puts ""
if {[info exists sid] && [check_session $sid]} {
#set datum [clock seconds]
#set datum [clock format $datum -format {%d-%m-%Y}]

# Backup ausführen
set backup "/etc/config/addons/email/backup.sh"
exec $backup

# Ausgabe des Backups
after 2000
if { [file exists "/etc/config/addons/email/email-backup.tar.gz"] } {
puts -nonewline "BACKUPOK"
} else {
puts "Content-Type: text/plain"
puts ""
puts "ERROR"
}
} else {
puts -nonewline "ERROR: could not find backup"
}
} else {
puts -nonewline "Error: no valid session"
}
26 changes: 15 additions & 11 deletions www/config_js.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
# @license Public Domain
##

load tclrega.so
source querystring.tcl
source session.tcl
source /etc/config/addons/email/config.tcl

################################################################################
Expand Down Expand Up @@ -67,8 +70,7 @@ proc putMails {} {
global MAIL_DIR MAIL_IDS
set first 1

puts " Mails:"
puts " \["
puts " \"Mails\": \["

foreach id $MAIL_IDS {
if { 1 != $first } then { puts " ," } else { set first 0 }
Expand Down Expand Up @@ -125,8 +127,7 @@ proc putAccount {} {

catch { array set account [loadFromFile $ACCOUNT_FILE] }

puts " Account:"
puts " \{"
puts " \"Account\": \{"
puts " \"server\": \"[jsstring $account(Server)]\","
puts " \"from\": \"[jsstring $account(From)]\","
puts " \"auth\": \"[jsstring $account(Auth)]\","
Expand Down Expand Up @@ -154,11 +155,14 @@ proc putUserScript {} {

puts "Content-Type: text/javascript; charset=utf-8"
puts ""
puts "Configuration ="
puts "\{"
putMails
puts " ,"
putAccount
puts " ,"
putUserScript
puts "\};"
if {[info exists sid] && [check_session $sid]} {
putMails
puts " ,"
putAccount
puts " ,"
putUserScript
} else {
puts "ERROR: no valid session"
}
puts "\}"
48 changes: 34 additions & 14 deletions www/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* @license Public Domain
**/

var SessionId = "";
var Configuration;

/*############################################################################*/
/*# DOM-Funktionen #*/
/*############################################################################*/
Expand Down Expand Up @@ -210,7 +213,7 @@ Mail = function(mailData)
* @const Mail.URL
* @brief URL zum Speichern von E-Mails.
**/
Mail.URL = "/addons/email/save.cgi?mail"
Mail.URL = "/addons/email/save.cgi";

Mail.prototype =
{
Expand Down Expand Up @@ -306,7 +309,7 @@ Mail.prototype =
data += this.m_content;

var result = "AJAX error";
try { result = http.post(Mail.URL, data); }
try { result = http.post(Mail.URL + '?sid=' + SessionId + '&mail', data); }
catch (ex) { }
if ("OK" == result) { alert("E-Mail wurde erfolgreich gespeichert!"); }
else { alert("Fehler beim Speichern der E-Mail (" + result + ")!"); }
Expand Down Expand Up @@ -380,7 +383,7 @@ MailCollection =

Account =
{
URL: "/addons/email/save.cgi?account",
URL: "/addons/email/save.cgi",

init: function()
{
Expand Down Expand Up @@ -411,7 +414,7 @@ Account =
data += "\n";

var result = "AJAX error";
try { result = http.post(Account.URL, data); }
try { result = http.post(Account.URL + '?sid='+SessionId+'&account', data); }
catch (ex) { }
if ("OK" == result) { alert("Kontodaten wurden erfolgreich gespeichert!"); }
else { alert("Fehler beim Speichern der Kontodaten (" + result + ")!"); }
Expand All @@ -434,7 +437,7 @@ Account =
**/
Tcl =
{
URL: "/addons/email/save.cgi?userScript",
URL: "/addons/email/save.cgi",

/**
* @fn init
Expand All @@ -456,7 +459,7 @@ Tcl =
data += $("userScriptTextArea").value;

var result = "AJAX error";
try { result = http.post(Tcl.URL, data); }
try { result = http.post(Tcl.URL + '?sid='+SessionId+'&userScript', data); }
catch (ex) { }
if ("OK" == result) { alert("Tcl Script wurde erfolgreich gespeichert!"); }
else { alert("Fehler beim Speichern des Tcl Scripts (" + result + ")!"); }
Expand All @@ -482,7 +485,7 @@ TestTCL =
data += $("userScriptTextArea").value;

var result = "AJAX error";
try { result = http.m_request("GET", TestTCL.URL, null); }
try { result = http.m_request("GET", TestTCL.URL + '?sid='+SessionId, null); }
catch (ex) { }
if ("TCLOK" == result) { alert("Das Tcl-Skript ist okay!"); }
else { alert("Das Tcl-Skript ist fehlerhaft: (" + result + ")"); }
Expand All @@ -496,7 +499,7 @@ TestTCL =

Test =
{
URL: "/addons/email/testmail.cgi?ID=1",
URL: "/addons/email/testmail.cgi",

/**
* @fn apply
Expand All @@ -509,7 +512,7 @@ Test =
data += $("userScriptTextArea").value;

var result = "AJAX error";
try { result = http.m_request("GET", Test.URL, null); }
try { result = http.m_request("GET", Test.URL + '?sid='+SessionId+'&ID=1', null); }
catch (ex) { }
if ("OK" == result) { alert("Testmail wurde gesendet!"); }
else { alert("Fehler beim Senden der Email (" + result + ")!"); }
Expand All @@ -527,7 +530,7 @@ Backup =
apply: function()
{
var result = "AJAX error";
try { result = http.m_request("GET", Backup.URL, null); }
try { result = http.m_request("GET", Backup.URL + '?sid='+SessionId, null); }
catch (ex) { }
if ("BACKUPOK" == result) { window.open('/addons/email/addon/email-backup.tar.gz');
}
Expand All @@ -545,8 +548,25 @@ Backup =
**/
startup = function()
{
MailCollection.init();
Account.init();
Tcl.init();
MainMenu.select("mailMenuButton");
if (location.search)
{
if (location.search.indexOf("sid=") > -1)
{
var teil = location.search.substring(location.search.indexOf("sid=") + 4);
if (teil.indexOf("&") > -1)
SessionId = teil.substring(0, teil.indexOf("&"));
else
SessionId = teil;
}
}

Configuration = JSON.parse(http.m_request("GET", "/addons/email/config_js.cgi?sid="+SessionId, null));
if (typeof(Configuration.Mails) !== 'undefined') {
MailCollection.init();
Account.init();
Tcl.init();
MainMenu.select("mailMenuButton");
} else {
alert("ERROR: no valid session");
}
};
2 changes: 0 additions & 2 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
<meta http-equiv="expires" content="0">
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="email.js"></script>
<script type="text/javascript" src="config_js.cgi"></script>

</head>
<body onload="startup();">
<div id="page">
Expand Down
9 changes: 9 additions & 0 deletions www/querystring.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
catch {
set input $env(QUERY_STRING)
set pairs [split $input &]
foreach pair $pairs {
if {0 != [regexp "^(\[^=]*)=(.*)$" $pair dummy varname val]} {
set $varname $val
}
}
}
32 changes: 22 additions & 10 deletions www/save.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,15 @@
# @license Public Domain
##

if { [catch {
load tclrega.so
source session.tcl
source querystring.tcl

puts "Content-Type: text/plain; charset=iso-8859-1"
puts ""

if { [info exists sid] && [check_session $sid] } {
if { [catch {

source /etc/config/addons/email/config.tcl

Expand Down Expand Up @@ -90,7 +98,14 @@ if { [catch {

# 3. CGI-Query übernehmen
if { [info exists env(QUERY_STRING)] } then {
set __args(Query) $env(QUERY_STRING)
set input $env(QUERY_STRING)
set pairs [split $input &]
foreach pair $pairs {
if {0 == [regexp "^(\[^=]*)=(.*)$" $pair dummy varname val]} {
set __args(Query) $pair
break
}
}
}
}

Expand Down Expand Up @@ -249,14 +264,11 @@ if { [catch {
default { error "Unknown Command [__args_get Query]" }
}

puts "Content-Type: text/plain"
puts ""
puts -nonewline "OK"

} errorMessage] } then {
puts "Content-Type: text/plain"
puts ""
puts "ERROR $errorMessage"
} errorMessage] } then {
puts -nonewline "ERROR $errorMessage"
}
} else {
puts -nonewline "ERROR: no valid session"
}


13 changes: 13 additions & 0 deletions www/session.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/tclsh

load tclrega.so

proc check_session sid {
if {[regexp {@([0-9a-zA-Z]{10})@} $sid all sidnr]} {
set res [lindex [rega_script "Write(system.GetSessionVarStr('$sidnr'));"] 1]
if {$res != ""} {
return 1
}
}
return 0
}
40 changes: 23 additions & 17 deletions www/testmail.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,30 @@
# @license Public Domain
##

load tclrega.so
source querystring.tcl
source session.tcl

puts "Content-Type: text/plain; charset=iso-8859-1"
puts ""

set email "/etc/config/addons/email/email"

if { [info exists env(QUERY_STRING)] } {
regsub -all {[&=]} $env(QUERY_STRING) { } query_str
regsub -all { } $query_str { {} } query_str
foreach {key val} $query_str {
set query($key) $val
}
if { [info exists query(ID)] } {
set ID [ format "%02d" $query(ID) ]
exec $email $ID
puts "Content-Type: text/plain"
puts ""
puts -nonewline "OK"
} else {
puts "Content-Type: text/plain"
puts ""
puts "ERROR ID missing"
if {[info exists sid] && [check_session $sid]} {
if { [info exists env(QUERY_STRING)] } {
regsub -all {[&=]} $env(QUERY_STRING) { } query_str
regsub -all { } $query_str { {} } query_str
foreach {key val} $query_str {
set query($key) $val
}
if { [info exists query(ID)] } {
set ID [ format "%02d" $query(ID) ]
exec $email $ID
puts -nonewline "OK"
} else {
puts -nonewline "ERROR: ID missing"
}
}
} else {
puts -nonewline "Error: no valid session"
}

Loading

0 comments on commit 49895b0

Please sign in to comment.