Skip to content

Commit

Permalink
implemented a sessionID (sid) check for exec.cgi/exec1.cgi which checks
Browse files Browse the repository at this point in the history
for a valid sessionID before executing any rega script code.
This fixes #4, thus CVE-2019-18939.
  • Loading branch information
jens-maus committed Nov 3, 2020
1 parent aeb187a commit 2386d13
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 47 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2
2.3
51 changes: 31 additions & 20 deletions www/exec.cgi
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#!/bin/tclsh

load tclrega.so
source session.tcl

catch {
set input $env(QUERY_STRING)
set pairs [split $input &]
foreach pair $pairs {
if {0 != [regexp "^(\[^=]*)=(.*)$" $pair dummy varname val]} {
set $varname $val
}
}
}

proc toString { str } {
set map {
Expand All @@ -27,25 +38,25 @@ proc toString { str } {
puts "Content-Type: text/plain; charset=iso-8859-1"
puts ""


if { [catch {
set content [read stdin]
array set script_result [rega_script $content]

set first 1
set result "\{\n"
foreach name [array names script_result] {
if { 1 != $first } { append result ",\n" } { set first 0 }
set value $script_result($name)
append result " [toString $name]: [toString $value]"
}
append result "\n\}"

puts $result
if {[info exists sid] && [check_session $sid]} {
if { [catch {
set content [read stdin]
array set script_result [rega_script $content]

} errorMessage] } {
puts $errorMessage
set first 1
set result "\{\n"
foreach name [array names script_result] {
if { 1 != $first } { append result ",\n" } { set first 0 }
set value $script_result($name)
append result " [toString $name]: [toString $value]"
}
append result "\n\}"

puts $result

} errorMessage] } {
puts $errorMessage
}
} else {
puts "{error: no valid session}"
}



54 changes: 34 additions & 20 deletions www/exec1.cgi
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#!/bin/tclsh

load tclrega.so
source session.tcl

catch {
set input $env(QUERY_STRING)
set pairs [split $input &]
foreach pair $pairs {
if {0 != [regexp "^(\[^=]*)=(.*)$" $pair dummy varname val]} {
set $varname $val
}
}
}

proc toString { str } {
set map {
Expand Down Expand Up @@ -29,25 +40,28 @@ proc toString { str } {
return "\"[string map $map $str]\""
}

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

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

if { [catch {
set content [read stdin]
array set script_result [rega_script $content]

set first 1
set result "\{\n"
foreach name [array names script_result] {
if { 1 != $first } { append result ",\n"} { set first 0 }
set value $script_result($name)
append result " [toString $name]: [toString $value]"
}
append result "\n\}"

puts $result
if {[info exists sid] && [check_session $sid]} {
if { [catch {
set content [read stdin]
array set script_result [rega_script $content]

} errorMessage] } {
puts $errorMessage
}
set first 1
set result "\{\n"
foreach name [array names script_result] {
if { 1 != $first } { append result ",\n"} { set first 0 }
set value $script_result($name)
append result " [toString $name]: [toString $value]"
}
append result "\n\}"

puts $result

} errorMessage] } {
puts $errorMessage
}
} else {
puts "{error: no valid session}"
}
7 changes: 4 additions & 3 deletions www/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,13 @@ changeNode = function(node)
if (e.onclick != null)
{
var fname = e.onclick.toString();
var sid = typeof(SessId) !== 'undefined' ? SessId : SessionId;
if ( fname.indexOf("EditScript") > -1)
{
var teilstring = fname.substring(fname.indexOf("EditScript") + 11);
var ssid = teilstring.substring(0, teilstring.indexOf(")"));
var req = xhr.create();
req.open("POST", "/addons/print/exec1.cgi", false);
req.open("POST", "/addons/print/exec1.cgi?sid="+sid, false);
var sreq = 'object oTmp = dom.GetObject( "' + ssid + '" ); if( oTmp ) { if( oTmp.DestinationValueType() == ivtString ) { Write( oTmp.DestinationValue().ToString() ); } }';
//alert(sreq);
req.send(sreq);
Expand All @@ -206,7 +207,7 @@ changeNode = function(node)
var teilstring = fname.substring(fname.indexOf(",") + 1).replace(" ", "");
var ssid = teilstring.substring(0, teilstring.indexOf(")"));
var req = xhr.create();
req.open("POST", "/addons/print/exec.cgi", false);
req.open("POST", "/addons/print/exec.cgi?sid="+sid, false);
var sreq = "";
if (window.DOMParser)
sreq = 'object tmObj = dom.GetObject("' + ssid + '"); Write("<?xml version=\\"1.0\\"?><!DOCTYPE tm [<!ENTITY amp \\"&#38;\\">]" # "><tm><zeile1>"); if (tmObj && (tmObj.Type() == OT_CALENDARDP)) { if (tmObj.SunOffsetType() == sotNone) { if ( (tmObj.CalDuration() == 0) && (tmObj.Time() == 0) ) { Write("<info>Zeitbereich ganzt&amp;auml;gig</info>"); } else { if (tmObj.CalDuration() != 0) { Write("<info>Zeitbereich von </info>"); Write("<convertDomTime>" # tmObj.Time() # "</convertDomTime>"); Write("<info> bis </info><calcEndTime>" # tmObj.Time() # ", " # tmObj.CalDuration() # "</calcEndTime>"); } else { Write("<info>Zeitpunkt: </info>"); Write("<convertDomTime>" # tmObj.Time() # "</convertDomTime>"); } } } else { if (tmObj.SunOffsetType() == sotAfterSunrise) { Write("<info>Zeitbereich Astrofunktion tags&amp;uuml;ber</info>"); } if (tmObj.SunOffsetType() == sotAfterSunset) { Write("<info>Zeitbereich Astrofunktion nachts</info>"); } } string sCalRep = tmObj.CalRepeatTime(); integer iPeriod = tmObj.Period(); integer iRepVal = tmObj.CalRepetitionValue(); integer iWdays = tmObj.Weekdays(); integer iType = tmObj.TimerType(); Write("</zeile1><zeile2>"); if (iType == ttCalOnce) { Write("<info>einmalig am: "); Write("<convertDomDate>" # sCalRep # "</convertDomDate>"); } if (iType == ttPeriodic) { Write("<info>Zeitintervall, alle "); integer iSelIdx = 0; string sVal = ""; sVal = iPeriod; if ( (iPeriod / (3600)) > 0) { if( (iPeriod % 3600) == 0 ) { sVal = iPeriod / (3600); iSelIdx = 0; } else { if( (iPeriod % 60) == 0 ) { sVal = iPeriod / (60); iSelIdx = 1; } else { sVal = iPeriod; iSelIdx = 2; } } } else { if ( (iPeriod / 60) > 0) { if( (iPeriod % 60) == 0 ) { sVal = iPeriod / (60); iSelIdx = 1; } else { sVal = iPeriod; iSelIdx = 2; } } else { sVal = iPeriod; iSelIdx = 2; } } if (iSelIdx == 0) { Write(sVal # " Stunden"); } if (iSelIdx == 1) { Write(sVal # " Minuten"); } if (iSelIdx == 2) { Write(sVal # " Sekunden"); } } if (iType == ttCalDaily) { Write("<info>t&amp;auml;glich, "); if (iRepVal != 0) { Write("alle " # iRepVal # " Tage"); } if (iWdays != 0) { if (iWdays == 96) { Write("am Wochenende (Sa., So.)"); } else { Write("jeden Tag, außer am Wochenende (Mo. bis Fr.)"); } } if ((iRepVal == 0) && (iWdays == 0)) { Write("jeden Tag"); } } if (iType == ttCalWeekly) { Write("<info>w&amp;ouml;chentlich, "); if (iRepVal != 0) { Write("alle " # iRepVal # " Wochen"); } else { Write("jede Woche am: "); } if ( (iWdays & 1) != 0) { Write("Montag "); } if ( (iWdays & 2) != 0) { Write("Dienstag "); } if ( (iWdays & 4) != 0) { Write("Mittwoch "); } if ( (iWdays & 8) != 0) { Write("Donnerstag "); } if ( (iWdays & 16) != 0) { Write("Freitag "); } if ( (iWdays & 32) != 0) { Write("Samstag "); } if ( (iWdays & 64) != 0) { Write("Sonntag"); } } if (iType == ttCalMonthly) { Write("<info>monatlich, "); if (iWdays == 0) { Write("am " # iPeriod # ". Tag jedes " # iRepVal # ". Monats"); } else { Write("jeden "); if (iPeriod == 1) { Write("ersten "); } if (iPeriod == 2) { Write("zweiten "); } if (iPeriod == 3) { Write("dritten "); } if (iPeriod == 4) { Write("vierten "); } if (iPeriod == 5) { Write("f&amp;uuml;nften "); } if (iWdays == 1) { Write("Montag "); } if (iWdays == 2) { Write("Dienstag "); } if (iWdays == 4) { Write("Mittwoch "); } if (iWdays == 8) { Write("Donnerstag "); } if (iWdays == 16) { Write("Freitag "); } if (iWdays == 32) { Write("Samstag "); } if (iWdays == 64) { Write("Sonntag "); } Write("jedes " # iRepVal # ". Monats"); } } if (iType == ttCalYearly) { Write("<info>j&amp;auml;hrlich, "); if (iWdays == 0) { Write("jeden " # iPeriod # ". "); if (iRepVal == 1) { Write("Januar"); } if (iRepVal == 2) { Write("Februar"); } if (iRepVal == 3) { Write("M&amp;auml;rz"); } if (iRepVal == 4) { Write("April"); } if (iRepVal == 5) { Write("Mai"); } if (iRepVal == 6) { Write("Juni"); } if (iRepVal == 7) { Write("Juli"); } if (iRepVal == 8) { Write("August"); } if (iRepVal == 9) { Write("September"); } if (iRepVal == 10) { Write("Oktober"); } if (iRepVal == 11) { Write("November"); } if (iRepVal == 12) { Write("Dezember"); } } else { Write("am "); if (iPeriod == 1) { Write("ersten "); } if (iPeriod == 2) { Write("zweiten "); } if (iPeriod == 3) { Write("dritten "); } if (iPeriod == 4) { Write("vierten "); } if (iPeriod == 5) { Write("f&amp;uuml;nften "); } if (iWdays == 1) { Write("Montag "); } if (iWdays == 2) { Write("Dienstag "); } if (iWdays == 4) { Write("Mittwoch "); } if (iWdays == 8) { Write("Donnerstag "); } if (iWdays == 16) { Write("Freitag "); } if (iWdays == 32) { Write("Samstag "); } if (iWdays == 64) { Write("Sonntag "); } Write("im "); if (iRepVal == 1) { Write("Januar"); } if (iRepVal == 2) { Write("Februar"); } if (iRepVal == 3) { Write("M&amp;auml;rz"); } if (iRepVal == 4) { Write("April"); } if (iRepVal == 5) { Write("Mai"); } if (iRepVal == 6) { Write("Juni"); } if (iRepVal == 7) { Write("Juli"); } if (iRepVal == 8) { Write("August"); } if (iRepVal == 9) { Write("September"); } if (iRepVal == 10) { Write("Oktober"); } if (iRepVal == 11) { Write("November"); } if (iRepVal == 12) { Write("Dezember"); } } } Write("</info>"); Write("</zeile2><zeile3>"); string sBegin = tmObj.Begin(); string sEnd = tmObj.End(); integer iCalCount = tmObj.CalRepetitionCount(); Write("<info>Beginn: </info><convertDomDate>" # sBegin # "</convertDomDate>"); if ( (iCalCount == 0) && (tmObj.EndSeconds() == 0) ) { Write("<info>, kein Enddatum</info>"); } else { if (iCalCount == 0) { Write("<info>, endet am: </info><convertDomDate>" # sEnd # "</convertDomDate>"); } else { Write("<info>, endet nach " # iCalCount # " Terminen</info>"); } } Write("</zeile3></tm>"); }';
Expand Down Expand Up @@ -395,7 +396,7 @@ getStdout = function()
}
catch (ex)
{
result = "INVALID JSON";
result = "INVALID JSON: " + textOutput;
}
return result;
};
Expand Down
6 changes: 3 additions & 3 deletions www/printprograms.htm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
getPrograms = function()
{
var req = xhr.create();
req.open("POST", "exec.cgi", false);
req.open("POST", "exec.cgi?sid="+SessionId, false);

var s = "string s_prgID;";
s += "object oPrg;";
Expand Down Expand Up @@ -75,7 +75,7 @@
/*p += " system.SetSessionVar(\"tmpPrgIDAL\", oPrg.ID());";
p += " Call(\"/esp/PrintPrograms.fn::PrintProgram()\")";*/

/*req.open("POST", "exec.cgi", false);
/*req.open("POST", "exec.cgi?sid="+SessionId, false);
req.send(p);
document.write(getStdout(req.responseText));*/
document.write(p);
Expand Down Expand Up @@ -152,4 +152,4 @@

</script>
</body>
</html>
</html>
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
}

0 comments on commit 2386d13

Please sign in to comment.