api-fuzz
api-fuzz copied to clipboard
python restful api fuzz test
IntelliFuzzTest cli æµè¯å·¥å ·
å®è£
git clone https://github.com/smasterfree/api-fuzz.git
pip install -r requirements.txt
å¿«éå¼å§
å°curl 请æ±ä½æ¾è¿ request.txt æä»¶ä¸ï¼æ§è¡å½ä»¤
python IntelliFuzzTest_cli.py request.txt
ç¹ç¹
- æ¯æè¯·æ±bodyä½åå¼
- æ¯æè¯·æ±url path åå¼
- éæºå¢å 请æ±header
- æ¯æpost/get/delete/putæ¹æ³
- å¯ä»¥ç´æ¥æ ¹æ®curlå½ä»¤è¿è¡åå¼
èæ¯
卿¥å¸¸æµè¯å·¥ä½ä¸ï¼ç»å¸¸ä¼æapiæ¥å£çæµè¯ï¼é¤äºæ£åæµç¨çæµè¯ä¹å¤ï¼æä»¬ç»å¸¸è¿éè¦è¦çä¸äºå¼å¸¸æ åµã
ä¾å¦ï¼
- ä¸åæ³å符串
- åç¬¦ä¸²è¶ é¿
- åºè¯¥æ¯æ°åç±»åçï¼ä¼ å ¥äºåæ¯
- åæ°ä¸ºç©º
- ä¼ å ¥äºä¸æï¼æ ç¹ç¬¦å·ç
- sqlæ³¨å ¥çç
äºå®ä¸ï¼æä»¬ç»çæ¥å£æµè¯demoæ¡æ¶ä¸ï¼å¨dataproviderä¸ä¹ç»å¸¸è½å¤çå°è¯¸å¦ä¸é¢çä¾åã
@DataProvider(name = "testIllegalName")
public static Object[][] testIllegalName(){
return new Object[][]{
//name
{null, 400, "åå为空æè
ååéæ³"},
{"", 400, "åå为空æè
ååéæ³"},
{"abcdefghijilmnopqrstu", 400, "åå为空æè
ååéæ³"},
{" ", 400, "åå为空æè
ååéæ³"},
{"12", 400, "åå为空æè
ååéæ³"},
{"-12", 400, "åå为空æè
ååéæ³"},
{"0.2", 400, "åå为空æè
ååéæ³"},
{"abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcd.com", 400, "åå为空æè
ååéæ³"},
{"zxq.qa.com", 400, "åå为空æè
ååéæ³"},
{"zxq_qa.com", 400, "åå为空æè
ååéæ³"},
};
}
æ¤å¤æ¯ççæ¥å£å¨ä¼ å ¥éææå¼çæ¶åï¼è½ä¸è½å¤å¾å¥½çå¤ç类似请æ±ã
餿¤ä»¥å¤ï¼è¿æä¸äºåä¸å¡åºæ¯å¼ºç¸å ³çå¼ç±»åï¼æ¯å¦ç½ç»æµè¯çæ¶åï¼æä»¬ä¼å ³å¿cidrçæ ¼å¼ï¼è®¡è´¹æµè¯çæ¶åï¼åç¹å«å ³æ³¨æ°åçç±»åã
䏿¹é¢ï¼ç»æ¯ä¸ªæ¥å£å¢å 类似çå¼å¸¸æ¥å£æµè¯ç¸å¯¹æ¯è¾æ è¶£ï¼å¦ä¸æ¹é¢ï¼æä»¬ä½ä¸ºäººï¼èèé®é¢ï¼ä¸ç®¡æ¯å¼åè¿æ¯æµè¯ï¼é½é¾å æä¸æ¼ä¸ï¼æä¸äºè¾¹è¾¹è§è§çcase没è½èèå°ã
æ¢ç¶å¦æ¤ï¼æä»¬è½å¦ç»ä¸æ½è±¡åºæ¥ä¸ç§æ¥å£å¼å¸¸æµè¯çæ¡æ¶ï¼èªå¨ æ³¨å ¥åç§ç±»åçå¼å¸¸ï¼ç¶åå°å¡æ¯æå¡æ²¡ææè·çï¼æåºtrace, exception çï¼è®°å½ä¸è¯·æ±çpayloadï¼ä¸ºåç»éªè¯è¦çæä¾æ¯æã
åç
主è¦ä½¿ç¨äºæ¨¡ç³æµè¯ææ¯ï¼fuzz testing, fuzzingï¼ãå ¶æ ¸å¿ææ³æ¯èªå¨æåèªå¨ççæéæºæ°æ®è¾å ¥å°ä¸ä¸ªç¨åºä¸ï¼å¹¶çè§ç¨åºå¼å¸¸ï¼å¦å´©æºï¼æè¨(assertion)失败ï¼ä»¥åç°å¯è½çç¨åºéè¯¯ï¼æ¯å¦å åæ³æ¼ã
ç®åçæ¨¡ç³æµè¯éæºè¾å ¥æ°æ®ï¼èæ´å é«æçæ¨¡ç³æµè¯ï¼éè¦çè§£å¯¹è±¡ç»ææè åè®®ãéè¿åæ°æ®å 容ï¼ç»æï¼æ¶æ¯ï¼åºåä¸å¼å ¥ä¸äºå¼å¸¸ï¼æ¥äººä¸ºçæé èªæçæ¨¡ç³æµè¯ã
å¦æä½ æç»å ³æ³¨æä»¶ç³»ç»æå æ ¸ææ¯ï¼ä½ ä¸å®æ³¨æè¿è¿æ ·ä¸ç¯æç« ï¼Fuzzing filesystem with AFLãVegard Nossum å Quentin Casasnovas å¨ 2016 å¹´å°ç¨æ·æç Fuzzing å·¥å · AFLï¼American Fuzzing Lopï¼è¿ç§»å°å æ ¸æï¼å¹¶é对æä»¶ç³»ç»è¿è¡äºæµè¯ã
ç»ææ¯ç¸å½æäººçãBtrfsï¼ä½ä¸º SLESï¼SUSE Linux Enterprise Serverï¼çé»è®¤æä»¶ç³»ç»ï¼ä» 卿µè¯ä¸åæäº 5 ç§éå°±æäºãè ext4 åææ¶é´æé¿ï¼ä½ä¹ä» æ 2 ä¸ªå°æ¶èå·²ã(https://zhuanlan.zhihu.com/p/28828826)
æä»¥åºäºæ¤ï¼å¨apiæ¥å£æµè¯ä¸å¼å ¥æ¨¡ç³æµè¯ç论ä¸ä¹æ¯å¯è¡çï¼è䏿¯ææçã
导åºcurlå½ä»¤
æä»¬éæ©curlå½ä»¤ä½ä¸ºæä»¬ç¨åºçè¾å ¥ã为ä»ä¹éæ©curlå½ä»¤å¢ï¼å 为许å¤å·¥å ·æ¯æå¯¼åºå°curlãä¾å¦ï¼openstack k8sçcli client齿¯æå¯¼åºå°curl
nova --debug rename e9211f78-d01e-4fc7-ab85-0ae5ccb80c6a aaaa
kubectl --v=9 get pod nginx-6c6dfb7d8d-2rb7z -o yaml
æ¤å¤ï¼ç±»ä¼¼chrome以åpostmançå·¥å ·ä¹æ¯æå¯¼åºå°curl


è§£æcurl请æ±
对äºä¸ä¸ªcurl请æ±ï¼æä»¬å¯ä»¥å°å ¶å解为å é¨å

å¯ä»¥çå°ï¼ä¸ä¸ªcurl请æ±ä¸»è¦å æ¬
-
Request method ï¼ éå¸¸å æ¬ POSTãGETã DELETE ãPUTçæ¹æ³ï¼é»è²é¨åã
-
Url path ï¼ ç½è²é¨åã
-
Headerï¼çº¢è²é¨åã
-
Bodyï¼ç»¿è²é¨åãé常æ¯POST/PUT ç±»å请æ±ä¸å å«ã
åå¼
éè¿ä»¥ä¸æµç¨ï¼åå«åå¼URL pathï¼éæºå¢å headerï¼bodyä½jsonåå¼çãç¶åå°åå¼åçåæ°è¿è¡æ¼è£ æä¸ä¸ªrequest请æ±ã

对äºheaderä½ï¼è§£æå°ä¸ä¸ªOrderDictï¼è¿è¡éæºå¢å ã

对äºbodyï¼éæºåå¼jsonä½ã


åå¼ç±»åä¼å¤ï¼å¨æ¤ä¸åèµè¿°ã
demo
ç®å IntelliFuzzTest å·¥å ·æ¯æget/post /put/deleteçç±»åç请æ±ååºã
ä¾å¦æ´æ°äºä¸»æºæ¥å£
curl 'http://pubbeta1-ha.iaas.cn-east1.service.local:8774/v2/9ac08939bf67465c88cd638107e0a6d6/servers/e42f4c55-0aa2-40ef-80ba-9a12ff75f8e7' -X PUT -H "X-Auth-Project-Id: admin" -H "User-Agent: python-novaclient" -H "Content-Type: application/json" -H "Accept: application/json" -H "X-Auth-Token: c8e48bd22b0346539276c407e1ce1b47" -d '{"server": {"name": "test1"}}'
å°curlè¯·æ±æ¾å ¥request.txtä¸ãæ§è¡æ¨¡ç³æµè¯

æä»¬å³å¯ä»¥çå°ä¸äºæå¡ç«¯å¼å¸¸äº§çã
æä»¬çä¸ç¼æå¡ç«¯æ¥å¿

å³å¯ä»¥çå°æ¯å 为é»åç¼ç å¼å¸¸å¯¼è´çé误ã
bodyä½çjsonåå¼ç±»åè¿æ¯å¾ä¸°å¯çã䏾便¥è¯´ï¼
(hzx_env) hzhuangzhexiao@pubbeta1-nova10:~$ curl -i http://pubbeta1-iaas.service.163.org:9797/v2.0/security-group-rules.json -X POST -H "X-Auth-Token: af75ed821eeb4d5c9e88fb4ba804ff48" -H "Content-Type: application/json" -H "Accept: application/json" -H "User-Agent: python-protonclient" -d '{"security_group_rule": {"direction": "ingress", "protocol": "tcp", "ethertype": "IPv4", "port_range_max": "6660", "security_group_id": "48b9cc1e-53f8-4f7e-8983-bffb209153f3", "port_range_min": "80", "remote_ip_prefix": "0.0.0.0/"}}'
HTTP/1.1 500
Content-Type: application/json;charset=ISO-8859-1
Content-Length: 6310
Date: Tue, 14 Nov 2017 05:59:10 GMT
Connection: close
An unknown exception occurred.
java.lang.ArrayIndexOutOfBoundsException: 1
at com.netease.cns.proton.server.service.SecurityGroupServiceImpl.validateIpPrefix(SecurityGroupServiceImpl.java:385)
at com.netease.cns.proton.server.service.SecurityGroupServiceImpl.createSecurityGroupRule(SecurityGroupServiceImpl.java:228)
at sun.reflect.GeneratedMethodAccessor385.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
æå°åºåå¼çbodyä½ï¼
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1D, "admin_state_up"_ true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test-1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_utrue}}
{"network-": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuup": true}}
{"network": {"cidr": "20.1.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", : tru}e}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vp¸-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1"Õ : true}}
{"network": {"cdr": "20100..0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_stap"::: true}}
{"network": {"cidr": "20.100.0.0/16", "name": hzx-vpc-test1", "admin_state_up": true}}
"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up":} true}}
{"neeeeeeeeeeeeeeeeeeeeeeeeeeeeeetwork": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up""admin_state_up""admin_state_up""admin_state_up""admin_state_up""admin_state_up""admin_s,ate_up""admin_state_up""admin_state_up": true}}
{"network": }
"n{et���: r{"cidr": "0.}0.0/-34359738368", "naD: true}}
{"network": }
{"[network": {"cidr": "20.-214748364800.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}{"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}{"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.1000.0/+.16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up""admin_state_up""admin_state_up": true}}
{"networ[k": {"cidr": "20.100.0.0/16", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/-4080", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.100.0.0/-4080", "name": "hzx-vpc-test1", "admin_state_up": true}}
{"network": {"cidr": "20.-25500.0.0/16", "name": "hzx-vpc-test1", "admin_stateeeeeeeeeeeeeeeeeeeee_up": true}}
GETç±»å请æ±å¯ä»¥å¯¹url pathè¿è¡æ¨¡ç³æ³¨å ¥ã

å¦å¤ï¼è¿æ¯æå¯¹è¯·æ±çheaderè¿è¡éæºå¢å ï¼æ¨¡æè¯·æ±çã