-
Notifications
You must be signed in to change notification settings - Fork 32
/
v3-cors.yaml
98 lines (95 loc) · 3.61 KB
/
v3-cors.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
rules:
# Rule default CORS policies in the batteries-included apollo-server
- id: v3-no-cors
languages: [js, ts]
message: >-
The Apollo GraphQL server lacks a CORS policy. By default, the batteries-included apollo-server package serves the Access-Control-Allow-Origin HTTP header with the wildcard value (*).
severity: WARNING
metadata:
category: security
cwe: "CWE-942: Permissive Cross-domain Policy with Untrusted Domains"
subcategory: [vuln]
confidence: HIGH
likelihood: LOW
impact: LOW
technology:
- graphql
- apollo-graphql-server
- apollo-graphql-server-v3
description: "Lack of CORS policy"
references:
- https://www.apollographql.com/docs/apollo-server/v3/security/cors#configuring-cors-options-for-apollo-server
patterns:
- pattern-either:
- pattern-inside: |
$X = require('apollo-server');
...
- pattern-inside: |
import 'apollo-server';
...
- pattern: |
new ApolloServer({...})
- pattern-not: |
new ApolloServer({..., cors: ..., ...})
# Rule for bad CORS policies in the batteries-included apollo-server
- id: v3-bad-cors
languages: [js, ts]
message: >-
The Apollo GraphQL server is setup with a CORS policy that reflects any origin, or with a regex that has known flaws.
severity: ERROR
metadata:
category: security
cwe: "CWE-942: Permissive Cross-domain Policy with Untrusted Domains"
subcategory: [vuln]
confidence: MEDIUM
likelihood: HIGH
impact: HIGH
technology:
- graphql
- apollo-graphql-server
description: "Bad CORS policy"
references:
- https://www.apollographql.com/docs/apollo-server/v3/security/cors#configuring-cors-options-for-apollo-server
mode: taint
pattern-sources:
- patterns:
- pattern-inside: |
{ origin: $BAD_CORS_ORIGIN }
- metavariable-pattern:
metavariable: $BAD_CORS_ORIGIN
pattern-either:
# 'true' mean that every origin is reflected
- pattern: |
true
- patterns:
# pattern alone or inside an array
- pattern-either:
- pattern: |
$CORS_SINGLE_ORIGIN
- pattern: |
[..., $CORS_SINGLE_ORIGIN, ...]
- metavariable-pattern:
metavariable: $CORS_SINGLE_ORIGIN
pattern-either:
# the '.' character is not escaped
- pattern-regex: ^/.*[^\\]\..*/$
# the regex does not end with '$'
- pattern-regex: ^/.*[^$]/$
# An attacker can make requests from ‘null’ origins
- pattern: |
'null'
pattern-sinks:
- patterns:
# The ApolloServer comes from the 'apollo-server' package
- pattern-either:
- pattern-inside: |
$X = require('apollo-server');
...
- pattern-inside: |
import 'apollo-server';
...
# The sink is the ApolloServer's cors argument
- pattern: |
new ApolloServer({..., cors: $CORS_ORIGIN, ...})
# This tells Semgrep that the sink is only the $CORS_ORIGIN variable
- focus-metavariable: $CORS_ORIGIN