情報学類 分散システム 2007年02月27日 筑波大学システム情報工学研究科 コンピュータサイエンス専攻, 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2006/2007-02-27
あるいは、次のページから手繰っていくこともできます。
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/2006/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 0123456789012345678901234567890123456789012345678901
2345678901234567890123456789012345678901234567890123456789 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-2006/2007-02-27 /format.cprintf() の には、外から来た文字列を与えてはならない。 syslog(3) も同様。% make format
cc format.c -o format % ./format aaa
aaa%
% ./format "%s%s%s%s"
Bus error %
![]()
そのような誰でも書き込める場所に不用意にのファイルを作るプログラムはシ ンボリックリンク攻撃に対して脆弱性を持つ。
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 には、バッファ・オーバーフローの問題はない。
perl の open() には、危険性がある。 C 言語のライブラリ関数 popen() と同じ動きをすることがある。
open(FILE, "|cmd")Perl の危険な関数、式、
産業技術総合研究所 グリッド研究センター セキュアプログラミングチーム
http://securit.gtrc.aist.go.jp/
)
IPA セキュア・プログラミング講座
http://www.ipa.go.jp/security/awareness/vendor/programming/
)