ChatGPT を使用してコードを監査したところ、200 を超えるセキュリティ脆弱性が見つかりました (GPT-4 と GPT-3 の比較レポート)

前半では、GPT-4 を使用して一部のコードの脆弱性を監査し、後半では GPT-3 を使用して git リポジトリを比較しています。最終結果は、chatgpt でさまざまなコードを分析するための参考用です. 誤検知の問題があります, 私のトレーニングモデルの問題により除外することはできません. 誤検知の結果についてメッセージを残してください.フォローアップして、できるだけ早く対処します〜

より包括的なコンテンツを見たい場合は、まず私をフォローしてプライベート メッセージを送信してください. フィードバックに基づいて、特定のコードに関する GPT-4 のより包括的な分析レポートを書きます.

序文

    GPT-3 は、この git リポジトリで 213 のセキュリティ脆弱性を発見しました。対照的に、市場で最高の商用ツールは、99 のセキュリティ脆弱性しか検出しませんでした。商用ツールはより構造化された形式でコンテキストを提供しますが、GPT-3 によって検出された 99/213 の脆弱性のランダム サンプルを手動で確認した後、4 つは誤検知でした。コード監査では、日常的な操作として誤検知があることは誰もが知っています。

さまざまなスクリプトの脆弱性の割合の結果は次のとおりです。

60be7c5dabdd9ecb25dcf97242273f6c.png

分析された脆弱性の数の全体的な割合:

799cf5f8122faf9e42eaf115fccefa45.png

序章

    ChatGPT は近年、インターネットの新しいお気に入りになりました。サイバーセキュリティ業界は、現代の人工知能の潜在的な影響に長い間懐疑的でしたが、限られたリソースと技術的知識のないハッカーによって悪用される可能性があることを恐れて、注意を払っているようです。 .

    現在、人工知能と機械学習の分野は大きな発展を遂げており、AI ベースのコード分析という新しい可能性の分野が開かれています.AI モデルを使用してコードのセキュリティ脆弱性を検出する方法は特に重要です.

    この記事では、OpenAI の GPT-4 を使用してコードの一部を分析し、記事の最後で、GPT-3 は 129 の脆弱なファイルを含むコード リポジトリでセキュリティの脆弱性をどのように検出するかを説明します。気になる方は個別に更新していきます!

走り方

    GPT-4は、公式サイトと同じ構成でロングコードにも対応したPlus会員版を採用。(PS: PLUS メンバーとして登録する必要がある友人がいる場合は、プライベート メッセージにメッセージを残してください。ナニー レベルのチュートリアルと招待コードを提供し、割引価格で購入できます~)

    GPT-3 の亜種 (text-davinci-003) には、4000 個のトークン (およそ 3000 個の英単語) のコンテキスト ウィンドウがあります。これは、一度にコードベース全体ではなく、最大で数百行のコードの要求を処理できることを意味します。

    この問題を解決するために、GPT-3 でスキャンできるファイルは 1 つだけです。これは、GPT-3 が複数のコード ファイルの相互作用によって引き起こされたセキュリティ ホールを見つけるのが難しいことを意味します。特にソース コードで、express.js、Flask、Python 標準ライブラリ、C 標準ライブラリなどの一般的なライブラリが使用されている場合。おそらくGPT-3には関連するレコードがあります。このホワイト ペーパーで分析されたコードでは、GPT-3 はインポート ライブラリに関連するレコードを持っており、インポート ライブラリのコードをチェックすることなく、セキュリティの脆弱性を正確に検出できます。

    公平を期すために言うと、既存の商用脆弱性スキャン ツールの多くは、静的分析を行う際にインポートされたライブラリのコードを実際には検査しないので、市場に出回っている一部のツールの動作とあまり変わらないと思います。

    分析されたコード リポジトリ内の各フォルダーは、セキュリティの脆弱性の種類にちなんで名付けられ、1 つ以上の脆弱性を含むサンプル コードを含むファイルが含まれています。これらのファイルの一部には些細なコードが含まれていますが、多くは本番環境のコードベースで遭遇する可能性のある同じコード スニペットです (注: これらはまだスニペットであるため、より大きなコードベースのコンテキストが欠けています)。リポジトリ内の各フォルダーの README.md には、そのフォルダー内のすべてのファイルに対する GPT-3 のセキュリティ脆弱性の分析が含まれています。

使用された脆弱なコードベース:

https://github.com/chris-koch-penn/gpt3_security_vulnerability_scanner

最初にGPT-4解析を使用しましたが、次のコードをGPT-3と比較します。

1》コードインジェクションの脆弱性検知

PHP コード スニペット 1 (tarlogic-ex2.php):

26cf07519468b67722871bf308fadf1c.png

試験結果:

このコードには抜け穴があります。つまり、PHP の unserialize 機能を介してリモート コード実行を実現できます。具体的な理由は次のとおりです。

  1. コードでは、エントリ クラスの __destruct() メソッドが $this->awesome->flag() を呼び出していることがわかります。PHP オブジェクトが破棄されると、__destruct() メソッドが自動的に実行されます。

  2. unserialize() 関数はコードの最後で使用され、シリアル化された文字列を PHP 値に変換します。この例では、ユーザーはコマンド ライン引数を介してシリアル化された文字列を入力できます。

  3. シリアライズされた文字列を構築することにより、攻撃者はエントリ クラスのインスタンスを作成し、その素晴らしいプロパティを GiveFlag クラスのインスタンスにポイントすることができます。このように、entry クラスのインスタンスが破棄されると、__destruct() メソッドは GiveFlag クラスの flag() メソッドを実行し、次に GiveFlag クラスの innocent() メソッドを実行します。GiveFlag クラスの innocent() メソッドは、「flag.txt」ファイルを開き、その内容を読み取ります。これにより、攻撃者は、悪意を持って作成されたシリアル化された文字列を入力してコード実行をトリガーし、「flag.txt」ファイルの内容を取得できます。

この脆弱性を修正するには、次の点を考慮することができます。

信頼できないデータで unserialize() 関数を使用しないでください。JSON などの他の方法を使用して、データを転送および解析できます。

__destruct() などの潜在的に危険なマジック メソッドには特に注意してください。これらの方法を使用する場合は、セキュリティ リスクが発生しないように注意してください。

結果はまだ非常に詳細です。

2" Flask デシリアライゼーションの脆弱性

Python コード (pickle2.py):

長いコードを分析する GPT-4 の機能:

from __future__ import unicode_literals
from flask import Flask, request, make_response, redirect, url_for, session
from flask import render_template, flash, redirect, url_for, request
from werkzeug.security import safe_str_cmp
from base64 import b64decode as b64d
from base64 import b64encode as b64e
from hashlib import sha256
from cStringIO import StringIO
import random
import string


import os
import sys
import subprocess
import commands
import pickle
import cPickle
import marshal
import os.path
import filecmp
import glob
import linecache
import shutil
import dircache
import io
import timeit
import popen2
import code
import codeop
import pty
import posixfile


SECRET_KEY = 'you will never guess'


if not os.path.exists('.secret'):
    with open(".secret", "w") as f:
        secret = ''.join(random.choice(string.ascii_letters + string.digits)
                         for x in range(4))
        f.write(secret)
with open(".secret", "r") as f:
    cookie_secret = f.read().strip()


app = Flask(__name__)
app.config.from_object(__name__)


black_type_list = [eval, execfile, compile, open, file, os.system, os.popen, os.popen2, os.popen3, os.popen4, os.fdopen, os.tmpfile, os.fchmod, os.fchown, os.open, os.openpty, os.read, os.pipe, os.chdir, os.fchdir, os.chroot, os.chmod, os.chown, os.link, os.lchown, os.listdir, os.lstat, os.mkfifo, os.mknod, os.access, os.mkdir, os.makedirs, os.readlink, os.remove, os.removedirs, os.rename, os.renames, os.rmdir, os.tempnam, os.tmpnam, os.unlink, os.walk, os.execl, os.execle, os.execlp, os.execv, os.execve, os.dup, os.dup2, os.execvp, os.execvpe, os.fork, os.forkpty, os.kill, os.spawnl, os.spawnle, os.spawnlp, os.spawnlpe,
                   os.spawnv, os.spawnve, os.spawnvp, os.spawnvpe, pickle.load, pickle.loads, cPickle.load, cPickle.loads, subprocess.call, subprocess.check_call, subprocess.check_output, subprocess.Popen, commands.getstatusoutput, commands.getoutput, commands.getstatus, glob.glob, linecache.getline, shutil.copyfileobj, shutil.copyfile, shutil.copy, shutil.copy2, shutil.move, shutil.make_archive, dircache.listdir, dircache.opendir, io.open, popen2.popen2, popen2.popen3, popen2.popen4, timeit.timeit, timeit.repeat, sys.call_tracing, code.interact, code.compile_command, codeop.compile_command, pty.spawn, posixfile.open, posixfile.fileopen]




@app.before_request
def count():
    session['cnt'] = 0




@app.route('/')
def home():
    remembered_str = 'Hello, here\'s what we remember for you. And you can change, delete or extend it.'
    new_str = 'Hello fellow zombie, have you found a tasty brain and want to remember where? Go right here and enter it:'
    location = getlocation()
    if location == False:
        return redirect(url_for("clear"))
    return render_template('index.html', txt=remembered_str, location=location)




@app.route('/clear')
def clear():
    flash("Reminder cleared!")
    response = redirect(url_for('home'))
    response.set_cookie('location', max_age=0)
    return response




@app.route('/reminder', methods=['POST', 'GET'])
def reminder():
    if request.method == 'POST':
        location = request.form["reminder"]
        if location == '':
            flash("Message cleared, tell us when you have found more brains.")
        else:
            flash("We will remember where you find your brains.")
        location = b64e(pickle.dumps(location))
        cookie = make_cookie(location, cookie_secret)
        response = redirect(url_for('home'))
        response.set_cookie('location', cookie)
        return response
    location = getlocation()
    if location == False:
        return redirect(url_for("clear"))
    return render_template('reminder.html')




class FilterException(Exception):
    def __init__(self, value):
        super(FilterException, self).__init__(
            'The callable object {value} is not allowed'.format(value=str(value)))




class TimesException(Exception):
    def __init__(self):
        super(TimesException, self).__init__(
            'Call func too many times!')




def _hook_call(func):
    def wrapper(*args, **kwargs):
        session['cnt'] += 1
        print session['cnt']
        print args[0].stack
        for i in args[0].stack:
            if i in black_type_list:
                raise FilterException(args[0].stack[-2])
            if session['cnt'] > 4:
                raise TimesException()
        return func(*args, **kwargs)
    return wrapper




def loads(strs):
    reload(pickle)
    files = StringIO(strs)
    unpkler = pickle.Unpickler(files)
    unpkler.dispatch[pickle.REDUCE] = _hook_call(
        unpkler.dispatch[pickle.REDUCE])
    return unpkler.load()




def getlocation():
    cookie = request.cookies.get('location')
    if not cookie:
        return ''
    (digest, location) = cookie.split("!")
    if not safe_str_cmp(calc_digest(location, cookie_secret), digest):
        flash("Hey! This is not a valid cookie! Leave me alone.")
        return False
    location = loads(b64d(location))
    return location




def make_cookie(location, secret):
    return "%s!%s" % (calc_digest(location, secret), location)




def calc_digest(location, secret):
    return sha256("%s%s" % (location, secret)).hexdigest()




if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5051)

試験結果:

    この Python コードは、Flask フレームワークを使用して、ユーザーがリマインダーを設定、取得、および削除できる Web アプリケーションを実装します。ただし、コードにはいくつかのセキュリティ上の問題があります。

    このコードは、Python の pickle モジュールを使用して、ユーザーが入力したデータをシリアライズおよびデシリアライズします。1. Pickle には既知のセキュリティ リスクがあり、特に信頼できないデータを扱う場合に顕著です。攻撃者は、悪意のある pickle データを作成することにより、任意のコードを実行する可能性があります。pickle.loads() をある程度のセキュリティで制御するためにコード内で _hook_call() 関数が使用されていますが、それでも絶対的なセキュリティを保証することはできません。JSON などのより安全な代替手段をお勧めします。

2. SECRET_KEY という名前の静的キーがコードで使用されているため、セキュリティ上のリスクが生じる可能性があります。セキュリティを強化するには、より強力なキー生成戦略を使用し、キーを定期的に変更することを検討してください。

3. ダイジェスト計算に sha256 を使用する 現時点で安全でないことは証明されていませんが、セキュリティを向上させるために、bcrypt などのより安全なハッシュ アルゴリズムの使用を検討できます。

4. eval、execfile、os.system などの安全でない関数を使用します。これらの危険な関数の使用を制限するためにコード内で black_type_list が定義されていますが、実際の開発では、潜在的なセキュリティ リスクを伴うこれらの関数の使用を避けるようにしてください。

5. このコードは、app.run() でホストを「0.0.0.0」に設定します。これは、アプリが利用可能なすべてのネットワーク インターフェイスでリッスンすることを意味します。本番環境では、これにより潜在的なセキュリティの問題が発生する可能性があります。開発環境でのみ「0.0.0.0」を使用することをお勧めします。本番環境では特定の IP アドレスまたはドメイン名を使用する必要があります。

要約すると、このコードには特定のセキュリティ リスクがあります。実際のアプリケーションでは、これらの問題を修正し、HTTPS 接続、アクセス制御など、セキュリティの他の側面に注意を払う必要があります。

与えられたアナリストは GPT-3.5 よりもはるかに包括的であり、GPT-3.5 の結果を比較することができます。

3 "コマンド インジェクションの脆弱性の検出

PHP コード 2:

<?php
$rootUname = $_GET['rootUname'];
$array = array();
/* check PHP Safe_Mode is off /
if (ini_get('safe_mode')) {
$array['phpSafeMode'] = '<strong><font class="bad">Fail - php safe mode is on - turn it off before you proceed with the installation</strong></font>br/>';
} else {
$array['phpSafeMode'] = '<strong><font class="Good">Pass - php safe mode is off</strong></font><br/>';
}
/ Test root account details */
$rootTestCmd1 = 'sudo -S -u ' . $rootUname . ' chmod 0777 /home 2>&1';
exec($rootTestCmd1, $cmdOutput, $err);
$homeDirPerms = substr(sprintf('%o', fileperms('/home')), -4);
if ($homeDirPerms == '0777') {
$array['rootDetails'] = '<strong><font class="Good">Pass - root account details are good </strong></font><br/>';
} else {
$array['rootDetails'] = '<strong><font class="bad">The root details provided have not passed: ' . $cmdOutput[0] . '</strong></font><br/>';
}
// reset /home dir permissions
$rootTestCmd2 = 'sudo -S -u ' . $rootUname . ' chmod 0755 /home 2>&1';
exec($rootTestCmd2, $cmdOutput, $err);
echo json_encode($array);

分析結果:

この PHP コードには、特定のセキュリティ リスクがあります。

  1. $_GET メソッドは、フィルター処理や検証を行わずに、ユーザー入力パラメーター rootUname を直接受け取るために使用されます。これにより、インジェクション攻撃などのセキュリティの問題が発生する可能性があります。ユーザー入力を安全に処理するために、filter_input() などの入力検証およびフィルタリング関数を使用することをお勧めします。

  2. このコードは、ユーザーから提供された rootUname を直接使用して、コマンド ラインを構築および実行します。これは、コマンド インジェクション攻撃につながる可能性があります。攻撃者は rootUname に悪意のあるコマンドを挿入し、サーバーにセキュリティ上の問題を引き起こす可能性があります。コマンド インジェクションを防ぐために、PHP の escapeshellarg() 関数を使用してパラメーターをエスケープするなど、パラメーター バインドを使用してコマンドを実行することをお勧めします。

  3. このコードは、exec() 関数を介してシステム コマンドを実行するため、特定のセキュリティ リスクにつながる可能性があります。実際の開発では、セキュリティ上のリスクを引き起こす可能性のあるこのような関数を使用しないようにしてください。使用する必要がある場合は、入力パラメーターの厳密な検証とフィルタリングを行う必要があります。

  4. コードはエラー情報を直接出力するため、サーバーの機密情報が公開される可能性があります。本番環境では、詳細なエラー メッセージをユーザーに直接出力しないように、エラー メッセージを処理することをお勧めします。

