Buscar este blog

domingo, 23 de octubre de 2016

Jenkins - SonarQube - Exclude sources from code analysis

If you need to exclude some folders from SONAR code analysis, for example, style sheets or javascript files, there are two options:
  • Set exclusions in the POM.XML file.
  • Set exclusions in the SONAR Runner plugin, in Jenkins.
In both cases, the key properties are (check http://docs.sonarqube.org/display/SONAR/Narrowing+the+Focus):
Use exclusion to analyze everything but the specified files:
  • sonar.exclusions - to exclude source code files
  • sonar.test.exclusions - to exclude unit test files
Use inclusion to analyzes only the specified files:
  • sonar.inclusions 
  • sonar.test.inclusions


For example, in POM.XML:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 (...)
 
 <properties>
  (...)  
        <sonar.exclusions>**/*.css,**/*.js</sonar.exclusions>      
 </properties>
 
</project>


In Jenkins, you can configure the SONAR plugin inside each job. In the Post-build Action you can set this configuration in the "Aditional properties" fields with "-D" prefix.


When the job runs, in the output console you will see something like this:
[INFO] [15:20:44.174] Source paths: src/main/webapp, pom.xml, src/main/java
[INFO] [15:20:44.175] Test paths: src/test/java
[INFO] [15:20:44.175] Binary dirs: target/classes
[INFO] [15:20:44.176] Source encoding: UTF-8, default locale: en_US
[INFO] [15:20:44.176] Index files
[INFO] [15:20:44.194] Excluded sources: 
[INFO] [15:20:44.194]   **/*.css
[INFO] [15:20:44.194]   **/*.js
[INFO] [15:20:47.235] 366 files indexed

domingo, 16 de octubre de 2016

Apache security headers - Iframe load issues

When you have a web site which use resources from another domain you will get involved in some security issues.

In this example Site A loads an iframe from site B. The same applies to other resources.

Site A: https://siteA.com/iframeParent.html
<html>
<head>
 <meta charset="UTF-8">
</head> 


<body>
 <h1>This is a iframe loaded from other site</h1>
 <iframe src="https://siteB.com/iframe.html">
 </iframe>

</body>

</html>

Site B: https://siteB.com/iframe.html
<html>
<head>
 <meta charset="UTF-8">
</head> 

<body>
 <h2>I am a iframe</h2>
</body>
</html>


There are two security headers to use here:
In Apache Web Server you need to load mod_headers.so module.


If SiteB sets SAMEORIGIN, then siteA will not be able to load the iframe.
    Header always append X-Frame-Options SAMEORIGIN

If siteB sets ALLOW-FROM siteA, then only siteA will be able to load the iframe.
    Header always append X-Frame-Options ALLOW-FROM https://siteA.com

If siteB sets security policy to frame-ancestors siteA, then only siteA will be able to load the iframe.
    Header always append Content-Security-Policy "frame-ancestors siteA.com"


If siteA sets security policy to default-src 'none', then siteA will not be able to load any external resource.
    Header always append Content-Security-Policy "default-src 'none'"

If siteA sets security policy to default siteB, then siteA will only be able to load external resources from siteB
    Header always append Content-Security-Policy "default-src 'self' siteB.com"


Note: Browser support:

sábado, 27 de agosto de 2016

Java applets security considerations

First of all, What are you doing here? Applets are absolutely deprecated and they will disappear definitely with Java 9.
Having said that, I´m currently working with some applets and java web start components, and very often we found with security issues and warnings coming  from de Java configuration.

The common errors I usually get are:
Your security settings have blocked an application from running due to missing a 'Permissions' manifest attribute in the main jar
Your security settings have blocked an untrusted application from running
The first one is easy to solve. Just add de permissions attribute in the manifest, usually with value "all-permissions".


For the second one you need to sign de applet (jarsigner) and to do one of the following things:
a) Add your site to the trusted sites of Java.
Go to Configure Java > Security > Edit list of sites. Add the one hosting your applet, for example http://localhost:8080.

b) Add the CA of the signer certificate to the trusted Authorities of Java.
Go to Configure Java > Security > Manage Certificates > CA of Signer.


I created two simple java project to play with these problems:

  • simple-applet. This is the applet project. In the pom.xml file you can see the plugins to insert de manifest entries and the signer.
  • simpe-boot-applet. This is the web app which uses the applet. You need to open http://localhost:8080/applet

Windows Server - Spring Security Kerberos authentication example

This post is a step by step guide to configure a Kerberos service which is accesible for human users (by using a web browser) and for other java applications (by using a HTTP client).
This post is almost entirely based in the Spring Security Kerberos reference documentation. I just have taken the parts I needed to develop a funcionality in one of my applications.

The overview of the solution is as follows:
  • There is a Windows Server 2008 R2 machine called WIN-GG8QUO4LVI8.test.com.
  • In this server the Active Directory and KDC (Key Distribution Center) are running.
  • The AD has three users: tomcat, user1 and humanUser1.
  • The root domain (and forest, as there is just one domain) is TEST.COM.
  • There is a second machine outside the domain. A Windows 7 machine.
  • In this PC, the sec-server-spnego-form-auth application is deployed.
  • This service will be called neo.example.org.
  • In this PC, the rest client sc-client-rest-template will also be "deployed".


The objectives are:
  • When humanUser is logged in WIN-GG8QUO4LVI8.test.com, he can access the tomcat app without introducing his username neither password. His identity is loaded from the windows session.
  • When humanUser is logged in the other PC, he can access the tomcat app by introducing his username and password.
  • The rest client can access the tomcat app by identifying itself with a username (user1) and his keytab file.


This image summarize this infrastructure:


So, I have my Active Directory configured with de domain "test.com" in a computer named "WIN-GG8QUO4LVI8", ie, my Domain Controller.


Based on this information, I can create a kerberos conf file (or .ini). The content of krb5.conf file is:
[libdefaults]
 default_realm = TEST.COM
 default_tkt_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
 default_tgs_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
 permitted_enctypes   = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc

[realms]
 TEST.COM  = {
  kdc = WIN-GG8QUO4LVI8.test.com
  default_domain = TEST.COM
 }

[domain_realm]
 .TEST.COM = TEST.COM

In the Active Directory I have the three necessary users. For example:



The steps  I'll follow to complete the deployments are as follow:
  1. Configure and install sec-server-spnego-form-auth
  2. Test the tomcat app from the Other PC with humanUser1
  3. Test the tomcat app from WIN-GG8QUO4LVI8 with humanUser1
  4. Configure and install sec-client-rest-template

1. Configure and install sec-server-spnego-form-auth

Configuration in WIN-GG8QUO4LVI8
First we need to setup a Service Principal Name (SPN) for the sec-server-spnego-form-auth.
A service is any process that do something, in this case, the tomcat app. Services are identified uniquely in the form of "<service class>/<host>:<port>[/<service name>]", and are they asociated with a login account name.

Our SPN will be "HTTP/neo.example.org" and the user associated will be "tomcat".
> setspn -A HTTP/neo.example.org tomcat

> setspn -L tomcat
Registered ServicePrincipalNames for CN=tomcat tomcat.,CN=Users,DC=test,DC=com:
        HTTP/neo.example.org

Now we need to generate a keytab file for this service and map the SPN created previously. Basically, we are saying that this keytab file belongs to this SPN, which is also asociated with a user.
You need to use the ktpass command:
> ktpass -out ./tomcat.keytab -mapuser tomcat@TEST.COM -princ HTTP/neo.example.org@TEST.COM -pass Password# -ptype KRB5_NT_PRINCIPAL -crypto ALL


> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\klist.exe" -k -t -k tomcat.keytab

Key tab: tomcat.keytab, 5 entries found.

[1] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[2] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[3] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[4] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[5] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00

The java klist command allows to list the entries in the keytab file. A keytab file contains pairs of kerberos principals an encrypted keys. In this case, the principal is the service.

