DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:security

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
devel:security [2015-11-07 16:19] – [Security Guidelines for Plugin Authors] 50.141.100.133devel:security [2023-08-14 13:41] (current) Klap-in
Line 6: Line 6:
  
 ===Summary=== ===Summary===
 +
 A list of the most common security issues and how to avoid them can be found on this page. A short summary: A list of the most common security issues and how to avoid them can be found on this page. A short summary:
   * Cross Site Scripting (XSS) -- inserts malicious code into website to manipulate site in browser of user   * Cross Site Scripting (XSS) -- inserts malicious code into website to manipulate site in browser of user
-  * Cross Site Request Forgery (CSRF) -- tricks to let you self do unknowingly harmful actions on your site +  * Cross Site Request Forgery (CSRF) -- tricks to let you do unknowingly harmful actions on your site 
   * Remote Code Inclusion -- includes code on server that's executed there   * Remote Code Inclusion -- includes code on server that's executed there
-  * Information leaks -- there is too much information showed+  * Information leaks -- there is too much information shown
   * SQL injection -- one can do unwanted requests on your data   * SQL injection -- one can do unwanted requests on your data
  
Line 25: Line 26:
  
 ===Escaping output=== ===Escaping output===
-At an absolute minimum the plugin should ensure any raw data output has all HTML special characters converted to HTML entities using the [[phpfn>htmlspecialchars]] function. DokuWiki provides a convenient shortcut called [[xref>hsc()]] for the function. URLs values should be escaped using [[phpfn>rawurlencode]].+At an absolute minimum the plugin should ensure any raw data output has all HTML special characters converted to HTML entities using the [[phpfn>htmlspecialchars()]] function. DokuWiki provides a convenient shortcut called [[xref>hsc()]] for the function. URLs values should be escaped using [[phpfn>rawurlencode()]].
  
 Also any wiki data extracted and used internally (eg. user names) should be treated with suspicion. Also any wiki data extracted and used internally (eg. user names) should be treated with suspicion.
Line 31: Line 32:
 ===Input checking=== ===Input checking===
 Check always all your input. Use whitelists, filters, conversions to the exact data type you mean e.g. from a number inputted as mixed php value to integer and more to ensure you have __only__ data you allowed. Check always all your input. Use whitelists, filters, conversions to the exact data type you mean e.g. from a number inputted as mixed php value to integer and more to ensure you have __only__ data you allowed.
 +
 +Please also refer to our chapter on processing [[request vars]] like ''_GET'', ''_POST'' or ''_SERVER''.
 +
  
 ==See also:== ==See also:==
Line 51: Line 55:
     // common plugin functions ommited     // common plugin functions ommited
  
-    function connectTo($mode) { +    public function connectTo($mode) { 
-        $this->Lexer->addSpecialPattern('!!!.*?!!!',$mode,'plugin_bold');+        $this->Lexer->addSpecialPattern('!!!.*?!!!', $mode, 'plugin_bold');
     }     }
  
-    function handle($match, $state, $pos, &$handler){ +    public function handle($match, $state, $pos, Doku_Handler $handler){ 
-        return array(substring($match,3,-3));+        return [substring($match, 3, -3)];
     }     }
  
-    function render($mode&$R, $data) { +    public function render($formatDoku_Renderer $renderer, $data) { 
-        if($mode != 'xhtml') return false; +        if($format != 'xhtml') return false; 
-        $R->doc .= '<b>'.$data[0].'</b>';  //no escaping+        $renderer->doc .= '<b>' . $data[0] . '</b>';  // no escaping
     }     }
 } }
Line 74: Line 78:
     // common plugin functions ommited     // common plugin functions ommited
  
-    function connectTo($mode) { +    public function connectTo($mode) { 
-        $this->Lexer->addSpecialPattern('!!!.*?!!!',$mode,'plugin_bold');+        $this->Lexer->addSpecialPattern('!!!.*?!!!', $mode, 'plugin_bold');
     }     }
  
-    function handle($match, $state, $pos, &$handler){ +    public function handle($match, $state, $pos, Doku_Handler $handler){ 
-        return array(substring($match,3,-3));+        return [substring($match, 3, -3)];
     }     }
  
-    function render($mode&$R, $data) { +    public function render($formatDoku_Renderer $renderer, $data) { 
-        if($mode != 'xhtml') return false; +        if($format != 'xhtml') return false; 
-        $R->doc .= '<b>'.htmlspecialchars($data[0]).'</b>'; //escaping+        $renderer->doc .= '<b>' . htmlspecialchars($data[0]) . '</b>'; //escaping
     }     }
 } }
Line 112: Line 116:
 </form> </form>
 </code> </code>
 +
 +In general it is recommended to not hand-craft forms, but use DokuWiki's [[form|form library]].
  
 === Classes and other Attributes === === Classes and other Attributes ===
Line 126: Line 132:
  
 <code php> <code php>
-$renderer->doc .= '<div class="msg_'.$class.'">'  //$class can be everything +$renderer->doc .= '<div class="msg_' . $class . '">'  //$class can be everything 
-                       .htmlspecialchars($message) +                       . htmlspecialchars($message) 
-                 .'</div>';+                . '</div>';
                                                                    
 </code> </code>
Line 135: Line 141:
  
 <code php> <code php>
