diff --git a/api/firewall.js b/api/firewall.js new file mode 100644 index 0000000..f90e108 --- /dev/null +++ b/api/firewall.js @@ -0,0 +1,105 @@ +const axios = require('axios'); +const middleware = require('./_common/middleware'); + +const hasWaf = (waf) => { + return { + hasWaf: true, waf, + } +}; + +const handler = async (url) => { + const fullUrl = url.startsWith('http') ? url : `http://${url}`; + + try { + const response = await axios.get(fullUrl); + + const headers = response.headers; + + if (headers['server'] && headers['server'].includes('cloudflare')) { + return hasWaf('Cloudflare'); + } + + if (headers['x-powered-by'] && headers['x-powered-by'].includes('AWS Lambda')) { + return hasWaf('AWS WAF'); + } + + if (headers['server'] && headers['server'].includes('AkamaiGHost')) { + return hasWaf('Akamai'); + } + + if (headers['server'] && headers['server'].includes('Sucuri')) { + return hasWaf('Sucuri'); + } + + if (headers['server'] && headers['server'].includes('BarracudaWAF')) { + return hasWaf('Barracuda WAF'); + } + + if (headers['server'] && (headers['server'].includes('F5 BIG-IP') || headers['server'].includes('BIG-IP'))) { + return hasWaf('F5 BIG-IP'); + } + + if (headers['x-sucuri-id'] || headers['x-sucuri-cache']) { + return hasWaf('Sucuri CloudProxy WAF'); + } + + if (headers['server'] && headers['server'].includes('FortiWeb')) { + return hasWaf('Fortinet FortiWeb WAF'); + } + + if (headers['server'] && headers['server'].includes('Imperva')) { + return hasWaf('Imperva SecureSphere WAF'); + } + + if (headers['x-protected-by'] && headers['x-protected-by'].includes('Sqreen')) { + return hasWaf('Sqreen'); + } + + if (headers['x-waf-event-info']) { + return hasWaf('Reblaze WAF'); + } + + if (headers['set-cookie'] && headers['set-cookie'].includes('_citrix_ns_id')) { + return hasWaf('Citrix NetScaler'); + } + + if (headers['x-denied-reason'] || headers['x-wzws-requested-method']) { + return hasWaf('WangZhanBao WAF'); + } + + if (headers['x-webcoment']) { + return hasWaf('Webcoment Firewall'); + } + + if (headers['server'] && headers['server'].includes('Yundun')) { + return hasWaf('Yundun WAF'); + } + + if (headers['x-yd-waf-info'] || headers['x-yd-info']) { + return hasWaf('Yundun WAF'); + } + + if (headers['server'] && headers['server'].includes('Safe3WAF')) { + return hasWaf('Safe3 Web Application Firewall'); + } + + if (headers['server'] && headers['server'].includes('NAXSI')) { + return hasWaf('NAXSI WAF'); + } + + if (headers['x-datapower-transactionid']) { + return hasWaf('IBM WebSphere DataPower'); + } + + return { + hasWaf: false, + } + } catch (error) { + return { + statusCode: 500, + body: JSON.stringify({ error: error.message }), + }; + } +}; + +exports.handler = middleware(handler); diff --git a/src/components/Results/Firewall.tsx b/src/components/Results/Firewall.tsx new file mode 100644 index 0000000..080b87d --- /dev/null +++ b/src/components/Results/Firewall.tsx @@ -0,0 +1,24 @@ +import styled from 'styled-components'; +import { Card } from 'components/Form/Card'; +import Row from 'components/Form/Row'; + +const Note = styled.small` +opacity: 0.5; +display: block; +margin-top: 0.5rem; +`; + +const FirewallCard = (props: { data: any, title: string, actionButtons: any }): JSX.Element => { + const data = props.data; + return ( + + + { data.waf && } + { !data.hasWaf && ( + *The domain may be protected with a proprietary or custom WAF which we were unable to identify automatically + ) } + + ); +} + +export default FirewallCard;