要約すると、このコードはセキュリティ リスクです。実際のアプリケーションでは、これらの問題を修正し、HTTPS 接続、アクセス制御など、セキュリティの他の側面に注意を払う必要があります。

4》XML 外部エンティティ インジェクション (XXE) 攻撃の脆弱性検出
PHP コード 3:

<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$info = simplexml_import_dom($dom);
$name = $info->name;
$tel = $info->tel;
$email = $info->email;
$password = $info->password;


echo "Sorry, $email is already registered!";
?>

分析結果:

このコードのセキュリティ上の問題の 1 つは、XML 外部エンティティ (XXE) インジェクション攻撃のリスクです。問題は、外部エンティティの解決を可能にする libxml_disable_entity_loader(false) 関数にあります。攻撃者は、サーバー上の機密ファイルを読み取ったり、悪意のある XML 入力を作成してネットワーク攻撃を開始したりできます。

この問題を解決するには、外部エンティティの読み込みを無効にして XXE 攻撃を防ぎ、コードで libxml_disable_entity_loader(false) を libxml_disable_entity_loader(true) に変更します。

また、セキュリティ上の問題が発生する可能性があるため、LIBXML_NOENT および LIBXML_DTDLOAD オプションは注意して使用してください。

さらに、このコードはユーザー入力の検証とエスケープを行わないため、クロスサイト スクリプティング (XSS) などの他のセキュリティ問題が発生する可能性があります。したがって、ユーザー入力を処理するときは、効果的に検証してエスケープするようにしてください。

5" XML 外部エンティティ インジェクション (XXE) 攻撃の脆弱性検出

このコードは比較的長いです。コード ベースの XmlReader_Tests.cs を参照してください。GPT-4 は長いスクリプトを処理できます。ロングトークンの特徴があります。コードの長さを示すスクリーンショットを撮ります。

8e694409433c4c76d0264fb2f9446be0.png

分析結果:

このテスト コードには、XmlReaderSettings と XmlReader をそれぞれ使用して XML ドキュメントの解析をテストする 3 つのテスト ケースが含まれています。1つずつ分析します。

  1. XMLReader_WithDTDProcessingParseAndXmlResolverSet_NotSafe(): このテスト ケースでは、XML パーサーが安全に設定されていません。DtdProcessing.Parse を使用するとドキュメント タイプ定義 (DTD) を解析できますが、XmlResolver は XmlUrlResolver であり、外部エンティティを解析できることを意味します。これは、XML 外部エンティティ (XXE) インジェクション攻撃につながる可能性があります。

  2. XMLReader_WithDTDProcessingIgnored_Safe(): このテスト ケースでは、XML パーサーの設定は比較的安全です。DtdProcessing を DtdProcessing.Ignore に設定すると、パーサーは DTD を無視し、XXE 攻撃を回避します。ただし、xmlDocument.XmlResolver がまだ XmlUrlResolver に設定されていることに注意してください。このテスト ケースではセキュリティ上の問題は発生しませんが、実際の使用では、潜在的なセキュリティ リスクを回避するために XmlResolver を null に設定することをお勧めします。

  3. XMLReader_WithDTDProcessingProhibited_Safe(): このテスト ケースでは、XML パーサーの設定は安全です。DtdProcessing.Prohibit は、DTD の解析を禁止し、XXE 攻撃を効果的に防ぎます。しかし、前のテスト ケースと同様に、

GPT-4 の監査機能の概要:

GPT-4 は、コード監査中に次の機能を示します。

  1. 鋭いセキュリティ意識: コードを監査するとき、コード内の潜在的なセキュリティ リスクをすばやく発見し、これらの問題をタイムリーに指摘できます。

  2. 総合的な分析力: コードを分析する際に、入力の検証から機密情報の開示などの分析まで、さまざまなセキュリティの問題を総合的に考慮することができます。

  3. 動的デバッグとシミュレートされた実行: コード実行プロセスをシミュレートすることで、コード ロジックをより深く理解し、潜在的なセキュリティ リスクを発見することができます。

  4. 的を絞った解決策: 問題を発見した後、特定の解決策を提供してコードのセキュリティを向上させることができます。

  5. 継続的な学習と適応: ネットワーク セキュリティ分野の継続的な開発により、さまざまなコードのセキュリティ分析機能をより適切に処理するために、新しい知識とテクノロジを継続的に学習することができます。

コード監査プロセス中に、彼は強力なセキュリティ認識と分析能力を発揮し、動的デバッグとシミュレートされた実行を通じてコード ロジックをより深く理解しました。ただし、セキュリティ監査は複雑で進行中のプロセスであり、継続的な学習と改善が必要です。

以下は、GPT-3 解析コードの結果です。

例 1:

フォーマット文字列攻撃に対して脆弱な単純な C プログラムを次に示します。

`#include <stdio.h>`
`int main(int argc, char **argv) {`
`printf(argv[1]);`
`return 0;`
`}`

検出された脆弱性:

1. 検証されていないユーザー入力: プログラムはユーザー入力の長さをチェックしないため、バッファー オーバーフロー攻撃につながる可能性があります。

2. フォーマット文字列の脆弱性: プログラムはユーザー入力のフォーマットをチェックしないため、フォーマット文字列攻撃につながる可能性があります。

例 2:

Log Forging の脆弱性を含むこの C# プログラムなど、高水準言語で書かれたそれほど単純ではないプログラムでこれを試してみましょう。私は個人的に、オープン ソース プロジェクトと製品コードベースで同様の (それほど重要ではありませんが) コードを見てきました。

`using Microsoft.AspNetCore.Http;`
`using Microsoft.AspNetCore.Mvc;`
`using Microsoft.Extensions.Logging;`
`using System;`
`using System.Collections.Generic;`
`using System.Linq;`
`using System.Threading.Tasks;`
`namespace WebFox.Controllers`
``
`[Route("api/[controller]")]`
`[ApiController]`
`public class LogInjection : ControllerBase`
`{`
`private readonly ILogger<LogInjection> _logger;`
`public LogInjection(ILogger<LogInjection> logger)`
`{`
`_logger = logger;`
`}`
`[HttpGet("{userInfo}")]`
`public void injectLog(string userInfo)`
`{`
`_logger.LogError("error!! " + userInfo);`
`}`
`}`
`}`

検出された脆弱性:

  1. ログ インジェクションの脆弱性: ユーザー入力が無害化されずにログに記録されるため、コードはログ インジェクション攻撃に対して脆弱です。

例 3:

次の C プログラムは、イメージの読み取りと操作を行います。範囲外の読み取りと書き込みを含む、多くのセキュリティ ホールが含まれています。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Image
{
    char header[4];
    int width;
    int height;
    char data[10];
};
int ProcessImage(char* filename){
    FILE *fp;
    char ch;
    struct Image img;
    fp = fopen(filename,"r"); 
    if(fp == NULL)
    {
        printf("\nCan't open file or file doesn't exist.");
        exit(0);
    }


    printf("\n\tHeader\twidth\theight\tdata\t\r\n");
    while(fread(&img,sizeof(img),1,fp)>0){
        printf("\n\t%s\t%d\t%d\t%s\r\n",img.header,img.width,img.height,img.data);
        int size1 = img.width + img.height;
        char* buff1=(char*)malloc(size1);
        memcpy(buff1,img.data,sizeof(img.data));
        free(buff1);
        if (size1/2==0){
            free(buff1);
        }
        else{
            if(size1 == 123456){
                buff1[0]='a';
            }
        }
        int size2 = img.width - img.height+100;
        //printf("Size1:%d",size1);
        char* buff2=(char*)malloc(size2);
        memcpy(buff2,img.data,sizeof(img.data));
        int size3= img.width/img.height;
        //printf("Size2:%d",size3);
        char buff3[10];
        char* buff4 =(char*)malloc(size3);
        memcpy(buff4,img.data,sizeof(img.data));
        char OOBR_stack = buff3[size3+100];
        char OOBR_heap = buff4[100];
        buff3[size3+100]='c';
        buff4[100]='c';
        if(size3>10){
                buff4=0;
        }
        else{
            free(buff4);
        }


        free(buff2);
    }
    fclose(fp);
}


int main(int argc,char **argv)
{
    ProcessImage(argv[1]);
}

検出された脆弱性:

1. 戻り値がチェックされていない: fopen() 関数の戻り値がチェックされていないため、null ポインターの逆参照が発生する可能性があります。

2. 範囲外の読み取り: memcpy() 関数を使用して、データを img.data から buff1 および buff2 にコピーしますが、宛先バッファーのサイズをチェックしないため、範囲外の読み取りが発生する可能性があります。

3. 範囲外書き込み: buff3 および buff4 配列の書き込みでは、ソース バッファーのサイズがチェックされないため、範囲外書き込みが発生する可能性があります。

4. 初期化されていないメモリーアクセス: OOBR*スタックおよび OOBR *

初期化されていない状態でヒープ変数にアクセスすると、未定義の動作が発生する可能性があります。

5. メモリ リーク: size3 変数が 10 より大きい場合、buff4 配列が解放されず、メモリ リークが発生する可能性があります。

GPT-3 は 5 つのうち 4 つが正しいです。脆弱性 1 は、fopen()の値が行でチェックされているため、誤検知ですif(fp == NULL)また、脆弱性 4 の文言は誤解を招きます。コード行で 2 つの未初期化メモリ アクセス エラーを参照するのは正しいですが、間違った変数名を指しています。

例 4:

最後の Java の例は私のお気に入りです。残念ながら、このコードを最初に読んだときは、何も問題がなかったからです。私には、それは完全に無害で見慣れたものに見えます - 私は実際に同様のコードを見たことがありますが、考え直すことはありませんでした.

class Utils
{
    // Function to serialize an object and write it to a file
    public static void SerializeToFile(Object obj, String filename)
    {
        try
        {
            FileOutputStream file = new FileOutputStream(filename);
            ObjectOutputStream out = new ObjectOutputStream(file);


            // Serialization of the object to file
            System.out.println("Serializing " + obj.toString() + " to " + filename);
            out.writeObject(obj);


            out.close();
            file.close();
        }
        catch(Exception e)
        {
            System.out.println("Exception: " + e.toString());
        }
    }


    // Function to deserialize an object from a file
    public static Object DeserializeFromFile(String filename)
    {
        Object obj = new Object();


        try
        {
            FileInputStream file = new FileInputStream(filename);
            ObjectInputStream in = new ObjectInputStream(file);


            // Deserialization of the object to file
            System.out.println("Deserializing from " + filename);
            obj = in.readObject();


            in.close();
            file.close();
        }
        catch(Exception e)
        {
            System.out.println("Exception: " + e.toString());
        }


        return obj;
    }

検出された脆弱性:

1. 安全でない逆シリアル化: 信頼されていないデータを逆シリアル化すると、リモートでコードが実行される可能性があります。

2. 安全でないファイル許可: 書き込みまたは読み取り中のファイルの許可が安全でない可能性があり、許可されていないアクセスが許可されます。

サイバーセキュリティにおける究極の「シフトレフト」

    シフト レフトとは、コードを運用環境にデプロイする前にセキュリティの脆弱性をテストするなど、開発プロセスの早い段階でセキュリティ プラクティスを適用するプロセスです。

    セキュリティのベスト プラクティスを適用し、開発者がコードを書いてコミットする際にサイバーセキュリティについて教育することにより、AI コード分析は、サイバーセキュリティにおける究極のシフトレフトを表すことができます。これにより、組織内で強力なサイバーセキュリティ文化が育まれ、次の大規模なハッキングを防ぐことさえできますが…

確かに、このテクノロジは完璧ではなく、経験豊富なサイバーセキュリティの専門家が監査を行う際に見逃すことのないいくつかの点が見落とされています。それでも、汎用の大規模言語モデルとしては驚くほど優れており、他の選択肢よりもはるかに安価です。

GPT-4 のリリース日は現在のところありませんが、これらの大規模な言語モデルは、機能が増えるにつれて進化し続けると思います。

誤検知の例

    GPT-3 によって検出された 213 の脆弱性のうち約 60 を手動で調べたところ、注目すべき誤検知の 1 つがこの Javascript プログラムの 13 行目にあることがわかりました。

var express = require('express');
var cookieParser = require('cookie-parser');
var escape = require('escape-html');
var serialize = require('node-serialize');
var app = express();
app.use(cookieParser())


app.get('/', function(req, res) {
 if (req.cookies.profile) {
   var str = new Buffer(req.cookies.profile, 'base64').toString();
   var obj = serialize.unserialize(str);
   if (obj.username) {
     res.send("Hello " + escape(obj.username)); // <--- GPT-3 makes a mistake here
   }
 } else {
     res.cookie('profile', "eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5IjoiYmFuZ2Fsb3JlIn0=", {
       maxAge: 900000,
       httpOnly: true
     });
 }
 res.send("Hello World");
});
app.listen(3000);

検出された脆弱性:

  • 安全でない Cookie の設定 (安全なフラグが設定されていません)

  • 検証されていないユーザー入力の逆シリアル化 (Cookie)

  • エスケープされていないユーザー入力 (ユーザー名) による潜在的な XSS 脆弱性

obj.usernameGPT-3 は最初の 2 つのバグについては正しかったが、 3番目のバグは誤検出だった。

結果:

実験結果によると、GPT-3 はスキャンされた 129 個のファイルのうち 85 個でセキュリティの脆弱性を検出できることが示されています。その能力は、コード監査の専門家に劣りません!

ee00517a5f5af645345e04e72e32a651.png

{name:'.php', value:50}, {name:'.js', value:20}, {name:'.cs', value:16}, {name:'.c', value:14 }, {名前:'.java', 値:9}, {名前:'.py', 値:8}, {名前:'.rb', 値:5}, {名前:'.asp', 値:3}、{名前:'.ts'、値:2}、{名前:'.go'、値:1}、{名前:'.html'、値:1}

052e8c7b346c8aa84e7f62723c151a57.png

{name:'脆弱性が見つかりました', 値:73}, {name:'脆弱性が見つかりません', 値:43}, {name:'脆弱性が見つかりました', 値:6}, {name:'回答', 値: 2 }, {name:'潜在的な脆弱性', 値:2}, {name:'分析', 値:1}, {name:'セキュリティの脆弱性', 値:1}, {name:'回答なし', 値:1}

asp、php、java、c、js、csなどのスクリプトの解析結果については、記事冒頭のコードライブラリを参照してください。

要約する

    この記事では、ChatGPT を使用してコードを監査するプロセスと結果について説明します。著者は GPT-3 を使用して 213 のセキュリティ脆弱性を検出し、そのうち 85 は正しく検出されました。GPT-3 の誤検知率は比較的低いですが、誤って報告されたり過小報告されている脆弱性がまだいくつかあります。著者は、GPT-3 を補助ツールとして使用してセキュリティの脆弱性を発見できると考えていますが、手動監査を完全に置き換えることはできません。

GTP-4はロングコードも扱えるので、コードをカットする必要がなく、余計なガイドも必要ありません。コード監査プロセス中に、彼は強力なセキュリティ認識と分析能力を発揮し、動的デバッグとシミュレートされた実行を通じてコード ロジックをより深く理解しました。GPT-3 よりはるかに強力ですが、まだ先は長いです。

おすすめ

転載: blog.csdn.net/FL63Zv9Zou86950w/article/details/130097606