-$allowed = array('notice','info','warning','error');   //whitelist +$allowed = ['notice', 'info', 'warning', 'error'];   // whitelist 
-if(!in_array($class,$allowed){                          +if(!in_array($class, $allowed){                          
-    $class = 'notice'; //unknown input, fall back to a sane default+    $class = 'notice'; // unknown input, fall back to a sane default
 } }
-$renderer->doc .= '<div class="msg_'.$class.'">' +$renderer->doc .= '<div class="msg_' . $class . '">' 
-                       .htmlspecialchars($message) +                       . htmlspecialchars($message) 
-                 .'</div>';+                . '</div>';
 </code> </code>
  
Line 152: Line 158:
 <code php> <code php>
 // empty URL on protocol mismatch // empty URL on protocol mismatch
-if(!preg_match('/^https?:\/\//i',$url)) $url = ''; +if(!preg_match('/^https?:\/\//i', $url)) 
 +    $url = ''; 
 +}
 </code> </code>
  
Line 159: Line 167:
 This vulnerability often appears into plugins due to the lack of understanding of this issue, often confused with the XSS. This vulnerability often appears into plugins due to the lack of understanding of this issue, often confused with the XSS.
  
-Cross Site Request Forgery refers to an attack where the victim's browser is tricked by a malicious site to ask for a page on a vulnerable site to do an unwanted action. The attack assumes the victim's browser have credentials to change something on the vulnerable site.+Cross Site Request Forgery refers to an attack where the victim's browser is tricked by a malicious site to ask for a page on a vulnerable site to do an unwanted action. The attack assumes the victim's browser has credentials to change something on the vulnerable site.
  
 ===Adding security token=== ===Adding security token===
-DokuWiki offers functions to help you deal against CSRF attacks: [[xref>getSecurityToken()]] and [[xref>checkSecurityToken()]]. Note that in the last versions of DokuWiki, you can use [[xref>formSecurityToken()]] instead of [[xref>getSecurityToken()]]. The latter will only give you the token value, but the other one will print or return a <div> with an hidden input of name "sectok" and value the security token. 
  
 +DokuWiki offers functions to help you deal against CSRF attacks. [[xref>getSecurityToken()]] will create a token that should be used to protect any authenticated action. It has to be included in links or forms triggering that action. All forms created with the [[form|form library]] will have security tokens added automatically, for handcrafted forms the [[xref>formSecurityToken()]] function can be used.
 +
 +
 +It is your resposibility as the plugin author to actually check the token before executing authorized actions using the [[xref>checkSecurityToken()]] function.
  
 ==See also== ==See also==
Line 184: Line 195:
 </code> </code>
  
-Then you process this form has follow:+Then you process this form as follows:
  
 <code php> <code php>
-if(isset($_GET['yn'])){ +global $INPUT; 
-    do_something_with_yn($_GET['yn']);+ 
 +if($INPUT->get->has('yn')){ 
 +    do_something_with_yn($INPUT->get->str('yn'));
 } }
 </code> </code>
Line 199: Line 212:
 </code> </code>
  
-What the user's browser will do then?+What will the user's browser do then?
  
-The browser will process this image as any other and will send a request to this URL. Your plugin will then see that $_GET['yn'] is set and will call the do_something_with_yn() function.+The browser will process this image as any other and will send a request to this URL. Your plugin will then see that ''$_GET['yn']'' is set and will call the ''do_something_with_yn()'' function.
  
 That's one of the examples of CSRF. Now, how to fix this security hole? That's one of the examples of CSRF. Now, how to fix this security hole?
Line 218: Line 231:
 </code> </code>
  
-Do you see the first input? Yes? Good. Now you have to check the security token when you recieve the form, before processing it:+Do you see the first input? Yes? Good. Now you have to check the security token when you receive the form, before processing it:
  
 <code php> <code php>
-if(isset($_GET['yn']) && checkSecurityToken()) { +global $INPUT; 
-    do_something_with_yn($_GET['yn']);+ 
 +if($INPUT->get->has('yn') && checkSecurityToken()) { 
 +    do_something_with_yn($INPUT->get->str('yn'));
 } }
 </code> </code>
Line 228: Line 243:
 As the malicious website will never find the value of the "sectok" hidden input, your form is no longer vulnerable to CSRF. As the malicious website will never find the value of the "sectok" hidden input, your form is no longer vulnerable to CSRF.
  
-**Note:** If the security token is not valid, the checkSecurityToken() function displays a message which inform the user.+**Note:** If the security token is not valid, the ''checkSecurityToken()'' function displays a message which informs the user.
  
  
Line 234: Line 249:
 ===== Remote Code Inclusion ===== ===== Remote Code Inclusion =====
  
-This attack allows an attacker to inject (PHP) code into your application. This may occur on including files, or using unsafe operations functions like [[phpfn>eval]] or [[phpfn>system]].+This attack allows an attacker to inject (PHP) code into your application. This may occur on including files, or using unsafe operations functions like [[phpfn>eval()]] or [[phpfn>system()]].
  
 **Always filter any input** that will be used to load files or that is passed as an argument to external commands. **Always filter any input** that will be used to load files or that is passed as an argument to external commands.
devel/security.1446909580.txt.gz · Last modified: 2015-11-07 16:19 by 50.141.100.133

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki