1. 程式人生 > >API驗證插件

API驗證插件

安全 key 時間限制 ack pda 依然 服務 超時 strong

前言

如果在訪問某WebAPI過程中request信息被他人截獲,若是get請求獲取數據還好,如果是post提交數據,勢必威脅數據安全,所以對於一個對安全性要求較高的API來說,對每個請求做身份驗證顯得尤為重要;

防範策略解析

策略1

客戶端發送http請求訪問API時,在請求頭裏設置一個雙方約定好的key;

知識點:

1、如果給Django程序發送請求頭,headers攜帶內容包含下滑杠 _,Django會不認識;

2、客戶端 auth-api ----->服務端 轉換成 ‘HTTP_AUTH_API‘格式

3、服務端獲取clent_key=request.META.get(‘HTTP_AUTH_API‘)

客戶端

技術分享
import  requests
key=sssdkjrjefjewfakfhkj
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:key}).text
#如果給Django程序發送請求頭,如果headers裏面的內容使用下滑杠 _,Django會不認識;
#auth-api  -----> 轉換成 ‘HTTP_AUTH_API‘格式
#服務端獲取clent_key=request.META.get(‘HTTP_AUTH_API‘)
print(respose)
View Code

服務端

技術分享
def test(request):
    key=sssdkjrjefjewfakfhkj
    clent_key=request.META.get(HTTP_AUTH_API)
    if clent_key == key:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

漏洞:雖然雙方約定好了key,但是請求頭依然會被截獲到;

策略2

1.key+當前客戶端時間戳 組成1個MD5加密字符串

2.MD5加密字符串|當前時間戳 組成1串密碼,hearder攜帶

3.服務端接收到客戶端發送的那1串密碼,split 出客戶端時間

4.來著客戶端時間+服務端key做MD5加密還原,對比客戶端和服務端

客戶端

技術分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字節類型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 時間戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和時間戳加密後的結果)| 時間戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)
View Code

服務端

技術分享
import hashlib
import time

def MD5(arg):
    hs = hashlib.md5()
    hs.update(arg.encode(utf-8))  # python3加密使用字節類型
    return hs.hexdigest()

def test(request):
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    server_md5_str=MD5(%s|%s%(key,client_ctime))

    if client_md5_str== server_md5_str:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

漏洞:折騰了半天雖然可以動態加密,但依然可以獲取到,且客戶端會生成很多加密字符串,黑客獲取任意一個都可以訪問到API

策略3

1.key+當前客戶端時間戳 組成1個MD5加密字符串

2.MD5加密字符串|當前時間戳 組成1串密碼,hearder攜帶

3.服務端接收到客戶端發送的那1串密碼,split 出客戶端時間

4.來著客戶端時間+服務端key做MD5加密還原,對比客戶端和服務端是否相等

5.動態密碼有時間限制,超過5秒失效

客戶端

技術分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字節類型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 時間戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和時間戳加密後的結果)| 時間戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)
View Code

服務端

技術分享
def test(request):
    server_float_ctime=time.time()
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    client_float_ctime=float(client_ctime)

    if client_float_ctime+5 < server_float_ctime:
        return HttpResponse(想要破解密碼最在5秒之內)

    server_md5_str = MD5(%s|%s % (key, client_ctime))
    if client_md5_str== server_md5_str:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

漏洞:雖然加密字符串有了時間限制,但時間就是漏洞

策略4

1.key+當前客戶端時間戳 組成1個MD5加密字符串

2.MD5加密字符串|當前時間戳 組成1串密碼,hearder攜帶

3.服務端接收到客戶端發送的那1串密碼,split 出客戶端時間

4.來著客戶端時間+服務端key做MD5加密還原,對比客戶端和服務端是否相等

5.動態+加密字符串+時間限制,超過5秒失效

6.記錄最近5秒訪問客戶端的加密字符串,如果當前客戶端使用的字符串存在記錄中,說明是竊取(因為正常用戶每次,訪問API會攜帶不同的加密字符串)

客戶端

技術分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字節類型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 時間戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和時間戳加密後的結果)| 時間戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)




#如果給Django程序發送請求頭,如果headers裏面的內容使用下滑杠 _,Django會不認識;
#auth-api  -----> 轉換成 ‘HTTP_AUTH_API‘格式
#服務端獲取clent_key=request.META.get(‘HTTP_AUTH_API‘)
View Code

服務端

技術分享
import hashlib
import time

def MD5(arg):
    hs = hashlib.md5()
    hs.update(arg.encode(utf-8))  # python3加密使用字節類型
    return hs.hexdigest()
visited_keys={} #使用memcached redis 超時時間5秒
def test(request):
    server_float_ctime=time.time()
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    client_float_ctime=float(client_ctime)
    #第1關時間限制
    if client_float_ctime+5 < server_float_ctime:
        return HttpResponse(想要破解密碼最在5秒之內)
    #第二關 MD5加密
    server_md5_str = MD5(%s|%s % (key, client_ctime))
    if client_md5_str != server_md5_str:
        return HttpResponse(休想)
    #第三關
    if visited_keys.get(client_md5_str):
        return HttpResponse(你放棄吧)
    visited_keys[client_md5_str]=client_float_ctime
    return HttpResponse(OK)
View Code

漏洞:待各位看官補充。。。。

API驗證插件