Recommendations Against Security Hacks

posted by custom software @ 12:11am, Friday 18 May 2012.

Web Security

Recommendations Against CSRF (aka XSS – cross site scripting)

(cross site request forgery) – an attack whereby a user from an outside source sends a request to a web application that a user has already authenticated itself with, from a different website.

   

Ways to prevent XSS

   

     1. using $_POST not $_REQUEST on inputted fields – this will prevent malicious users from scripting elements that rely on a basic $_GET
    eg:
<img src="http://www.example.com/process.php?amount=33&destination_card_number=1111222233334444" />

    

2. hashed token in session checked on each page
  eg:
  (outgoing PHP Response) – send a unique ID ‘token’ out to the user’s ‘to-be-submitted’ form
 

$token= md5(uniqid());
    $_SESSION[“validationToken”]= $token;
    session_write_close();
echo ‘<input type=”hidden” name=”token” value=”$token”/>’;
 

(Incoming PHP Request) – check the token after it returns – make sure it’s still who we expect it to be

$token= $_SESSION[“validationToken”];
  unset($_SESSION[“validationToken”]);
  session_write_close();
  if ($_POST['token']==$token) {
  // perform the requested action.
  } else {
  // log potential CSRF attack.
  }
 

3. Putting a timeout on the hashed token (I didn’t say token hash).

$token_age = time() - $_SESSION['token_time'];
  if ($token_age <= 300) //300 seconds – an arbitrary time for this example
  {
  /* Less than five minutes has passed. */
}
 

4. Enforcing session timeout and limit it to a minimum.
  How this can affect security:
a) The user leaves workstation and browser cache. Someone else can access. medium risk.

b) The more serious in your case, session hijacking. To hijack a session all one needs is the sessionid. Normally you'd check if the session belongs to the user, but if session identifies the user you can't. Then all that is required to hijack a session, is to guess (easier if never expires) or catch with a network sniffer.

5. Don't waste time with checking $_SERVER['HTTP_REFERER'] since that only stops attacks from a browser
  **everyone’s initial response to “how should we secure the system?”
 
  6. Put into htaccess file directives that disallow SQL injection keywords in the query string (delete/drop/insert etc)
 
  7. Fail open error handling (remove all 'ugly error' messages).  
  Users should NEVER know what error happened, only that an error DID happen. This is where logging comes in for our debug audit on a proper log file. Showing the user that a file at /home/fvreb/public_html/includes/lang/en/eng-ca.php could not be found is not a wise solution for showing hackers the directory structure.
 
  8. Validation – make sure banned terms and invalid characters are not passed into the system.
 
  9. Use striptags() on user input before saving to remove NULL bytes, HTML and PHP tags stripped from a given string input.
 
  10. Using a ‘captcha’ image on submitted forms. Ensures it’s not a script executing.
 
  11. HTML encode user-supplied data that is embedded into a returned page (ie a confirmation before submition). Again this would be preventing things like this from being printed to the page:
<img src="http://www.example.com/process.php?amount=33&destination_card_number=1111222233334444" />

12. Post vs Get in Ajax calls.
GET should be used for what it is intended for: Getting data from the server (not sending), without changing state on the server. It should not be used to update resources on the server. POST or PUT are designed for that. Using HTTP the way it was intended to be used both helps avoid some (but far from all) XSS attacks, it also makes browsers behave a lot nicer when communicating with your site. The browser expects that GET requests can be safely repeated, without requiring confirmation from the user. That's what it does if you refresh the page, for example, or use the back/forward buttons. POST is expected to change state on the server, so the browser typically asks for confirmation before repeating a POST request.

AJAX Issues

  Many issues can be found in AJAX calls since developers often pass queries as GET methods out of habit. Changing the queries to POST and then checking to ensure that they are only posted parameters on the receiving end also helps mitigate SQL and XSS injections.
  Adding the random tokens on all queries will help against XSS – JQUERY has a built in method. Standard AJAX outside of frameworks will need to be manually adjusted.
 
  JQuery Tricks
  To use this token with jQuery, you need to make it available to javascript. You typically do this by adding it as a javascript variable.
  var csrf_token = '<%= token_value %>';//random generated query drawn on serverside

Next, the trick is to bind to the global ajaxSend event, and add the token to any POST request

$("body").bind("ajaxSend", function(elm, xhr, s){ 
if (s.type == "POST") { 
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
  }
 
});

Ways to Track and Trace XSS Attempts

  1. Maintain audit logs and create a banned IP list
  2. Key event should be logged, which typically include:

     
  •    all events relating to the authentication functionality, such as successful and failed login, and change of password
  •  
  •    key transactions, such as credit card payments and funds transfers
  •  
  •    access attempts that are blocked by the access control mechanisms
  •  
  •    any requests containing known attack strings that indicate overtly malicious intentions
  •  
  •    logging used by banks will track every single client request with complete forensic record that can be used to investigate further incidents and allow for fixes based on that information
  •  
  •    log time of each event, IP address, session token, user's account (if authenticated)
     
  •     **these logs need to be strongly protected against unauthorized re/write access. An effective approach is to store audit logs on an autonomous system that accepts only update messages from the main application. In some situations, logs may be flushed to a write once media (CD) to ensure integrity in the event of a successful attack
  • poorly protected audit logs can provide a gold mine of information to an attacker, disclosing a host of sensitive information such as session tokens and request parameters that may enable them to immediatley comprimise the entire application
    

3. installation of alerting mechanisms that monitor traffic and anomalies such as:

   
         
  •        large numbers of requests being received from a single IP address or user, indicating a scripted attack
  •      
  •        business anomalies, such as unusual number of funds transfers to/from a single account
  •      
  • requests containing known attack strings
  •      
  •        requests where data that is hidden from ordinary user has been modified (eg: token changed)
  •      
  •        off the shelf intrusion detection software on server
            It’s important to note that reacting to apparent attacks is not a substitute for fixing vulnerabilities but even the most efforts to purge an application of security flaws may leave some exploitable defects remaining. Placing further obstacles in the way of an attacker is an effective defense-in-depth measure that reduces the likelihood that residual vulnerabilities will be found and exploited.
       

Validation and Sanitization

       

Validation – preventing the process from continuing due to the presence of disallowed characters
          Sanitization – removal of disallowed characters without disrupting the flow of the process
    Things to check for:

       
             
  •            control characters
  •          
  •            non alphanumeric (symbols, etc)
  •          
  •            excessive lengths
  •          
  •            spam
  •          
  •            binary data
  •          
  •            alternate encoded data (ascii, unicode, utf-8, hex, octal)
  •          
  •            sql injection
  •          
  •            code injection                                
  •        

            A basic Sanitization routine could recursively run on an inputted value until it detects no further changes.
            1.  strip any <script> expressions that appear
            2.  truncate input
            3.  remove quotation marks
            4.  url decode input
            5.  if any items deleted/changed then return to step 1. may want to flag on certain rules (eg rule 1)                                     

Brief Recap of XSS Security Holes

       
     
  1. Lack of input validation on user input
  2.  
  3.    Lack of sanitization on received input
  4.  
  5.    Lack of sufficient logging mechanism
  6.  
  7.    Sufficient logging mechanism with unsecure storage (a different server)
  8.  
  9.    Fail-open error handling
  10.  
  11.    Not closing the database connection properly
  12.  
  13.    Lack of confirming who a user is (hashed token)
  14.  
  15.    Htaccess configuration:
        RewriteCond %{QUERY_STRING} [^a-z](sql|declare|char|union|set|cast|convert|delete|drop|exec|insert|meta|script|select|truncate|update)[^a-z] [NC]
        RewriteRule (.*) - [F]

Bootstrapping

  Bootstrapping means that every server request are funneled through a single (or a few) PHP file. This file will be the “bootstrapper” of our application. It will help instantiate objects that are needed by every page in general such as starting a session, connecting to a database, defining constants and default variables, etc.
  Reference from: http://www.serversidemagazine.com/php/bootstrap-php-code/ 

How to Create a Bootstrap File

  Generally it’s a good practice to setup a bootstrap file for every PHP website or web application. This way a developer could easily manage the behavior of his application in a centralized manner.
  This file is generally the main entry point on each HTTP request, usually the index.php file in the document root.
  It is important to mention that this file usually doesn’t contain any HTML markup, just pure PHP that will load the template files if necessary or a front controller as how most of the MVC frameworks implement it.
 

What to Bootstrap

 

It is a good plan to create a mockup of functionalities that we wish to assign and implement in our file.
  Usually a bootstrap file contains the necessary source code, libraries and logic to start the entire application. From showing figuring out what page to show, how to communicate with the database, etc.
Generally the file should contain the following initializations:

 
       
  •      Configuration
  •    
  •      Session, cookies
  •    
  •      Caching
  •    
  •      Database
  •    
  •      Directory and file paths
  •    
  •      Global variables and constants
  •    
  •      Web application status
  •    
  •      Web page routing
  •    
  •      Feeds
  •    
  •      XML/RPC
  •    
  •      Filtering of submitted values *
  •    
  •      Validation *
  •    
  •       Security checks *     

                                                           
  •  
 

Setting Up
  A bootstrap file usually starts by including those libraries that are necessary for the file itself to function correctly. This involves setting general directory and file paths, loading configuration files, etc.
 
 

  //let's set up a root path constant
  define('ROOT',getcwd().DIRECTORY_SEPARATOR);
   
  //define the includes and config folders
  define('INCLUDES',ROOT.'includes'.DIRECTORY_SEPARATOR);
  define('CONFIG',ROOT.'config'.DIRECTORY_SEPARATOR);
   
  //load in the main configuration file
  include_once(CONFIG.'base.inc.php');
 


    After the basic configuration we can write additional logic into the file, e.g. loading the session object, database object, etc. It’s worth mentioning that every item from the list above should be an object/class, if we are using OOP, that manages that particular feature.
  It’s also encouraged that even for a basic web project we set up different application statuses such as Development,Production or Testing and to load different libraries, logic for every status.
  E.g. In production is a good practice to disable error display:
 

 
  //define our status constant
  define('STATUS','production');
   
  //check what status we have
  switch (STATUS) {
 
case 'production': { 
ini_set('display_errors','Off');
    //and other specific includes, commands, etc.
  } 
}

Lastly we would set the page routing logic. A class that parses the HTTP request and renders the page by loading the necessary template files if any.
    After we set up the bootstrap file, we have to direct all request to this file. This is usually achieved with the help of a few rewrite rules in a .htaccess file in our root directory (or that directory where the index.php file is stored).

<IfModule mod_rewrite.c>
  RewriteEngine On
   
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
   
  # Rewrite all other URLs to index.php/URL
  RewriteRule ^(.*)$ index.php/$1 [PT,L]
   
</IfModule>
<IfModule !mod_rewrite.c>
  ErrorDocument 404 /index.php
</IfModule>

   

 

PreProcessing

  Preprocessing is telling the system to process other directives before handling the requested page.
  This would be a good solution for systems that cannot utilize bootstrap methods as provided by organized frameworks
  AUTO_PREPEND_FILE

 
       
  •   Found in php.ini file on server
  •    
  •     Treats it like in ‘include file’ function.
  •    
  •     To disable it, leave it blank
  •    
  •     Global across all files being parsed by server
  •    
  •     Php.ini
  •    
  •     auto_prepend_file = /server/path/filename.php
  •    
  •     .htaccess
  •    
  •     php_value auto_prepend_file /server/path/filename.php
  •  

Recommended reading:
  https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
  OWASP is the Open Source Web Application Security Project
  http://ha.ckers.org/xss.html cheat sheet of hacking methods to test for vulnerabilities
  http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/
  java based filter, but still a great recommendation – could be configured in an htaccess rule as well.
  http://erlend.oftedal.no/blog/?blogid=118 session based tokens in jquery

Recommendations Against SQL Injection

SQL injection is an often used technique to attack databases through a website. This is done by including portions of SQL statements in a web form entry field in an attempt to get the website to pass a newly formed rogue SQL command to the database (e.g. dump the database contents to the attacker).
  Often a good read of the apache logs will display multiple requests issued to test the vulnerable parameters such as “userID”, which involved injecting the string
  “999'+union+select+Table_name,Column_name+from+Information_schema.Columns+where+table_name='members'+;#” into the parameter’s value:

Limit table access on a connection object.
  Specify explicitly which tables a connection can access. There’s no reason for a user connection to have admin privileges across the database.

Validation and Sanitization

  All items should be properly validated before submitting. Many  systems ‘sanitizes’ (removes unwanted characters), which is a great start, but look at it this way:
  The system needs to make apple sauce. The first step is to remove anything not wanted in the sauce (the apple peel). So we write a sanitization method ‘removePeel()’ and then pass it on to the ‘makeSauce()’ routine. But what if we didn’t have an apple in the first place? What if the user passed us an orange? We sanitized the object (removePeel() – the unwanted characters) but at the very end we added an orange to the mix.
 
An example would be placing an email in the name field. We might remove all unwanted characters (@, ‘.’) but the the person’s name is now:
davemeikleymailcom
which is basically the email address sanitized for a person’s full name.
  Sanitizing will remove unwanted characters but allow the system to continue forward not checking to see if there are any other security rules being broken, while validation will discontinue until all invalid inputs and characters have been removed.
 

