情報学類 分散システム					2008年02月19日
                                       筑波大学システム情報工学研究科
                                       コンピュータサイエンス専攻, 電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
	http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2007/2008-02-19
あるいは、次のページから手繰っていくこともできます。
	http://www.coins.tsukuba.ac.jp/~yas/
	http://www.cs.tsukuba.ac.jp/~yas/
協調して動作しているプログラムの間で、ある一連の作業を識別するための数 を意味する。
RPCでは、途中経過を表すのに利用する。 NFS では、readdir() で用いられている。
WWW(World Wide Web)では、1回のデータ転送ごとに通信路が切断される ので、通常はWWWのブラウザ(クライアント)とWWWサーバの間では、途 中経過を保持することができない。
途中経過を保存したい時:
WWWで途中経過を保存するためには、cookie が使われる。
4.  EXAMPLES
4.1  Example 1
   Most detail of request and response headers has been omitted.  Assume
   the user agent has no stored cookies.
      1. User Agent -> Server
        POST /acme/login HTTP/1.1
        [form data]
        User identifies self via a form.
      2. Server -> User Agent
        HTTP/1.1 200 OK
        Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
        Cookie reflects user's identity.
      3. User Agent -> Server
        POST /acme/pickitem HTTP/1.1
        Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
        [form data]
        User selects an item for "shopping basket".
      4. Server -> User Agent
        HTTP/1.1 200 OK
        Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
                Path="/acme"
        Shopping basket contains an item.
      5. User Agent -> Server
        POST /acme/shipping HTTP/1.1
        Cookie: $Version="1";
                Customer="WILE_E_COYOTE"; $Path="/acme";
                Part_Number="Rocket_Launcher_0001"; $Path="/acme"
        [form data]
        User selects shipping method from form.
      6. Server -> User Agent
        HTTP/1.1 200 OK
        Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
        New cookie reflects shipping method.
      7. User Agent -> Server
        POST /acme/process HTTP/1.1
        Cookie: $Version="1";
                Customer="WILE_E_COYOTE"; $Path="/acme";
                Part_Number="Rocket_Launcher_0001"; $Path="/acme";
                Shipping="FedEx"; $Path="/acme"
        [form data]
        User chooses to process order.
      8. Server -> User Agent
        HTTP/1.1 200 OK
        Transaction is complete.
   The user agent makes a series of requests on the origin server, after
   each of which it receives a new cookie.  All the cookies have the
   same Path attribute and (default) domain.  Because the request-URIs
   all path-match /acme, the Path attribute of each cookie, each request
   contains all the cookies received so far.
http://www.coins.tsukuba.ac.jp/~syspro/2007/shui/1stHalf.html#sec:buffer-overflow
   1:	/*
   2:	        strcat-snprintf.c -- snprintf を使った文字列のコピーと結合
   3:	        ~yas/syspro/string/strcat-snprintf.c
   4:	        Created on: 2006/01/17 03:17:24
   5:	*/
   6:	
   7:	#include <stdio.h> /* stderr, snprintf() */
   8:	#include <stdlib.h> /* malloc() */
   9:	#include <string.h> /* strcat() */
  10:	
  11:	
  12:	main( int argc, char *argv[], char *envp[] )
  13:	{
  14:	        if( argc != 2 )
  15:	        {
  16:	            fprintf(stderr,"Usage:%% %s string\n",argv[0] );
  17:	            exit( 1 );
  18:	        }
  19:	        good( argv[1] );
  20:	        bad( argv[1] );
  21:	}
  22:	
  23:	#define DOCUMENT_ROOT "/usr/local/httpd/htdocs/"
  24:	#define BUFFSIZE 100
  25:	
  26:	bad( char *s )
  27:	{
  28:	    char buf[BUFFSIZE];
  29:	    int fd ;
  30:	        strcpy( buf,DOCUMENT_ROOT );
  31:	        strcat( buf,s );
  32:	        printf(" bad: open(\"%s\", O_RDONLY )\n",buf );
  33:	}
  34:	
  35:	good( char *s )
  36:	{
  37:	    char buf[BUFFSIZE];
  38:	    int req ;
  39:	        req = snprintf( buf,sizeof(buf),"%s%s",DOCUMENT_ROOT,s );
  40:	        if( req >= sizeof(buf) )
  41:	        {
  42:	            fprintf(stderr,"good: buffer overflow attack detected.\n");
  43:	            fprintf(stderr,"required: %d, actual: %d, strlen: %d, [%s]\n",
  44:	                    req, sizeof(buf), strlen(buf), buf );
  45:	            return( 0 );
  46:	        }
  47:	        printf("good: open(\"%s\", O_RDONLY )\n",buf );
  48:	        return( 1 );
  49:	}
