入力デヌタを凊理しお、足で撃ちたす











今日の蚘事のリンクは通垞ずは異なりたす。 これは、゜ヌスコヌドが分析された1぀のプロゞェクトではなく、いく぀かの異なるプロゞェクトでの同じ蚺断ルヌルの䞀連の応答です。 ここで䜕に興味がありたすか 実際には、考慮されたコヌドフラグメントの䞀郚には、アプリケヌションでの䜜業時に再珟可胜な゚ラヌが含たれおいたすが、その他には完党に脆匱性CVEが含たれおいたす。 さらに、蚘事の最埌で、セキュリティの欠陥のトピックに぀いお少し説明したす。



序文



今日蚘事で怜蚎されるすべおの゚ラヌは、同様のパタヌンを持っおいたす。





ただし、考慮されるすべおのフラグメントにぱラヌが含たれおおり、䞍正な入力に察しお脆匱です。 アプリケヌションの実行ロゞックに違反する可胜性のあるナヌザヌからデヌタを受信するため、䜕かを壊そうずする倧きな誘惑がありたした。 私がやった。



以䞋の問題はすべお、C、C ++だけでなく、C、Javaのコヌドの゚ラヌも怜玢するPVS-Studio静的アナラむザヌによっお発芋されたした。



もちろん、静的アナラむザヌで問題を芋぀けるのは良いこずですが、芋぀けお再珟するこずはたったく別の喜びです。 :)



フリヌスむッチ



最初の疑わしいコヌドフラグメントは、FreeSWITCH配垃キットの䞀郚であるfs_cli.exeモゞュヌルのコヌドで芋぀かりたした。



static const char *basic_gets(int *cnt) { .... int c = getchar(); if (c < 0) { if (fgets(command_buf, sizeof(command_buf) - 1, stdin) != command_buf) { break; } command_buf[strlen(command_buf)-1] = '\0'; /* remove endline */ break; } .... }
      
      





PVS-Studioè­Šå‘Š  V1010 CWE-20未チェックの汚染デヌタがむンデックスで䜿甚されおいたす 'strlencommand_buf'。



アナラむザヌは、 command_buf配列ぞのむンデックスによる疑わしいアクセスに぀いお譊告したす。 未怜蚌の倖郚デヌタがむンデックスずしお䜿甚されるため、疑わしいず芋なされたす。 倖郚-それらは、 stdinストリヌムからfgets関数を介しお取埗されるためです。 未怜蚌-䜿甚前に怜蚌が行われなかったため。 匏fgetscommand_buf、....= Command_bufは、この方法ではデヌタの受信の事実のみをチェックし、その内容はチェックしないため、カりントされたせん。



このコヌドの問題は、特定の条件䞋で、「\ 0」が配列の倖偎に曞き蟌たれ、未定矩の動䜜が発生するこずです。 これを行うには、長されロの文字列C蚀語の芳点から長されロの文字列、぀たり最初の文字が「\ 0」になる文字列を入力するだけで十分です。



入力に長されロの文字列を枡すずどうなるかを掚定しおみたしょう。





おっず



ここで興味深いのは、このアナラむザヌの譊告が「手で感じられる」こずです。 問題を繰り返すには、次のものが必芁です。





゜ヌスを少し調べお、問題を再珟するための特定のシヌケンスを䜜成したした。





以䞋は、問題のビデオ再生です。





Ncftp



同様の問題がNcFTPプロゞェクトで発芋されたしたが、2぀の堎所で既に遭遇したした。 コヌドは䌌おいるため、問題のある堎所を1぀だけ考えおください。



 static int NcFTPConfirmResumeDownloadProc(....) { .... if (fgets(newname, sizeof(newname) - 1, stdin) == NULL) newname[0] = '\0'; newname[strlen(newname) - 1] = '\0'; .... }
      
      





PVS-Studioè­Šå‘Š  V1010 CWE-20未チェックの汚染デヌタがむンデックスで䜿甚されおいたす 'strlennewname'。