Configuration in the Other PC
Once we have all the kerberos configuration done, we can start to prepare our tomcat application sec-server-spnego-form-auth.
This spring boot application has a configuration file, application.yml, with two importan keys:
  • service-principal. The name of the service that this application is providing.
  • keytab-localtion. The path to the keytab file which contains the keys wich authenticate this application in the KDC.

With de information above, the application.yml file would be:
server:
    port: 8080
app:
    service-principal: HTTP/neo.example.org@TEST.COM
    keytab-location: D:/kerberos/tomcat.keytab

Remember that we also have the krb5.conf with de global configuration. We can tell our app to use it with the argument -Djava.security.krb5.conf=/path/to/krb5.conf.

In order to start this application you have to execute the following command:
java -Djava.security.krb5.conf=D:/kerberos/krb5.conf -jar sec-server-spnego-form-auth-1.0.2.BUILD-SNAPSHOT.jar

Ok. Our tomcat app is up and running.

2. Test the tomcat app from the Other PC with humanUser1

In the Other PC, I had the following IPs in my hosts file:
127.0.0.1   neo.example.org

192.168.65.129 WIN-GG8QUO4LVI8
192.168.65.129 WIN-GG8QUO4LVI8.test.com

When a user tries to access to http://neo.example.org:8080/hello, he will get the auth form. This is because this user is outside the domain.


3. Test the tomcat app from WIN-GG8QUO4LVI8 with humanUser1

Now, humanUser1 logs in WIN-GG8QUO4LVI8, which is a PC inside the domain (well, it is the server domain...).
When this user tries to access to http://neo.example.org:8080/hello, he will enter automatically.

I will use firefox, so you need to configure the following:
  • Open Firefox.
  • At address field, type about:config.
  • In filter/search, type negotiate.
  • Set parameter network.negotiate-auth.trusted-uris to http://neo.example.org:8080 (if you already have other URL, you need to separate them by using ",").

I also added this URL to my local intranet sites in the Internet Explorer configuration.

4. Configure and install sec-client-rest-template

Fine. The human users have access to the web application. If the user is loged in inside the domain, he doesn´t need to autenticate again (Single Sign On), but if the user try to access from outside, he needs to use his login and password.

Now I want to authenticate a java application which will make a http connection (a GET request) to the secure page in the sec-server-spnego-form-auth application.

Configuration in WIN-GG8QUO4LVI8
You need to create a second keytab file. In this case, this file will contain the keys for user1, which will be the user used by the sec-client-rest-template.
Previously we created a keytabfile for the tomcat user, which is the acconut name asociated with the service, by using the ktpass command. Now we just need to create the ketabfile for a external user, without to associate this user with any service.

We use the ktab tool, shipped with Java.
> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\ktab.exe" -a user1 Password# -k user1.keytab

> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\klist.exe" -k -t -K user1.keytab

Key tab: user1.keytab, 3 entries found.

[1] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x97bb5f77eb114814e2c1e639ec914429
         Time stamp: Aug 26,  2016 16:09:43
[2] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x4f5ea81531e5136807d9fe9d75d0f2e6cbd9b6eacd546d7f
         Time stamp: Aug 26,  2016 16:09:43
[3] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x63245e61ad75fbc0b9360b4e380d83d8
         Time stamp: Aug 26,  2016 16:09:43

Configuration in the Other PC
Once we have keytab file we can start to prepare our tomcat application sec-client-rest-template.
This spring boot application has a configuration file, application.yml, with two important keys:
  • user-principal. The user that this application will use to authenticate itself.
  • keytab-localtion. The path to the keytab file wich contains the keys wich authenticate this application in the KDC.
  • access-url: The URL of our service.

With the information above, the application.yml file would be:
app:
    user-principal: user1@TEST.COM
    keytab-location: D:/kerberos/user1.keytab
    access-url: http://neo.example.org:8080/hello


Remember that we also have the krb5.conf with de global configuration. We can tell our app to use it with de argument -Djava.security.krb5.conf=/path/to/krb5.conf.

In order to start this application you have to execute the following command:
java -Djava.security.krb5.conf=D:/kerberos/krb5.conf -jar sec-client-rest-template-1.0.2.BUILD-SNAPSHOT.jar