snprintf() の引数
snprintf() は、%s 以外に %d や %c も使える。
snprintf() は、決してバッファ・オーバーフローを起こすことはないが、バッ ファが足りない時には意図していない結果が保存されていることになる。後ろ が切れてもよい場合には、リターンされた結果を比較しない方法がある。 (void とも書かなくてもよい。)
(void)snprintf( buf,sizeof(buf),"%s%s",DOCUMENT_ROOT,s );
実行例:
% cp ~yas/syspro/string/strcat-snprintf.c . 
% make strcat-snprintf 
cc     strcat-snprintf.c   -o strcat-snprintf
% ./strcat-snprintf index.html 
good: open("/usr/local/httpd/htdocs/index.html", O_RDONLY )
 bad: open("/usr/local/httpd/htdocs/index.html", O_RDONLY )
% ./strcat-snprintf 01234567890123456789012345678901234567890123456
789012345678901234567890123456789012345678901234567890123456789
good: buffer overflow attack detected.
required: 134, actual: 100, strlen: 99, [/usr/local/httpd/htdocs/0123456
78901234567890123456789012345678901234567890123456789012345678901234]
 bad: open("/usr/local/httpd/htdocs/012345678901234567890123456789012345
678901234567890123456789012345678901234567890123456789012345678901234567
89", O_RDONLY )
Segmentation fault
% 
Gateway とは、WWW で使われている HTTP というプロトコルへの入り口という 意味である。 プログラムの実行結果は、普通は、HTML にすることが多いが、普通のテキス トであることもイメージであることもある。
CGI の利用例
JavaScript は、文法が少し Java 言語に似ているが、Java とはまったく別の 言語である。WWW ページの中の Javaアプレットは、 「実行可能なインライン・イメージ」に似ている。これに対して JavaScript の記述は、「実行可能なインライン・テキスト」 に似ている。
JavaScrip のプログラムの例:
<SCRIPT LANGUAGE="JavaScript">
<!--
for( i=0 ; i<10; i++ )
  document.writeln("<P>hello,world</P>");
//-->
</SCRIPT>
これは、<P>hello,world</P> を 10 回書いた
のと同じ効果がある。<!--と
//->は、JavaScriptを知らないブラウザにはコメント
として扱われる。関数定義などは、ヘッダ部分
<HEAD></HEAD>に書くという方法もよく使われる。
for、while 、
if, else, continue,
break がある。ただし、switch は使えない。
function で、関数定義ができる。
var で宣言すれば、ローカル変数になる。
配列は、new Array(長さ) で確保する。
class というキーワードはない。
function に new を付けて呼べば、オブジェ
クトになる。オブジェクトのメソッドでは、this を使っ
て要素を参照できる。
JavaScript の記述は、CGI と似ているところもあるが、JavaScript でないと
できないものに、ブラウザの制御がある。たとえば、次の例では、ブラウザの
(戻る)ボタンと同じ動きをさせることができる。
<A HREF="javascript:history.back();">戻る</A>次の例は、
<FORM></FORM>からパラメタを受け取るも
のである。
<SCRIPT LANGUAGE="JavaScript">
function go(s,h,p)
{
	location.href = s.value + "://" + h.value + p.value ;
}
</SCRIPT>
<FORM NAME="form1">
<INPUT NAME="scheme" TYPE="text" VALUE="http"><BR>
<INPUT NAME="host"   TYPE="text"><BR>
<INPUT NAME="path"   TYPE="text" VALUE="/"><BR>
<INPUT TYPE="button" VALUE="go" onClick="go(form1.scheme,form1.host,form1.path)">
</FORM>
onClick 属性の値は、クリックした時に評
価される式であり、関数 go() が呼び出されている。引
数は、<FORM> の値である。関数 
go() の中では、
.value フィールドから値が読み出されている。
location.href に代入することで
そのページを表示させることができる。
この例では、<INPUT type="text">と
<INPUT type="button">が使われている。その他に、
<FORM>では、<INPUT
TYPE="radio">、<INPUT TYPE="checkbox">、
<SELECT>が使える。イベントとしては、
onClick が主に使われる。その他に、
onFocus が使われることもある。
JavaScript では、document.open() で新しく HTML の
ドキュメントを生成して、それをブラウザに表示させることもできる。
WWWブラウザでは、信頼しているサイトから送られてくるJavaScriptのプログ ラムだけを実行するようにし、攻撃サイトから送られてくるJavaScriptのプロ グラムを実行しないようにしたい。
脆弱性があるサイトでは、攻撃サイトから送られてきた JavaScript のプログ ラムを中継してしまう。
 図? JavaScripの送信元サイトの区別
CGI のプログラムをつくる時には、クロスサイトスクリプティング攻撃に気を つける。これは、クライアントから送られてる文字列の中に <SCRIPT>のようなタグが含まれていた場合、それをそのままクラ イアントに送り返すと問題がある。
クライアントから送られてきた文字列は、必ず検査し、安全な状態にして (sanitize)から使う。「<>&"」のようなタグが含まれている場合 には注意する。このような文字列を受け取った場合、不用意に送り返してはい けない。送り返す時には、必ず次のように変換する。
| 画面表示 | 代りに送りだす文字列 | 
| & | & | 
| < | < | 
| > | > | 
| " | " | 
format.c]
   1: 
   2: /*
   3:         f o r m a t .c -- printf() 系の危険な利用方法
   4:  */
   5: main(int argc, char *argv[])
   6: {
   7:         printf(argv[1]);
   8: }
% wget http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2007/2008-02-19
/format.c 
% make format 
cc     format.c   -o format
% ./format aaa 
aaa% 
% ./format "%s%s%s%s"  
Bus error
% 
printf() の  には、外から来た文字列を与えてはならない。
syslog(3) も同様。
そのような誰でも書き込める場所に不用意にのファイルを作るプログラムはシ ンボリックリンク攻撃に対して脆弱性を持つ。
if( check(filename) )
	    fd = open(filename,O_RDONLY)
check() と open() の間に、check() の状態が変化してしまうことがある。
他のプログラムを実行する時には、execve() のようなシステムコールを使い、
かつ、限られたプログラムしか実行しないようにすると安全性が高くなる。ク
ライアントから送られてきた文字列をsystem() や popen() に渡してプログラ
ムを実行する時には、必ず検査する。特にシェルが解釈する特殊な文字
「| & ; && || `」などが含
まれていた場合、意図しないプログラムが実行されることがある。
char *user ;
...
snprintf(cmd,BUFSIZE,"finger %s",user );
f = poepn(cmd,"r");
もし、user に ";" や "|" が含まれていたら、、、 
f = poepn("finger yas; /bin/sh","r");
perl の open() には、危険性がある。 C 言語のライブラリ関数 popen() と同じ動きをすることがある。
open(FILE, "|cmd")
Perl の危険な関数、式、
産業技術総合研究所 グリッド研究センター セキュアプログラミングチーム
http://securit.gtrc.aist.go.jp/
)
IPA セキュア・プログラミング講座
http://www.ipa.go.jp/security/awareness/vendor/programming/
)