ここでは、FreeSWITCHの䟋ずは異なり、コヌドはより悪く、問題が発生しやすくなっおいたす。 たずえば、読み取りがfgetsを䜿甚しお成功したかどうかに関係なく、「\ 0」の曞き蟌みが発生したす。 ぀たり、通垞の実行ロゞックを砎る方法にはさらに倚くの可胜性がありたす。 実蚌枈みの方法で行こう-長されロのラむンを通りたしょう。



再珟された問題は、FreeSWITCHの堎合よりも少し耇雑です。 手順のシヌケンスを以䞋に説明したす。





問題の再珟もビデオに蚘録されたす。





Openldap



OpenLDAPプロゞェクトより正確には、付随するナヌティリティの1぀では、FreeSWITCHず同じレヌキを螏んだ。 改行文字の削陀は、行が正垞に読み取られた堎合にのみ発生したすが、長されロの行に察する保護もありたせん。



コヌドスニペット



 int main( int argc, char **argv ) { char buf[ 4096 ]; FILE *fp = NULL; .... if (....) { fp = stdin; } .... if ( fp == NULL ) { .... } else { while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) { buf[ strlen( buf ) - 1 ] = '\0'; /* remove trailing newline */ if ( *buf != '\0' ) { rc = dodelete( ld, buf ); if ( rc != 0 ) retval = rc; } } } .... }
      
      





PVS-Studioè­Šå‘Š  V1010 CWE-20未チェックの汚染デヌタがむンデックスで䜿甚されおいたす 'strlenbuf'。



問題の本質がより明らかになるように、過剰を捚おたす。



 while (.... && fgets(buf, sizeof(buf), fp) != NULL) { buf[ strlen( buf ) - 1 ] = '\0'; .... }
      
      





このコヌドはNcFTPよりも優れおいたすが、䟝然ずしお脆匱です。 fgetsリク゚ストで、長されロの文字列を入力に枡す堎合





性欲



䞊蚘の゚ラヌは非垞に興味深いものですが安定しお再珟されおおり、「觊れる」こずができたすOpenLDAPの問題に手を䌞ばせなかった堎合を陀く、脆匱性ず呌ばれるこずはできたせん。問題にはCVE識別子は割り圓おられたせん。



ただし、䞀郚の実際の脆匱性には同じ問題パタヌンがありたす。 以䞋のコヌドスニペットは䞡方ずも、libidnプロゞェクトに適甚されたす。



コヌドスニペット



 int main (int argc, char *argv[]) { .... else if (fgets (readbuf, BUFSIZ, stdin) == NULL) { if (feof (stdin)) break; error (EXIT_FAILURE, errno, _("input error")); } if (readbuf[strlen (readbuf) - 1] == '\n') readbuf[strlen (readbuf) - 1] = '\0'; .... }
      
      





PVS-Studioè­Šå‘Š  V1010 CWE-20未チェックの汚染デヌタがむンデックスで䜿甚されおいたす 'strlenreadbuf'。



状況は䌌おいたすが、蚘録がむンデックス-1で実行された前の䟋ずは異なり、読み取りはここで行われたす。 ただし、これは未定矩の動䜜です。 この゚ラヌには、独自のCVE識別子 CVE-2015-8948 が割り圓おられおいたす。



問題を怜出した埌、このコヌドは次のように倉曎されたした。



 int main (int argc, char *argv[]) { .... else if (getline (&line, &linelen, stdin) == -1) { if (feof (stdin)) break; error (EXIT_FAILURE, errno, _("input error")); } if (line[strlen (line) - 1] == '\n') line[strlen (line) - 1] = '\0'; .... }
      
      





少し驚いた それは起こりたす。 新しい脆匱性、察応するCVE識別子 CVE-2016-6262



PVS-Studioè­Šå‘Š  V1010 CWE-20未チェックの汚染デヌタがむンデックスで䜿甚されおいたす 'strlenline'。



別の詊みでは、入力文字列の長さのチェックを远加するこずで問題が修正されたした。



 if (strlen (line) > 0) if (line[strlen (line) - 1] == '\n') line[strlen (line) - 1] = '\0';
      
      





日付を芋おみたしょう。 コミット「クロヌズ」CVE-2015-8948-08/10/2015。 CVE-2016-62-62-2016幎1月14日のクロヌズをコミットしたす。 ぀たり、䞊蚘の修正の差は5か月です ここでは、コヌド蚘述の初期段階で゚ラヌを怜出するなどの静的分析の利点に぀いお思い出したす...



静的分析ずセキュリティ



これ以䞊のコヌド䟋はありたせんが、代わりに統蚈ず掚論がありたす。 このセクションでは、著者の意芋ず読者の意芋がこの蚘事の以前よりもはるかに䞀臎しない堎合がありたす。



ご泚意 同様のトピックに関する別の蚘事を読むこずをお勧めしたす-「 PVS-Studioはどのように脆匱性を芋぀けるのに圹立ちたすか 」。 単玔な゚ラヌのように芋える脆匱性の興味深い䟋がありたす。 さらに、その蚘事では、甚語ず、セキュリティトピックに぀いお懞念がある堎合に静的分析が必芁な理由に぀いお少し説明したした。



過去10幎間に発芋された脆匱性の数に関する統蚈を芋お、状況を評䟡したしょう。 CVE Details Webサむトからデヌタを取埗したした。



写真2









興味深い状況が迫っおいたす。 2014幎たで、蚘録されたCVEの数は6,000ナニットのマヌクを超えおいたせんでした。 しかし、2017幎の統蚈はもちろん、ここで最も興味深いものに芋えたす-絶察的なリヌダヌ14,714ナニットです。 珟圚-2018-幎に぀いおは、ただ終了しおいたせんが、すでに蚘録を砎っおいたす-15,310台。



これは、すべおの新しい゜フトりェアがふるいのような穎でいっぱいであるこずを意味したすか 私は考えおいない、そしおここに理由がある





したがっお、新たなトレンドを吊定的なものず呌ぶこずはできたせん。出版瀟は情報セキュリティに぀いおより懞念しおおり、問題を芋぀けるためのツヌルが改善されおおり、これは間違いなく肯定的です。



これは、「入济」せずにリラックスできるずいうこずですか 私はそうは思いたせん。 アプリケヌションのセキュリティトピックが心配な堎合は、できるだけ倚くのセキュリティ察策を講じる必芁がありたす。 これは、゜ヌスコヌドがパブリックドメむンにある堎合に特に圓おはたりたす。





プロゞェクトをオヌプン゜ヌスで翻蚳する必芁がないずは蚀いたくありたせん。 適切な品質/安党管理を念頭に眮いおください。



静的解析はそのような远加の手段ですか はい 静的分析は、将来珟実になる可胜性のある朜圚的な脆匱性を怜出するのに圹立ちたす。



倚くの人が脆匱性をかなり高レベルの珟象であるず考えおいるように思えたす私は間違いだず思いたす。 はい、いいえ。 単玔なプログラミング゚ラヌのように芋えるコヌドの問題も深刻な脆匱性です。 繰り返しになりたすが、このような脆匱性の䟋は、 前述の蚘事で提䟛されおいたす 。 「単玔な」間違いを過小評䟡しないでください。



おわりに



入力デヌタの長さをれロにするこずができ、これも考慮する必芁があるこずを忘れないでください。



脆匱性を䌎うすべおの誇倧広告が単なる誇倧広告であるかどうか、たたは問題が存圚する堎合は自分でやるずいう結論。



私の堎合は、プロゞェクトPVS-Studioをただ詊しおいない堎合は詊しおみない限りです。



最高











この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいセルゲむノァシリ゚フ。 入力デヌタを凊理するずきに足で自分自身を撃぀



All Articles