Safesql V1
S
Safesql V1
由deathsaber93開發
基於Keras 3.x訓練的惡意SQL檢測模型,能識別多種SQL注入攻擊向量
下載量 41
發布時間 : 6/16/2024
模型概述
專門用於檢測惡意SQL的模型,能識別包括基於錯誤的注入、聯合查詢注入、盲注等多種SQL注入攻擊方式。
模型特點
多類型SQL注入檢測
能識別多種SQL注入攻擊向量,包括基於錯誤的注入、聯合查詢注入、盲注等7種類型
高效特徵工程
通過遞歸特徵消除篩選出10個關鍵數值特徵用於訓練,提升檢測效率
高級訓練策略
採用預熱階段和主訓練階段的雙階段學習率調整,結合特殊回調函數防止梯度爆炸
高精度檢測
基準測試顯示99.76%的準確率,誤報率僅0.03%
模型能力
SQL注入檢測
惡意SQL識別
文本分類
使用案例
網絡安全
Web應用防火牆
集成到WAF中即時檢測SQL注入攻擊
99.76%的檢測準確率
數據庫審計
監控數據庫查詢日誌中的可疑SQL語句
0.61%的漏報率
🚀 SafeSQL-v1 (在線演示)
SafeSQL-v1是一個專門用於檢測惡意SQL的Keras 3.x模型。它能檢測多種SQL注入向量,為數據庫安全保駕護航。
✨ 主要特性
- 能夠檢測多種SQL注入向量,如基於錯誤、聯合、盲注、布爾、時間、帶外和堆疊查詢等類型。
- 基於約167K條SQL數據進行訓練,惡意和良性SQL分佈近乎均勻。
- 採用特殊的預處理和特徵選擇方法,訓練過程中使用了學習率調整和梯度爆炸保護機制。
- 應用了權重和內核約束,防止過擬合,提高泛化能力。
- 使用混合精度技術,加快模型加載和推理速度。
📦 安裝指南
- 根據你的硬件情況(是否使用GPU),下載相應的
requiremnts-[cpu/gpu].txt
文件並安裝:
pip install -r requirements.txt
- 下載模型文件
sqid.keras
。
💻 使用示例
基礎用法
import re
from multiprocessing import cpu_count
from keras.src.saving import load_model
import pandas as pd
from numpy import int64
from pandarallel import pandarallel
from sklearn.preprocessing import RobustScaler
model = load_model('./sqid.keras')
pandarallel.initialize(use_memory_fs=True, nb_workers=cpu_count())
def sql_tokenize(sql_query):
sql_query = sql_query.replace('`', ' ').replace('%20', ' ').replace('=', ' = ').replace('((', ' (( ').replace(
'))', ' )) ').replace('(', ' ( ').replace(')', ' ) ').replace('||', ' || ').replace(',', '').replace(
'--', ' -- ').replace(':', ' : ').replace('%23', ' # ').replace('+', ' + ').replace('!=',
' != ') \
.replace('"', ' " ').replace('%26', ' and ').replace('$', ' $ ').replace('%28', ' ( ').replace('%2A', ' * ') \
.replace('%7C', ' | ').replace('&', ' & ').replace(']', ' ] ').replace('[', ' [ ').replace(';',
' ; ').replace(
'/*', ' /* ')
sql_reserved = {'SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'NOT', 'IN', 'LIKE', 'ORDER', 'BY', 'GROUP', 'HAVING',
'LIMIT', 'BETWEEN', 'IS', 'NULL', '%', 'LIKE', 'MIN', 'MAX', 'AS', 'UPPER', 'LOWER', 'TO_DATE',
'=', '>', '<', '>=', '<=', '!=', '<>', 'BETWEEN', 'LIKE', 'EXISTS', 'JOIN', 'UNION', 'ALL',
'ASC', 'DESC', '||', 'AVG', 'LIMIT', 'EXCEPT', 'INTERSECT', 'CASE', 'WHEN', 'THEN', 'IF',
'IF', 'ANY', 'CAST', 'CONVERT', 'COALESCE', 'NULLIF', 'INNER', 'OUTER', 'LEFT', 'RIGHT', 'FULL',
'CROSS', 'OVER', 'PARTITION', 'SUM', 'COUNT', 'WITH', 'INTERVAL', 'WINDOW', 'OVER',
'ROW_NUMBER', 'RANK',
'DENSE_RANK', 'NTILE', 'FIRST_VALUE', 'LAST_VALUE', 'LAG', 'LEAD', 'DISTINCT', 'COMMENT',
'INSERT',
'UPDATE', 'DELETED', 'MERGE', '*', 'generate_series', 'char', 'chr', 'substr', 'lpad',
'extract',
'year', 'month', 'day', 'timestamp', 'number', 'string', 'concat', 'INFORMATION_SCHEMA',
"SQLITE_MASTER", 'TABLES', 'COLUMNS', 'CUBE', 'ROLLUP', 'RECURSIVE', 'FILTER', 'EXCLUDE',
'AUTOINCREMENT', 'WITHOUT', 'ROWID', 'VIRTUAL', 'INDEXED', 'UNINDEXED', 'SERIAL',
'DO', 'RETURNING', 'ILIKE', 'ARRAY', 'ANYARRAY', 'JSONB', 'TSQUERY', 'SEQUENCE',
'SYNONYM', 'CONNECT', 'START', 'LEVEL', 'ROWNUM', 'NOCOPY', 'MINUS', 'AUTO_INCREMENT', 'BINARY',
'ENUM', 'REPLACE', 'SET', 'SHOW', 'DESCRIBE', 'USE', 'EXPLAIN', 'STORED', 'VIRTUAL', 'RLIKE',
'MD5', 'SLEEP', 'BENCHMARK', '@@VERSION', 'VERSION', '@VERSION', 'CONVERT', 'NVARCHAR', '#',
'##', 'INJECTX',
'DELAY', 'WAITFOR', 'RAND',
}
tokens = sql_query.split()
tokens = [re.sub(r"""[^*\w\s.=\-><_|()!"']""", '', token) for token in tokens]
for i, token in enumerate(tokens):
if token.strip().upper() in sql_reserved:
continue
if token.strip().isnumeric():
tokens[i] = '#NUMBER#'
elif re.match(r'^[a-zA-Z_.|][a-zA-Z0-9_.|]*$', token.strip()):
tokens[i] = '#IDENTIFIER#'
elif re.match(r'^[\d:]*$', token.strip()):
tokens[i] = '#TIMESTAMP#'
elif '%' in token.strip():
tokens[i] = ' '.join(
[j.strip() if j.strip() in ('%', "'", "'") else '#IDENTIFIER#' for j in token.strip().split('%')])
return ' '.join(tokens)
def add_features(x):
s = ["num_tables", "num_columns", "num_literals", "num_parentheses", "has_union", "depth_nested_queries", "num_join", "num_sp_chars", "has_mismatched_quotes", "has_tautology"]
x['Query'] = x['Query'].copy().parallel_apply(lambda a: sql_tokenize(a))
x['num_tables'] = x['Query'].str.lower().str.count(r'FROM\s+#IDENTIFIER#', flags=re.I)
x['num_columns'] = x['Query'].str.lower().str.count(r'SELECT\s+#IDENTIFIER#', flags=re.I)
x['num_literals'] = x['Query'].str.lower().str.count("'[^']*'", flags=re.I) + x['Query'].str.lower().str.count(
'"[^"]"', flags=re.I)
x['num_parentheses'] = x['Query'].str.lower().str.count("\\(", flags=re.I) + x['Query'].str.lower().str.count(
'\\)',
flags=re.I)
x['has_union'] = x['Query'].str.lower().str.count(" union |union all", flags=re.I) > 0
x['has_union'] = x['has_union'].astype(int64)
x['depth_nested_queries'] = x['Query'].str.lower().str.count("\\(", flags=re.I)
x['num_join'] = x['Query'].str.lower().str.count(
" join |inner join|outer join|full outer join|full inner join|cross join|left join|right join",
flags=re.I)
x['num_sp_chars'] = x['Query'].parallel_apply(lambda a: len(re.findall(r'[\'";\-*/%=><|#]', a)))
x['has_mismatched_quotes'] = x['Query'].parallel_apply(
lambda sql_query: 1 if re.search(r"'.*[^']$|\".*[^\"]$", sql_query) else 0)
x['has_tautology'] = x['Query'].parallel_apply(lambda sql_query: 1 if re.search(r"'[\s]*=[\s]*'", sql_query) else 0)
return x
input_sqls = ['SELECT roomName , RoomId FROM Rooms WHERE basePrice > 160 AND maxOccupancy > 2;', # 非惡意
"ORDER BY 1,SLEEP(5),BENCHMARK(1000000,MD5('A')),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18#", # 惡意
"; desc users; --", # 惡意
"ORDER BY 1,SLEEP(5),BENCHMARK(1000000,MD5('A')),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27", # 惡意
"SELECT DISTINCT t2.datasetid FROM paperdataset AS t3 JOIN dataset AS t2 ON t3.datasetid = t2.datasetid JOIN paperkeyphrase AS t1 ON t1.paperid = t3.paperid JOIN keyphrase AS t4 ON t1.keyphraseid = t4.keyphraseid WHERE t4.keyphrasename = ""semantic parsing"";" # 非惡意
]
numeric_features = ["num_tables", "num_columns", "num_literals", "num_parentheses", "has_union", "depth_nested_queries", "num_join", "num_sp_chars", "has_mismatched_quotes", "has_tautology"]
input_df = pd.DataFrame(input_sqls, columns=['Query'])
input_df = add_features(input_df)
scaler = RobustScaler()
x_in = scaler.fit_transform(input_df[numeric_features])
preds = model.predict([input_df['Query'], x_in]).tolist()
for i, pred in enumerate(preds):
print()
print(f'查詢語句: {input_sqls[i]}')
print(f'是否為惡意: {pred[0] >= 0.50} ({pred[0]})')
print()
# 運行基準測試
input_df = pd.read_csv('benchmark.csv')
hits = 0
data_size = input_df.shape[0]
miss_pos, miss_neg = [], []
total_negs = input_df[input_df['Label'] == 1.0].shape[0]
total_pos = input_df[input_df['Label'] == 0.0].shape[0]
pred_trans = ['良性', '惡意']
false_metrics = {0: 0, 1: 0}
x_in = scaler.transform(input_df[numeric_features])
print('正在運行基準測試')
preds = model.predict([input_df['Query'], x_in])
miss_q = []
actuals = input_df['Label'].tolist()
for i, pred in enumerate(preds):
pred = int(pred[0] > .95)
if pred == actuals[i]:
hits += 1
else:
false_metrics[int(pred)] += 1
print('基準測試完成。')
print('正在打印結果。')
acc = round((hits / data_size) * 100, 2)
f_neg = round((false_metrics[0] / total_negs) * 100, 2)
f_pos = round((false_metrics[1] / total_pos) * 100, 2)
print(f'總數據量: {data_size}')
print(f'負樣本總數: {total_negs} \t 正樣本總數: {total_pos}')
print()
print(f'命中總數: {hits}/{data_size},準確率為 {acc}%。')
print(f'假陰性: {false_metrics[0]}({f_neg}%) \t 假陽性: {false_metrics[1]}({f_pos}%)')
🔧 技術細節
- 訓練數據:使用了約167K條SQL數據,包含惡意和良性SQL,分佈近乎均勻。數據來源包括多個公開數據集,如 b-mc2/sql-create-context、philikai/Spider-SQL-LLAMA2_train 等。
- 預處理:對SQL數據進行了特殊的預處理,使用了特殊的掩碼標記。同時生成了28個額外的數值特徵,並使用遞歸特徵消除方法選擇了前10個特徵進行訓練。
- 訓練過程:訓練過程分為熱身階段和主訓練階段。熱身階段使用較小的、正弦衰減的學習率,主訓練階段使用較高的學習率和餘弦衰減。使用了特殊的回調函數來監測和防止梯度爆炸,並根據爆炸規模自動調整學習率和模型權重。
- 模型約束:應用了權重和內核約束,幫助防止過擬合,提高模型的泛化能力。
- 混合精度:使用 混合精度 技術,加快模型加載和推理速度。
📚 詳細文檔
模型元信息
屬性 | 詳情 |
---|---|
反饋郵箱 | aakash.howlader@gmail.com |
模型類型 | 語言模型 |
支持語言 | 英語 |
許可證 | Apache 2.0 |
在線演示 | SafeSQL-v1-Demo |
檢查點信息
823/823 ━━━━━━━━━━━━━━━━━━━━ 99s 120ms/step - AUPR: 0.9979 - f1_score: 0.5782 - fn: 64.0947 - fp: 8.2500 - loss: 0.0236 - precision: 0.9987 - recall: 0.9889 - val_AUPR: 0.9970 - val_f1_score: 0.5775 - val_fn: 34.0000 - val_fp: 4.0000 - val_loss: 0.0298 - val_precision: 0.9985 - val_recall: 0.9873 - learning_rate: 7.0911e-04
基準測試結果
- 總SQL數量:30919
- 總負樣本數量:11382
- 總正樣本數量:19537
- 命中總數:30844/30919,準確率為 99.76%
- 假陰性數量:69(0.61%)
- 假陽性數量:6(0.03%)
訓練數據和基準測試數據
- 訓練數據:dataset/train.csv
- 基準測試數據:dataset/benchmark.csv
📄 許可證
本模型使用 Apache 2.0 許可證。
架構圖
Distilbert Base Uncased Finetuned Sst 2 English
Apache-2.0
基於DistilBERT-base-uncased在SST-2情感分析數據集上微調的文本分類模型,準確率91.3%
文本分類 英語
D
distilbert
5.2M
746
Xlm Roberta Base Language Detection
MIT
基於XLM-RoBERTa的多語言檢測模型,支持20種語言的文本分類
文本分類
Transformers 支持多種語言

X
papluca
2.7M
333
Roberta Hate Speech Dynabench R4 Target
該模型通過動態生成數據集來改進在線仇恨檢測,專注於從最差案例中學習以提高檢測效果。
文本分類
Transformers 英語

R
facebook
2.0M
80
Bert Base Multilingual Uncased Sentiment
MIT
基於bert-base-multilingual-uncased微調的多語言情感分析模型,支持6種語言的商品評論情感分析
文本分類 支持多種語言
B
nlptown
1.8M
371
Emotion English Distilroberta Base
基於DistilRoBERTa-base微調的英文文本情感分類模型,可預測埃克曼六種基本情緒及中性類別。
文本分類
Transformers 英語

E
j-hartmann
1.1M
402
Robertuito Sentiment Analysis
基於RoBERTuito的西班牙語推文情感分析模型,支持POS(積極)/NEG(消極)/NEU(中性)三類情感分類
文本分類 西班牙語
R
pysentimiento
1.0M
88
Finbert Tone
FinBERT是一款基於金融通訊文本預訓練的BERT模型,專注於金融自然語言處理領域。finbert-tone是其微調版本,用於金融情感分析任務。
文本分類
Transformers 英語

F
yiyanghkust
998.46k
178
Roberta Base Go Emotions
MIT
基於RoBERTa-base的多標籤情感分類模型,在go_emotions數據集上訓練,支持28種情感標籤識別。
文本分類
Transformers 英語

