アーカイブ

‘java’ カテゴリーのアーカイブ

java の AntiSamyでサニタイズ、任意のHTMLタグを許可しscriptタグとかを無効化

2010 年 8 月 24 日 tdtsh コメントはありません

一般公開するWEBサービスを作る場合、慣れてないと手がかかるのがセキュリティへの配慮です。

Google App Engineとか使っている時点でSQLインジェクションとかディレクトリ・トラバーサルとかOSコマンド・インジェクションとか関係ありませんが、セッションハイジャックとかアプリケーションの作りに依存する部分は他のフレームワークと同じです。

気をつけたいのがXSS(クロスサイト・スクリプティング)です。

HTMLタグ不許可な場合は簡単なんですが、昨今のWEBサービスではブログをはじめフォームにHTMLタグを入力できる様なサービスが増えてきたので大変です。

良い子のウェブプログラマはIPAのガイドライン、安全なウェブサイトの作り方 (PDFファイル、2.09MB) を参考にします。

同ガイドラインでは根本解決策を「入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する」としています。
そんなもん自力で書いてられません。

そこで、OWASP(Open Web Application Security Project)謹製のAntiSamyを使いたいと思います。

 

 


ダウンロード

Google Codeから antisamy-bin.1.4.1.jar をダウンロードします。

設定はポリシーファイルで行います。テンプレが用意されていますのでダウンロードします。
ここを参考に、antisamy-ebay.xml をダウンロードしました。

 

 


インストール

基本的にjarファイルをクラスパスに置くだけ、の筈ですが、私の環境ではそれだけでは動きませんでした。(slim3 1.0.5、Eclipse 3.5、google app engine for java 1.3.6)
いろんなクラスが見つからないと怒られます。

先ほどのGoogle CodeでAll downloadsをSearch すると、antisamy-required-libs-1.2.zip が出てきます。こいつをダウンロードして解党し、依存性があるであろうjar達をクラスパスに置いたら動きました。

 

 


使い方

またもやここを参考にしてください。

一応書いときます。

import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;
import org.owasp.validator.html.PolicyException;
import org.owasp.validator.html.ScanException;
...
	public static final String PATH_ANTISAMY_POLICY = "WEB-INF/antisamy-ebay-1.4.1.xml";
...
	public static String doSamy(String str)
		throws PolicyException, ScanException
	{
		Policy policy = Policy.getInstance(PATH_ANTISAMY_POLICY);
		AntiSamy as = new AntiSamy();
		CleanResults cr = as.scan(str, policy);
		return cr.getCleanHTML();
	}
...

 

 


Youtubeを動かしたい

Youtubeのタグが弾かれる事に気がつきました。

一番なんでもアリのポリシーファイル(antisamy-anythinggoes-1.4.1.xml)に変えてもダメです。

色々ググっているウチに、先人の知恵を発見。
AntiSamy Policy to allow YouTube Videos

無事Youtubeも動くようになりました。

FireFoxのプラグインXSS MEでテストしてみましたが、機嫌よくサニタイズしている様に見えます。

満足です。

 

 


カテゴリー: Google App Engine, java, slim3 タグ:

OpenID RP を Google App Engine (java) で (dyuproject)

2010 年 3 月 18 日 tdtsh Comments off

 
前回も書きましたが、GAE/J上ではSocketが使えない。故にopenid4javaはGAEでは使えない。

でも、dyuprojectは動くし、動かした上にコードを公開されている方もいる。

どうやらGAE/Jの URLフェッチ API を使っている模様。そりゃそれしか方法はないですよね。

私は職業プログラマでは無いので、車輪の再開発どころか、なるべくコードは書きたくないんです。
早速、dyprojectにトライしてみましょう。
 
 


dyuproject-openid-1.1.6-jarjar.jar のダウンロード

dyuprojectDownloadsから、dyuproject-1.1.6.zipをダウンロードします。

JavaDocとか他のライブラリとかデモが不要なら、dyuproject-openid-1.1.6-jarjar.jar でもいいです。
 
 


eclipseのGAEプロジェクトへライブラリを追加する

ダウンロードしたzipファイルの、/dist に、dyuproject-openid-1.1.6-jarjar.jar はあります。
それを、eclipse の /war/WEB-INF/lib/にコピーします。

eclipseを起動して、war/WEB-INF/lib/ の下にコピーしたjarファイルを右クリックして、[ビルド・バス(B)] – [ビルド・パスに追加(A)]をクリックします。

念のため、プロジェクトの[参照ライブラリー]に追加されている事を確認します。
 
 


/WEB-INF/web.xml に追記する

QuickStartOpenid – dyuprojectのんを参考にしながら書きます。
ちょっとだけ手を加え (ログアウト用サーブレットを追加とか) ましたが、基本的に同じです。

<filter>
    <filter-name>openid-filter</filter-name>
    <filter-class>com.dyuproject.openid.OpenIdServletFilter</filter-class>
    <init-param>
        <param-name>forwardUri</param-name>
        <param-value>/</param-value>
    </init-param>
</filter> 

<filter-mapping>
    <filter-name>openid-filter</filter-name>
    <url-pattern>/openid-login</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>openid-filter</filter-name>
    <url-pattern>/openid-logout</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>openid-servlet</servlet-name>
    <servlet-class>my.package.OpenIdLoginServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>openid-servlet</servlet-name>
    <url-pattern>/openid-login</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>openid-logout</servlet-name>
    <servlet-class>my.package.OpenIdLogoutServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>openid-logout</servlet-name>
    <url-pattern>/openid-logout</url-pattern>
</servlet-mapping>

ログイン用サーブレットを作る

QuickStartOpenid – dyuprojectのサンプルコードにほんに少しだけ異常系を付け足しただけです。

package my.package;

import com.dyuproject.openid.RelyingParty;
import com.dyuproject.openid.ext.AxSchemaExtension;
import com.dyuproject.openid.OpenIdUser;

public class OpenIdLoginServlet extends HttpServlet {

    static {
        RelyingParty.getInstance()
        .addListener(new AxSchemaExtension()
            .addExchange("email")
            .addExchange("nickname")
            .addExchange("fullname")
            .addExchange("gender")
            .addExchange("postcode")
            .addExchange("country")
            .addExchange("language")
        );
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
    {
        OpenIdUser user = (OpenIdUser) request.getAttribute(OpenIdUser.ATTR_NAME);
        if (user != null) {
            String identity = user.getIdentity();
            HttpSession session = request.getSession();
            session.setAttribute("identity", identity);
            Map axschema = AxSchemaExtension.get(user);
            if (axschema != null && axschema.size() > 0) {
                session.setAttribute("email", axschema.get("email"));
                session.setAttribute("nickname", axschema.get("nickname"));
            } else {
                session.setAttribute("email", "unknown");
                session.setAttribute("nickname", identity);
            }
        } else {
            //
        }
        response.sendRedirect(response.encodeRedirectURL(request.getParameter("redirect_url")));
    }

}

 
 


ログアウト用サーブレットを作る

QuickStartOpenid – dyuprojectにはサンプルが無かったけど、ログインしっぱなしじゃ困るから、ログアウト用サーブレットも作ります。

package my.package;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.servlet.RequestDispatcher;

public class OpenIdLogoutServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
    {
        HttpSession session = request.getSession(false);
        session.invalidate();
        response.sendRedirect(response.encodeRedirectURL(request.getParameter("redirect_url")));

    }
}

 
 


動かす

あとはHTMLでいいので、OpenIDプロバイダのURLを引数 “openid_identifier”にセットして、サーブレットに渡すAタグなり、フォームなりを書いて実行します。

mixi OpenIDならこんな感じですね。

<a href="openid-login?openid_identifier=https://mixi.jp">mixiでログインします</a>

なんて簡単なんでしょう。

サンプルコードでは、mixi、Google、Yahoo!、openid.ne.jp は動きました。
hatena はうまくいきませんでした。なんでだろう。

nickNameが取れたのはmixiだけでした。

 
 


カテゴリー: Google App Engine, OpenID, java タグ:

Google App Engine for Java で Google Data (GData) API を使う 1

2010 年 3 月 11 日 tdtsh Comments off

Google App Engine/Java (以下 GAE/J) のアプリケーションから、Google Calender とか、Google Mapとか、Picasa Web Albums とかと連携したい。

なんでも、Google Data (GData) APIなるものを使えば良いらしい。

Google Data (GData) APIとは

GData APIとはなんでしょう。
Google Data (GData) APIのサイトによると、
「Google DATA API では、Web 上のデータを読み書きするシンプルな標準プロトコルを提供します。」ということです。

サポートされているGoogleのサービスは、こんなにあります。(2010年3月現在)


Google Data (GData) API クライアント ライブラリ

GAE/JなのでJava版を使いますけど、phpやJavaScriptでもイケるので簡単に試せますね。

Downloads – gdata-java-client – Project Hosting on Google Codeからライブラリをダウンロードします。
サンプルは要らないので、gdata-src.java-1.40.3.zip にしましたが、ライブラリが欲しいだけならどっちでもいいです。

ダウンロードしたzipファイルの、gdata/java/lib に、たくさんjarファイルがあります。
利用したいGoogleのサービスに対し、jarファイルの名称から何が必要かなんとなく想像がつきますね。

gdata-analytics-2.1.jar
gdata-analytics-meta-2.1.jar
gdata-appsforyourdomain-1.0.jar
gdata-appsforyourdomain-meta-1.0.jar
gdata-base-1.0.jar
gdata-blogger-2.0.jar
gdata-blogger-meta-2.0.jar
gdata-books-1.0.jar
gdata-books-meta-1.0.jar
gdata-calendar-2.0.jar
gdata-calendar-meta-2.0.jar
gdata-client-1.0.jar
gdata-client-meta-1.0.jar
gdata-codesearch-2.0.jar
gdata-codesearch-meta-2.0.jar
gdata-contacts-3.0.jar
gdata-contacts-meta-3.0.jar
gdata-core-1.0.jar
gdata-docs-3.0.jar
gdata-docs-meta-3.0.jar
gdata-finance-2.0.jar
gdata-finance-meta-2.0.jar
gdata-gtt-2.0.jar
gdata-gtt-meta-2.0.jar
gdata-health-2.0.jar
gdata-health-meta-2.0.jar
gdata-maps-2.0.jar
gdata-maps-meta-2.0.jar
gdata-media-1.0.jar
gdata-photos-2.0.jar
gdata-photos-meta-2.0.jar
gdata-projecthosting-2.1.jar
gdata-projecthosting-meta-2.1.jar
gdata-sidewiki-2.0.jar
gdata-sidewiki-meta-2.0.jar
gdata-sites-2.0.jar
gdata-sites-meta-2.0.jar
gdata-spreadsheet-3.0.jar
gdata-spreadsheet-meta-3.0.jar
gdata-webmastertools-2.0.jar
gdata-webmastertools-meta-2.0.jar
gdata-youtube-2.0.jar
gdata-youtube-meta-2.0.jar

gdata/java/deps にも、こんなんいてはります。

google-collect-1.0-rc1.jar
jsr305.jar

疲れたから次回に続きます。

カテゴリー: Google App Engine, java タグ:

javax.imageio.ImageIO で gif画像 の write (とリサイズ関係)

2010 年 2 月 26 日 tdtsh Comments off

たまたまImageIOを触る機会があって始めて認識した事なんですが、javax.imageio.ImageIO で gif 画像を扱う時、JDK5まではreadが出きてもwirteが出来なかったんですね。

「Java SE 6完全攻略」第13回 GIFファイルの書き出し – IT Pro

よくよく考えたら判ることだったんですけど、2004年頃まではUnisys特許絡みがあったので、書き込み出来なくしてたんですね。

ImageIO と絡んでgifとかの画像のリサイズとか調べてたら、イイ感じのサンプル発見したのでメモ。

今まで AffineTransformOp を多用していたのですが、「早いけど、荒い」方法だったんですね。どうりでリサイズ後のベクター画像が汚いわけだ・・・

Image Javaテクニカルサンプル集さんの、ここここここ

多分ここのコードは物凄く再利用されているんだろうなぁ。
そういう意味では、目立たないけどすごい社会貢献だと思います。

私も見習いたいと思います。

カテゴリー: java タグ:

GAE/J (Google App Engine for java) で 拡張log4jを使う(日本時間)

2010 年 2 月 4 日 tdtsh Comments off

先日、GAE/J (Google App Engine for java) で log4jを使うの続きです。

こんな素敵なエントリーを発見!
GAE/Jでlog4jの日付を日本時間で出力する。- 今週のキャリッジさん

GAEの管理コンソールの[Logs]の表示を日本時間にする事は出来ないけど、ログ出力の中身を日本時間にする事は出来る模様。

logging.apache.orgから、apache-log4j-extras-1.0.tar.gz を取ってきて、解凍した apache-log4j-extras-1.0.jar を、war/WEB-INF/lib にコピーして、eclipseのビルドパスに追加しました。

それから、src/log4j.properties を修正します。

log4j.appender.A1.layout=org.apache.log4j.PatternLayout
↓
log4j.appender.A1.layout=org.apache.log4j.EnhancedPatternLayout

log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%F:%L] - %m%n
↓
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}{Asia/Tokyo} %-5p - %m%n

war/WEB-INF/appengine-web.xml 書いときます。

<system-properties>
	<property name="org.apache.commons.logging.Log" value="org.apache.commons.logging.impl.Log4JLogger"/ >
	<property name="java.util.logging.config.file" value="WEB-INF/classes/log4j.properties"/>
</system-properties>
カテゴリー: Google App Engine, java タグ: