plugin:exttab2
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
plugin:exttab2 [2010-05-13 15:03] – 74.108.1.236 | plugin:exttab2 [2020-06-04 16:25] (current) – StarArmy | ||
---|---|---|---|
Line 6: | Line 6: | ||
email : disorder.chang@gmail.com | email : disorder.chang@gmail.com | ||
type : Syntax | type : Syntax | ||
- | lastupdate : 2007-11-06 | + | lastupdate : 2010-08-28 |
- | compatible : 2007-06-26b | + | compatible : 2007-06-26b, !Hogfather |
depends | depends | ||
conflicts | conflicts | ||
- | similar | + | similar |
- | tags : Mediawiki, tables | + | tags : Mediawiki, tables, !obsolete |
- | securityissue: | + | |
+ | downloadurl: | ||
+ | sourcerepo: https:// | ||
+ | |||
+ | securityissue: | ||
---- | ---- | ||
Line 129: | Line 133: | ||
now | now | ||
| . | | . | ||
+ | |} | ||
+ | </ | ||
+ | |||
+ | === Failed attempts at XSS attacks === | ||
+ | < | ||
+ | {| border=" | ||
+ | |- | ||
+ | |onmouseover=" | ||
+ | **javascript onmouseover attack** | ||
+ | |style=" | ||
+ | **CSS url attack** | ||
+ | |- | ||
+ | |style=' | ||
+ | stuff | ||
+ | | | ||
+ | |->< | ||
+ | | **illegal close tag attack** | ||
+ | |col2 | ||
+ | |- | ||
+ | |colspan=' | ||
+ | |- | ||
+ | |rowspan=' | ||
+ | |- | ||
+ | | does | ||
|} | |} | ||
</ | </ | ||
Line 142: | Line 170: | ||
=====Revision History===== | =====Revision History===== | ||
+ | * 2010-08-28 0.3.0 (hopefully) fixed XSS vulnerability ([[marcianx@gmail.com|Ashish Myles]]) | ||
* 2006-11-06 0.2.0 support nested table and many more... | * 2006-11-06 0.2.0 support nested table and many more... | ||
* 2006-10-04 0.1.0 Initial release | * 2006-10-04 0.1.0 Initial release | ||
=====Sources===== | =====Sources===== | ||
- | <code php> | + | < |
<?php | <?php | ||
// | // | ||
Line 154: | Line 182: | ||
* @license | * @license | ||
* @author | * @author | ||
- | * @date 2007-10-04 | + | * @date 2010-08-28 |
*/ | */ | ||
Line 168: | Line 196: | ||
*/ | */ | ||
class syntax_plugin_exttab2 extends DokuWiki_Syntax_Plugin { | class syntax_plugin_exttab2 extends DokuWiki_Syntax_Plugin { | ||
+ | |||
var $stack = array(); | var $stack = array(); | ||
+ | |||
function syntax_plugin_exttab2(){ | function syntax_plugin_exttab2(){ | ||
define(" | define(" | ||
Line 183: | Line 211: | ||
EXTTAB2_TD=> | EXTTAB2_TD=> | ||
EXTTAB2_TH=> | EXTTAB2_TH=> | ||
+ | |||
/* // DOKU constant not work when preview | /* // DOKU constant not work when preview | ||
EXTTAB2_TABLE=> | EXTTAB2_TABLE=> | ||
Line 191: | Line 219: | ||
EXTTAB2_TH=> | EXTTAB2_TH=> | ||
*/ ); | */ ); | ||
+ | |||
+ | /* attribute whose value is a single word */ | ||
+ | $this-> | ||
+ | # table attributes | ||
+ | # simple ones (value is a single word) | ||
+ | ' | ||
+ | # more complex ones (value is a string or style) | ||
+ | ' | ||
+ | # additional tr, thead, tbody, tfoot attributes | ||
+ | ' | ||
+ | # additional td attributes | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
} | } | ||
Line 197: | Line 239: | ||
' | ' | ||
' | ' | ||
- | ' | + | ' |
' | ' | ||
' | ' | ||
Line 226: | Line 268: | ||
function postConnect() { | function postConnect() { | ||
$para = " | $para = " | ||
+ | |||
// caption: |+ params | caption | // caption: |+ params | caption | ||
$this-> | $this-> | ||
+ | |||
// row: |- params | // row: |- params | ||
$this-> | $this-> | ||
+ | |||
// table open | // table open | ||
$this-> | $this-> | ||
+ | |||
// table close | // table close | ||
$this-> | $this-> | ||
- | | + | |
// header | // header | ||
$this-> | $this-> | ||
+ | |||
//cell | //cell | ||
$this-> | $this-> | ||
+ | |||
//end | //end | ||
// $this-> | // $this-> | ||
Line 250: | Line 292: | ||
$this-> | $this-> | ||
} | } | ||
- | | + | |
/** | /** | ||
* Handle the match | * Handle the match | ||
Line 265: | Line 307: | ||
if(preg_match ( '/ | if(preg_match ( '/ | ||
$func = " | $func = " | ||
- | $params = $m[1]; | + | $params = $this-> |
return array($state, | return array($state, | ||
} | } | ||
Line 275: | Line 317: | ||
else if(preg_match ("/ | else if(preg_match ("/ | ||
$func = " | $func = " | ||
- | $params = $m[1]; | + | $params = $this-> |
return array($state, | return array($state, | ||
} | } | ||
else if(preg_match ( '/ | else if(preg_match ( '/ | ||
$func = " | $func = " | ||
- | $params = $m[1]; | + | $params = $this-> |
return array($state, | return array($state, | ||
} | } | ||
else if(preg_match("/ | else if(preg_match("/ | ||
$func = " | $func = " | ||
- | $params = $m[1]; | + | $params = $this-> |
return array($state, | return array($state, | ||
} | } | ||
else if(preg_match("/ | else if(preg_match("/ | ||
$func = " | $func = " | ||
- | $params = $m[1]; | + | $params = $this-> |
return array($state, | return array($state, | ||
} | } | ||
Line 298: | Line 340: | ||
} | } | ||
} | } | ||
- | | + | |
/** | /** | ||
* Create output | * Create output | ||
*/ | */ | ||
- | + | ||
function render($mode, | function render($mode, | ||
+ | |||
if($mode == ' | if($mode == ' | ||
list($state, | list($state, | ||
- | | + | |
switch ($state) { | switch ($state) { | ||
case DOKU_LEXER_UNMATCHED : | case DOKU_LEXER_UNMATCHED : | ||
Line 324: | Line 366: | ||
} | } | ||
return true; | return true; | ||
- | | + | |
} | } | ||
return false; | return false; | ||
} | } | ||
+ | |||
+ | /** | ||
+ | * Make the attribute string safe to avoid XSS attacks. | ||
+ | * WATCH OUT FOR | ||
+ | * - event handlers (e.g. onclick=" | ||
+ | * - CSS (e.g. background: url(javascript: | ||
+ | * - closing the tag and opening a new one | ||
+ | * WHAT IS DONE | ||
+ | * - turn all whitespace into ' ' (to protect from removal) | ||
+ | * - remove all non-printable characters and < and > | ||
+ | * - parse and filter attributes using a whitelist | ||
+ | * - styles with ' | ||
+ | * (I know this is brutally aggressive and doesn' | ||
+ | * some safe stuff, but better safe than sorry.) | ||
+ | * NOTE: Attribute values MUST be in quotes now. | ||
+ | */ | ||
+ | function _cleanAttrString($attr="" | ||
+ | if (is_null($attr)) return NULL; | ||
+ | # Keep spaces simple | ||
+ | $attr = trim(preg_replace('/ | ||
+ | # Remove non-printable characters and angle brackets | ||
+ | $attr = preg_replace('/ | ||
+ | # This regular expression parses the value of an attribute and | ||
+ | # the quotation marks surrounding it. | ||
+ | # It assumes that all quotes within the value itself must be escaped, | ||
+ | # which is not technically true. | ||
+ | # To keep the parsing simple (no look-ahead), | ||
+ | # quotes. | ||
+ | $val = " | ||
+ | $nattr = preg_match_all("/ | ||
+ | if (!$nattr) return NULL; | ||
+ | |||
+ | $clean_attr = ''; | ||
+ | for ($i = 0; $i < $nattr; ++$i) { | ||
+ | $m = $matches[$i]; | ||
+ | $attrname = strtolower($m[1]); | ||
+ | $attrval | ||
+ | # allow only recognized attributes | ||
+ | if (in_array($attrname, | ||
+ | # make sure that style attributes do not have a url in them | ||
+ | if ($attrname != ' | ||
+ | (stristr($attrval, | ||
+ | | ||
+ | { | ||
+ | $clean_attr .= " $attrname=$attrval"; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return $clean_attr; | ||
+ | } | ||
+ | |||
function _attrString($attr="", | function _attrString($attr="", | ||
if(is_null($attr) || trim($attr)=="" | if(is_null($attr) || trim($attr)=="" | ||
Line 335: | Line 429: | ||
return $attr; | return $attr; | ||
} | } | ||
- | | + | |
var $tagsmap = array(); | var $tagsmap = array(); | ||
- | | + | |
function _starttag($tag, | function _starttag($tag, | ||
$tagstr = $this-> | $tagstr = $this-> | ||
Line 345: | Line 439: | ||
return $r; | return $r; | ||
} | } | ||
- | | + | |
function _endtag($tag, | function _endtag($tag, | ||
$tagstr = $this-> | $tagstr = $this-> | ||
$before = $this-> | $before = $this-> | ||
$after = $this-> | $after = $this-> | ||
+ | |||
$r = $before."</" | $r = $before."</" | ||
return $r; | return $r; | ||
} | } | ||
+ | |||
function table_open($params=NULL){ | function table_open($params=NULL){ | ||
$r .= $this-> | $r .= $this-> | ||
Line 361: | Line 455: | ||
return $r; | return $r; | ||
} | } | ||
+ | |||
function table_close($params=NULL){ | function table_close($params=NULL){ | ||
$t = end($this-> | $t = end($this-> | ||
Line 385: | Line 479: | ||
break; | break; | ||
} | } | ||
- | | + | |
while(($t = end($this-> | while(($t = end($this-> | ||
$r .= $this-> | $r .= $this-> | ||
Line 393: | Line 487: | ||
$r .= $this-> | $r .= $this-> | ||
return $r; | return $r; | ||
- | | + | |
} | } | ||
- | | + | |
function end($params=NULL){ | function end($params=NULL){ | ||
while(!empty($this-> | while(!empty($this-> | ||
Line 402: | Line 496: | ||
return $r; | return $r; | ||
} | } | ||
- | | + | |
function caption($params=NULL){ | function caption($params=NULL){ | ||
if(($r = $this-> | if(($r = $this-> | ||
Line 411: | Line 505: | ||
return $r; | return $r; | ||
} | } | ||
+ | |||
function row($params=NULL){ | function row($params=NULL){ | ||
$r .= $this-> | $r .= $this-> | ||
Line 418: | Line 512: | ||
return $r; | return $r; | ||
} | } | ||
+ | |||
function header($params=NULL){ | function header($params=NULL){ | ||
$r .= $this-> | $r .= $this-> | ||
Line 425: | Line 519: | ||
return $r; | return $r; | ||
} | } | ||
+ | |||
function cell($params=NULL){ | function cell($params=NULL){ | ||
$r .= $this-> | $r .= $this-> | ||
Line 432: | Line 526: | ||
return $r; | return $r; | ||
} | } | ||
- | | + | |
function _closetags($tag){ | function _closetags($tag){ | ||
$r = ""; | $r = ""; | ||
Line 439: | Line 533: | ||
case EXTTAB2_TH: | case EXTTAB2_TH: | ||
$t = end($this-> | $t = end($this-> | ||
- | + | ||
switch($t){ | switch($t){ | ||
case EXTTAB2_TABLE: | case EXTTAB2_TABLE: | ||
Line 462: | Line 556: | ||
case EXTTAB2_TR: | case EXTTAB2_TR: | ||
$t = end($this-> | $t = end($this-> | ||
- | + | ||
switch($t){ | switch($t){ | ||
case EXTTAB2_TABLE: | case EXTTAB2_TABLE: | ||
Line 546: | Line 640: | ||
2010/05/01: Skimming through the code, I'm guessing the vulnerability is that the table can take arbitrary event attributes (e.g. '' | 2010/05/01: Skimming through the code, I'm guessing the vulnerability is that the table can take arbitrary event attributes (e.g. '' | ||
+ | > That is a correct analysis of the vulnerability that was reported [by me, directly to the author] resulting in the security flag being set. The objective of the changes is good, although I haven' | ||
+ | |||
+ | This plugin does not work with 2011-05-25a " | ||
+ | |||
+ | > This plugin does work in Rincewind. You need to ensure you include '' | ||
+ | |||
+ | 2012/02/09: I am having the same trouble in Angua as the previous comment regarding Rincewind. I tried assigning the class=" | ||
+ | but I think most everything on the table first line is ignored. If you contact me I can show you examples. | ||
+ | >UPDATE: It works! | ||
+ | 2014-03-19: The plugin code of exttab2 has moved to [[https:// |
plugin/exttab2.1273755792.txt.gz · Last modified: 2010-05-13 15:03 by 74.108.1.236