Casting / Type Handling

  Strongly typed variables is a terrific yet simple trick in mitigating SQL Injections. By forcing a passed parameter to be cast as the proper data type it is meant to be, this can help to throw an error (stopping the execution) or discarding the crunchy bits (the SQL injection code) attached. This is an advantage other languages (such as Java or C) have over basic scripted languages such as PHP that do not enforce strong data types.
  Eg:
 
  $age = $_POST[“age”];
  //where $age=17 from the request object
  Vs.
  $age = $_POST[“age”];
  //where $age=17'+union+select+Table_name,Column_name+
  from+Information_schema.Columns+where+table_name='members'+;#”;
  By casting $age as an integer, the system will either set $age to 17 and ignore the rest, or simply throw an error – depending on the language used.
  Parameterized Queries / Stored Procedures
  Parameterized Queries seriously mitigate the chances of malicious code getting into your SQL. PHP has a new class called PDO (Prepared Data Object) which offers a comfortable level of abstraction away from the database.
  ($conn is a PDO object)
 
$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
  $stmt->bindValue(':id', $id);
  $stmt->bindValue(':name', $name);
$stmt->execute();

Stored Procedures are similar to parameterized queries, except they cast their received arguments, forcing them to be clean. Write them once, they’re out of the way and cached in database server memory which actually helps speed up queries.

SPRINTF()
  sprintf() can be used with conversion specifications to ensure that the dynamic argument is treated the way it's supposed to be treated (auto-casting).
  $id = $_GET['id'];
$query = sprintf("SELECT username FROM users WHERE id = '%d' ", $id);

HTMLEntities()
  htmlentities() in conjunction with the optional second quote_style parameter, allows the use of ENT_QUOTES, which will convert both double and single quotes. This will work in the same sense as addslashes() and mysql_real_escape_string() in regards to quotation marks, however, instead of prepending a backslash, it will use the HTML entity of the quotation mark.
  In addition to using ENT_QUOTES within htmlentities(), a third parameter can be set which forces the use of a character set within conversion. This will help stop unpredicted results from using multibyte characters in character sets such as BIG5 and GPK.
  The following is an example of code which would help to prevent SQL injection in PHP.

$id = $_GET['id'];
  $id = htmlentities( $id, ENT_QUOTES, 'UTF-8' );
   
  $query = 'SELECT username FROM users WHERE id = "' . $id . '"';
 

HTACCESS Rules

 

RewriteCond %{QUERY_STRING} [^a-z](sql|declare|char|union|set|cast|convert|delete|
    drop|exec|insert|meta|script|select|truncate|update)[^a-z] [NC]
RewriteRule (.*) - [F]
  Deny any information passed in a URI string (query based) that has database characters. The only downside is sometimes you want to pass the term “action=delete” on a clicked link – this would now be banned by the htaccess rules, so a modification would need to be performed on code to change ‘delete’ to ‘del’ or ‘remove’ or ‘castigate’...

comments (0)

C#'s Version of AJAX Not Really Impressive For the Hand Coder

posted by custom software @ 2:15am, Monday 6 February 2012.

C# has had their own version of AJAX for quite a few years now.  Works real well too - as long as you're developing your web apps as a drag n drop programmer using the tools provided by Microsoft's Dot Net architecture. Forces you to play inside their sandbox and use their controls although there are still methods of writing in the back end that don't necessarily call on the Microsoft page controls - not everyone wants to use the Dot Net TextBox for example.

The idea of Ajax is to retrieve information from the server without needing to redraw the whole page. So why is it that the MS AJAX raise a complete page load event when you click on a basic AJAX item on the page? Isn't the whole point to simply "get what I need and insert that new value in the page" ?  Why does it need to go through the complete page load/page draw event sequence? That's not AJAX, that's an MS workaround to behave like AJAX in the browser, but the server still treats it like a whole new page request. Disappointing on some of the more complex pages.

comments (0)

How to Display Errors in PHP

posted by custom software @ 5:47am, Saturday 4 February 2012.

OK, so here's a chunk of code I always simply google whenever I'm debugging PHP if I don't feel like locating a file that has it commented out. I tend to remove the debug attributes simply to keep my pages nice and clean.

For those of you looking for it, the easiest way is:
ini_set('display_errors', 1); 
error_reporting(E_ALL);

Simply put that at the top of the page and let it rip. You'll be able to see a nice...uh... well... you'll hopefully be a step closer to deciphering what's going on...

Another more elegant approach is to use a verbose log it so you can go through it later. That can be achieved like this:
ini_set('display_errors', 1); 
ini_set('log_errors', 1); 
ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); 
error_reporting(E_ALL);

comments (0)

Log In