R
SamLowe
848.12k
565
Xlm Emo T
XLM-EMO是一個基於XLM-T模型微調的多語言情感分析模型,支持19種語言,專門針對社交媒體文本的情感預測。
文本分類
Transformers 其他

X
MilaNLProc
692.30k
7
Deberta V3 Base Mnli Fever Anli
MIT
基於MultiNLI、Fever-NLI和ANLI數據集訓練的DeBERTa-v3模型,擅長零樣本分類和自然語言推理任務
文本分類
Transformers 英語

D
MoritzLaurer
613.93k
204
精選推薦AI模型
Llama 3 Typhoon V1.5x 8b Instruct
專為泰語設計的80億參數指令模型,性能媲美GPT-3.5-turbo,優化了應用場景、檢索增強生成、受限生成和推理任務
大型語言模型
Transformers 支持多種語言

L
scb10x
3,269
16
Cadet Tiny
Openrail
Cadet-Tiny是一個基於SODA數據集訓練的超小型對話模型,專為邊緣設備推理設計,體積僅為Cosmo-3B模型的2%左右。
對話系統
Transformers 英語

C
ToddGoldfarb
2,691
6
Roberta Base Chinese Extractive Qa
基於RoBERTa架構的中文抽取式問答模型,適用於從給定文本中提取答案的任務。
問答系統 中文
R
uer
2,694
98