Security関係のLinkをまとめました。 はてぶにすればいいのに > 自分
- 高木浩光@自宅の日記
- 徳丸浩の日記
- Masato Kinugawa Security Blog
- mala 今LINEにいるんですね
- yohgaki's blog 書かない日記
- 忙しい人のためのサイバーセキュリティニュース
- (n), (n)inja csirt(個人でCSIRT)
- マクニカネットワークスセキュリティ研究センターブログ
あー、勉強しないと。
Security関係のLinkをまとめました。 はてぶにすればいいのに > 自分
あー、勉強しないと。
ここ最近、Knapsack Problemが流行っている感じがしています。
応用情報技術者過去問題 平成29年春期 午後問3では基本「全探索」、改善提案が「枝刈り」でしたが、それでは全然不十分です。この問題は要するにKnapsack Problemのちょっとした変形で、code量もさしたることなく書けますし、折角FEではなくAPなのだし、日本の若者のためにも、Knapsackで書くよう誘導すべきだったのでは、と「禿げしく」思ったものでした。
すると、今度は応用情報技術者過去問題 平成29年秋期 午後問3でKnapsack Problemを正面から出してきましたね。0-1ではなく普通の。ぼくは前回のrevengeではないかと思ってみています。 問題自体は、あまりにも普通のKnapsack Problemなので、ツッコミようがなくてつまんなかったデス。
この他にアジアでも。そっちは0-1でした。
ちなみに日本語では「ナップザック」、登山用語はドイツから入ってきたから、です。
Robolectricのquick startは、本家が詳しい。
build.gradle
に、以下が必要(Android Studio 2系の場合)。 1 2 3 4 5 6 7 |
|
public class CLASS名
のところで黄色いヒントをclickしてCreate Test class
を選択、JUnit4
で作成Whitebox
はorg.powermock.reflect.Whitebox
で置き換え@RunWith
のMockitoJUnitRunner
はorg.mockito.junit.MockitoJUnitRunner
で置き換えorg.mockito.exceptions.misusing.UnnecessaryStubbingException:
というwarningが出るようになったので@RunWith(MockitoJUnitRunner.Silent.class)
にすると解消Robolectric
なTestは、1.@RunWith(RobolectricTestRunner.class)
2.activity = Robolectric.setupActivity(SomeActivity.class);
でActivity
を起動RuntimeException: Multi dex installation failed
と言われるのでshadows-multidex
が必要@RunWith
がかぶっちゃうよ、どうしよう! → 本家に解説あり。要は、@PowerMockIgnore
でmockito、robolectric、android標準classesを除外、@PrepareForTest
でstatic methodを持つclassを指定し、@Rule
を入れ(使わないのによくわからないが必要)、PowerMockito.mockStatic(...)
で当該classを指定NoClassDefFoundError: org/powermock/classloading/ClassloaderExecutor
と言われるので、powermock-classloading-xstream
が必要NoClassDefFoundError: org/mockito/cglib/proxy/MethodInterceptor
と言われるので、powermock-api-mockito2
と2
でないとならないjavax.xml.parsers.FactoryConfigurationError: Provider ...DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory
と言われるので@PowerMockIgnore
に"javax.xml.*", "org.xml.sax.*", "org.w3c.dom.*", "org.apache.log4j.*"
が必要org/powermock/default.properties is found in 2 places
と言われてerrorにはならないけどwarningが出るので、@PowerMockIgnore
に"org.powermock.*"
も入れておく(試行錯誤の末なので参照なし)AsyncTask
があっても、特段その終了を待たずにtestが終了してしまう。Robolectric.getBackgroundThreadScheduler().pause();
でAsyncTask#doInBackground()
を止める必要がある(AsyncTask#onPreExecute()
は実行される)。ShadowAsyncTaskTest.java
を見ると、setUp()
でRobolectric.getBackgroundThreadScheduler().pause();
(とRobolectric.getForegroundThreadScheduler().pause();
?)でthread止めて、asyncTask.execute()
するとonPreExecute()
が動き、次にShadowApplication.runBackgroundTasks();
するとdoInBackground()
、ShadowLooper.runUiThreadTasks();
するとonPostExecute()
が動く(ようだが、試してみるとShadowApplication.runBackgroundTasks()
で返ってこなくなった。何故?!←これは単にAsyncTask
中でdialog出して止まっていたため)PowerMockito.whennew(XXX.class).thenReturn(mock);
だと、 1 2 3 4 |
|
@Implements
書くのは面倒ではあるが、PowerMockを@Rule
して並存させると上述のようにclass loaderがどうのと言われて失敗したので、Robolectric一本で頑張った方がよさ気。PowerMock使わないならtestCompile
もrobolectric
とshadows-multidex
の2つで済むし、PowerMock導入に伴って変更したMockito部分も変更不要になる。@Config
にshadows={ShadowXXX.class}
と追記していけば良い。ShadowXXX
というclassが揃っている(e.g. ShadowActivity
)。まるっとmockしたものを返したい場合には、custom shadow methodでreturn Shadow.newInstanceOf(ShadowBluetoothDevice.class);
で良い。public void __constructor__(...){...}
でよく、@Implementation
annotationは不要(あっても害はない)。extends
してるclassのconstructorの場合には、super classのconstructorのshadowingも必要。さもなくばsuper classの当該constructorが実行されてしまう。また、super classのconstructorもshadowingする場合、当該Shadow classの方もextends
しないとClassCastException
に見舞われる。A extends B
でA
のconstructorをshadowingしたらB
のconstructorもshadowingし、ShadowA extends ShadowB
にする必要がある。Shadows.shadowOf(myDialog).hasBeenDissmissed()
といったようにUIの状態を取得できる。context.getPackageManager().getLaunchIntentForPackage("package name")
がRobolectricsでやるとnull
を返しやがるのでヌルポで失敗しくさる。多くの人が困っている模様。cf. PackageManager#getLaunchIntentForPackage() returns null #747 ←これによると2.2の頃から。3.4からPackageManager
周りはRobolectricPackageManager
がdeprecatedになって他と同じようにShadowPackageManager
を使えとMigrating from 3.3 to 3.4にはあるが、shadowOf(RuntimeEnvironment.application.getPackageManager());
としても、versionを3.3に落としてRuntimeEnvironment.setRobolectricPackageManager(packageManager);
としても、testにおけるApplicationPackageManager#getLaunchIntentForPackage
はnull
を返す。仕方なく、ShadowApplicationPackageManager
をextendsしてcustom PackageManagerを作ってみても、何を@implements
したらいいのか。PackageManager.class
では効かないし(抽象クラス?なのでそれは仕方ないのだろう)、android.app.ApplicationPackageManager.class
では何故か名前解決に失敗してcompile出来ない。RobolectricPackageManagerTest.javaを見ると、notNullValue()
でassert出来そうなのだが、うまく行かなかった(Step Overしてやってみても、そもそもShadowApplicationPackageManager
ではなくandroid.app.ApplicationPackageManager#getLaunchIntentForPackage
が何かにmethod callを取られて空で返している感じ)。色々探して結局諦めた。ホントは、↓というようにやりたかったのだが。 1 2 3 |
|
せめてresourceの場所なりと。
app/src/main/java/...
にsourceがありapp/src/test/groovy/...
にSpock Testcodeがある)。build.gradle
でのandroid.sourceSets.test.setRoot(...)
は効かないようだったbuildscript.dependencies
でclasspath 'org.codehaus.groovy:groovy-android-gradle-plugin:1.2.0'
を指定、apply plugin: 'com.android.application'
とapply plugin: 'groovyx.android'
を指定、dependencies
にtestCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
を指定すれば素のSpock、testCompile 'com.github.hkhc:electricspock:0.6'
ならElectricSpock、androidTestCompile 'com.andrewreitz:spock-android:2.0'
ならSpock for Android(←これだけandroidTestCompile
なのに注意)という感じでしょうか。
RxJava + Retrofitなんて鉄板だからRobolectricによるtestなんてすぐ見つかると思ってたんですが、意外に手こずりました。要は、
RxJavaHooks
(RxJava のテスト(2): RxJavaHooks, RxAndroidPlugins)MockWebServer
は、例にあるように基本new
してMockResponse
をenqueue
してurl(...)
すればstartしてreturn valueにURL(http://localhost:XXXXX/
←random port number)が入っているのでそれをRetrofitに食わせればいいのだけれども、URLをsetする部分はShadowの中なので、test classから直接食わせられず。なので固定port番号を使いたく、その場合server.url("/...");
は不要で、 1
|
|
http
になるとisCleartextTrafficPermitted()
まわりで失敗するようになった。これは、isCleartextTrafficPermitted()
fails on OpenJDK 8 + Robolectric #2533にあるように、NetworkSecurityPolicy
をShadowしてやればよい。onNext
やonCompleted
が実行されない問題は、Robolectric.flushBackgroundThreadScheduler();
ではなく、 1
|
|
Retrofit2
のService interfaceでObservable<...>
を返す場合のもの。Call<...>
を返す形にしてenqueue()
してCallback<...>
でonResponse()
、onFailure()
でhandleする場合には、こうは行かなかった(onResponse()
もonFailure()
も実行されない)。ShadowLooper.runUiThreadTasks()
でうまく行くようなことを書いてある情報(Testing retrofit 2 with robolectric, callbacks not being called)もあったが、症状変わらず。OkHttpのMockWebServerとRobolectricでFragmentの動作をテストするにRetrofit2内で使っているOkHttpClient.Builder#newBuilder
をshadowしてうまく行く話があったので、試すと確かにonResponse()
が呼ばれた! ただ、今回ぼくは実classの方でnew Retrofit().newBuilder().client(new OkHttpClient().newBuilder().build())
とかってclient
methodを使っておらずdefaultで裏でimplicitlyに生成されるOkHttpClient
そのまま使っており、それだとnewBuilder()
呼ばれないので、色々辿ってった挙句、okhttp3.Dispatcher#executorService
をshadowして、前述のpageにあったようにすぐcommand.run()
するexecute
methodを持つAbstractExecutorService
classを返してやると、うまく行った。Dispatcher#executorService
ってjava.util.concurrent.ThreadPoolExecutor
をdefaultでは使っており、Androidのthreadとは違うから、uncontrollableだったんですね。考えてみるに、RxAndroidと違いRetrofitはAndroid専用ではないので、java.util.concurrent
のExecutor
使ってるのも当然ですか。基本的には、AccountManager.get(Context)
はJUnit Test内でもtarget class内でも同じobjectを返すので、そのままassertion可能
ただ、例えばmanager.blockingGetAuthToken(...)
でExceptionを起こさせたい時は、AccountManager manager = spy(AccountManager.get(application));
したmanager
をgetSystemService(Context.ACCOUNT_SERVICE)
でdoReturn
するようにしたApplication
をspy
して、そのapplication
をRuntimeEnvironment.application
の代わりにねじ込む必要がある(Using mockito to mock AccountManager)。具体的には、 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Rule
public ExpectedException thrown = ExpectedException.none();
:
Account account = new Account("any name", CarCloudAuthUtil.ACCOUNT_TYPE);
Application application = spy(RuntimeEnvironment.application);
util = new CarCloudAuthUtil(application);
AccountManager manager = spy(AccountManager.get(application));
doReturn(manager)
.when(application)
.getSystemService(Context.ACCOUNT_SERVICE);
manager.addAccountExplicitly(account, "any key", new Bundle());
manager.setAuthToken(account, CarCloudAuthUtil.AUTH_TOKEN_TYPE, "any string");
doThrow(AuthenticationException.class)
.when(manager)
.blockingGetAuthToken(eq(account), eq(CarCloudAuthUtil.AUTH_TOKEN_TYPE), eq(true));
thrown.expect(AuthenticationException.class);
thrown.expectMessage(new IsNull());
Exception
のassertionは、@Test(expected=...)
でも良いが、@Rule
でも書ける(JUnitでの例外テストの書き方)。その場合、Exception#message
がnull
の場合のassertionはorg.hamcrest.core.IsNull
を用いてthrown.expectMessage(new IsNull());
とする(ExpectedException.expectMessage((String) null) is not working)。
mocking method実行時に他のことをしたい時には、when(mock.methodCall()).thenAnswer(m -> {...});
とlambdaで書ける(mockitoとJMockitについてのメモ)。
Tomcatの複数の脆弱性(CVE-2017-12617, CVE-2017-12615 , CVE-2017-12616)が、範囲が広がって出てました。 readonly initialization parameter
をfalse
にしてPUT
を有効化している時にaffectする(任意のjsp fileを不正にPUT
してから好き放題する)、とのことなので、きょうびはRESTでPUT
多用するから影響範囲広いんでしょうか? 否、「default servletのinitialization parameter(具体的にはweb.xml
のservlet
tagのinit-param
)でfalse
を明示した時(defaultはtrue
)なので、殆どのところはそんなことしてないから大丈夫なんじゃないでしょうか。 実際、POCで試してみたところ、うちのsiteは(version的には範囲内ですが)Not Vulnerable to CVE-2017-12617
と出ました。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ python tomcat-cve-2017-12617.py -u http://localhost:8080
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
[@intx0x80]
Poc Filename Poc.jsp
Not Vulnerable to CVE-2017-12617
こういうの、あったんですねー。すごいすごい。 Alpaca Algo、かつてのCapitalicoだそうですが、 自分でindicatorを指定して、勝ちpattern(負例も!)を指定して、 そうすると裏で超高速に事例を学習し、 back testまで速攻でやってくれるとは! 幾つか試してみましたけど、テキトーにやっても、 back testでプラスになったりするので、おぉー! と思ってはみたものの。 back testの期間をdefaultの3ヶ月ではなく、 1年とか、特に2016年を入れると、 途端に物凄い成績悪くなります。 なんでー!? 2016年って何か違ったんでしょうか。 っていうか、2017年の方がおかしい? とにかく、何か違うようです。
patternに当てはまったら通知もしてくれるというので、 試してみます。 まだ本番への適用は怖い感じですが。
9日朝、2回通知来ましたけど、以降はさっぱり当たりませんでした。 デモ取引では、10:05にentryして15:48現在まだ売買成立してません。 ドル円上下15pipsなので、day tradeにはちょっと大きめの幅なんでしょう。
色々試してみると、