swissfintechinnovations / ca-payment

Common APIs for AIS and PIS
https://www.common-api.ch
Apache License 2.0
0 stars 3 forks source link

Validate "X-PSU-IP-Address" against pattern #87

Open ochatelain opened 3 months ago

ochatelain commented 3 months ago

Just a little more strict definition

dschoeni commented 3 months ago

Just be careful, your regex doesn't include IPv6, but IPv6 values are valid to be included in X-Forwarded-For headers provided by proxies and gateways (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For).

ochatelain commented 1 month ago

Just be careful, your regex doesn't include IPv6, but IPv6 values are valid to be included in X-Forwarded-For headers provided by proxies and gateways (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For).

(([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4})

Could someone verify, if this is really a valid IPv6.

svenbiellmann commented 1 month ago

Just be careful, your regex doesn't include IPv6, but IPv6 values are valid to be included in X-Forwarded-For headers provided by proxies and gateways (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For).

(([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4})

Could someone verify, if this is really a valid IPv6.

@dkoeni : Kannst du dies beurteilen?

dkoeni commented 1 month ago

This pattern is not valid since it does not match e.g. FF01::101, which is a valid IPv6 address. To come up with a good regex for IPv6 is rather tricky because there isn't a single pattern to match.

For example, 0:0:0:0:0:FFFF:8190:0726, 0:0:0:0:0:FFFF:8190:726, ::FFFF:8190:0726, ::FFFF:8190:726, ::FFFF:129.144.7.38, and 0:0:0:0:0:FFFF:129.144.7.38 are valid representations of the same IPv6 address (RFC 4291, Section 2.2, and there are actually more representations added in later RFCs). So the proper pattern to match all those cases would be (([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])),

which corresponds to

(
([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8  
:((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::     
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
([0-9a-fA-F]{1,4}:){1,4}:
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
)

However regex101 does not verify that this regex match the address ffff::ffff even it should be as line 4 matches this pattern.

To conclude I would suggest to allow only specific representations of IPv6 to implement a more efficient Regex pattern, if this is suitable in context of the API use cases.