Block Public IPs with APIM based on header - azure-api-management

Because APIM sits behind an Application Gateway, it will only see traffic as coming from the app gateway, so I do not believe the simple ip-filter policy will work. App gateway does add the original source IP to the x-original-host header though.
I am new to APIM policy and do not know how to build logic into it. What I want to do is IF the x-forwarded for value IS in a private IP, allow...else, deny. I see that policy expressions are written in C#, which I know nothing about.
Was thinking something like this
<policies>
<inbound>
<base />
<check-header name="" x-original-host="" failed-check-error-message="" ignore-case="true">
<value>This is where I need to go through the list of private IP ranges</value>
</check-header>
</inbound>
[...]
</policies>
That could can be completely wrong too. My intent is to create rule that allows private IPs only, and denies everything else. Here are the private IPs to allow:
Class A: 10.0.0.0 to 10.255.255.255
Class B: 172.16.0.0 to 172.31.255.255
Class C: 192.168.0.0 to 192.168.255.255

See this Filter on request IP Address when using an Application Gateway

Related

Catch 22? Blocked by CORS policy: Same server, internal/external IP, no SSL

My apologies if this is a duplicate. I can find a million results about CORS policy issues, but not about this specific one:
I developed a simple "speed test" site for my users (wfh employees of my company) to access. It tests speeds across the public net to different datacenters we utilize, and via the users' VPN connection to one of our DCs.
There are more complicated elements, but for a basic round-trip "ping" I have an extremely simple PHP script on the server that contains:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');
if ($_GET['simple'] == '1')
die('{ }');
?>
It is called like this:
$.ajax({
type: 'GET',
url: sURL,
data: { ignore: (pingCounter.start = new Date().getTime()) },
dataType: 'text',
timeout: iTimeout
})
.done(function(ret) {
pingCounter.end = new Date().getTime();
[...] (additional code omitted for brevity)
(I know this has additional overhead other than the raw round-trip network traffic timing, but I don't need sub-ms accuracy. I just need to be able to tell users "the problem is on your end" or "ah yes, the problem is the latency between your house and this particular DC".)
The same server running that PHP code is addressable at the following URLs at the DC wherein our VPN server lies:
http://speedtest-int.mycompany.com/ping.php
http://speedtest-ext.mycompany.com/ping.php
Public DNS resolves like this:
speedtest-int.mycompany.com IN A 1.1.1.1 (Actual public IP redacted)
speedtest-int.mycompany.com IN A 10.1.1.1 (Actual internal IP redacted)
If I access either URL from my browser directly, it loads fine (which is to say it responds with { }).
When loading via the JS snippet above, the call to http://speedtest-ext.mycompany.com/ping.php works fine.
The call to http://speedtest-int.mycompany.com/ping.php fails with "The request client is not a secure context and the resource is in more-private address space 'private'".
Fair enough, the solution is to add Access-Control-Allow-Private-Network: *, right?
EXCEPT that apparently can only be used with SSL:
https://developer.chrome.com/blog/private-network-access-update/
I have a self-signed cert on there, but that obviously fails by policy for that reason.
I could just get a LetsEncrypt cert for multiple subdomains. EXCEPT it will never validate the URL http://speedtest-int.mycompany.com because the LetsEncrypt servers won't be able to reach that to validate ownership, as it's a private IP.
I have no control over most of my users' machines, so I can't necessarily install trusted internal certs or change browser options. Most users use Chrome.
So is my solution to buy a UCC or wildcard cert?
I feel like I'm in a catch-22, and I don't want to spend however-much on a UCC cert for an internal app that will be very very very occasionally used by one of our 25 home-based employees when I want to prove that their home "internet is bad" and not the corp network.
Thanks in advance; I'm sure there's a stupidly obvious solution I'm not seeing.
(I'm considering pushing a /32 route to my VPN users for another real public IP to be used in place of the internal IP. Then I can have the "internal" test run against an otherwise publicly accessible IP which could be validated by LetsEncrypt, but VPN users would hit it via the VPN. Is that silly?)
Edit: If anyone is curious -- or it helps to clarify my goal here -- this is the output when accessing the speedtest page:
http://s.co.tt/wp-content/uploads/2021/12/Internal_Speedtest_Example-Redacted.png
It repeats for 20 cycles (or until stopped) and runs each element a varying number of times per cycle, collecting the average time for each. It ain't pretty, but it work(ed).

How to set proxy server for Json Web Keys

I'm trying to build JWKS object for google JSON web keys to verify the signature of JWT token received from google. Inside our corporate environment, we need to set the proxy server to reach out external one. Below code runs outside the corporate environment.
HttpsJwks https_jwks = new HttpsJwks(GOOGLE_SIGN_KEYS);
List<JsonWebKey> jwks_list = https_jwks.getJsonWebKeys();
Library: jose4j0.4.1
Thanks in advance.
HttpsJwks uses the SimpleGet interface to make the HTTP call. By default it's an instance of Get, which uses java's HttpsURLConnection. So I think using the https proxy properties should work - see https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html for more about https.proxyHost and https.proxyPort.
If you need to do something more exotic for whatever reason, you can set your own implementation/instance of SimpleGet on the HttpsJwks instance too.

How to fix cross-site origin policy for server and web-site

I'm using Dropwizard, which I'm hosting, along with a website, on the google cloud (GCE). This means that there are 2 locations currently active:
Some.IP.Address - UI
Some.IP.Address:8080 - Dropwizard server
When the UI tries to call anything from my dropwizard server, I get cross-site origin errors, which is understandable. However, this is posing a problem for me. How do I fix this? It would be great if I could somehow spoof the addresses so that I don't have to fully qualify the resource in the UI.
What I'm looking to do is this:
$.get('/provider/upload/display_information')
Or, if I have to fully qualify
$.get('http://Some.IP.Address:8080/provider/upload/display_information')
I tried setting Origin Filters in Dropwizard per this google groups thread (https://groups.google.com/forum/#!topic/dropwizard-user/ybDOTOxjlLI), but it doesn't seem to work.
In index.html that is served by the server at http://Some.IP.Address you might have a jQuery script that look as follows.
$.get('http://Some.IP.Address:8080/provider/upload/display_information', data, callback);
Of course your browser will not allow accessing http://Some.IP.Address:8080 due to the Same-Origin-Policy (SOP). The protocol (http, https) and the host as well as the port have to be the same.
To achieve Cross-Origin Resource Sharing (CORS) on Dropwizard, you have to add a CrossOriginFilter to the servlet environment. This filter will add some Access-Control-Headers to every response the server is sending. In the run method of your Dropwizard application write:
import org.eclipse.jetty.servlets.CrossOriginFilter;
public class SomeApplication extends Application<SomeConfiguration> {
#Override
public void run(TodoConfiguration config, Environment environment) throws Exception {
FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORS", CrossOriginFilter.class);
filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
filter.setInitParameter("allowedOrigins", "http://Some.IP.Address"); // allowed origins comma separated
filter.setInitParameter("allowedHeaders", "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filter.setInitParameter("allowedMethods", "GET,PUT,POST,DELETE,OPTIONS");
filter.setInitParameter("preflightMaxAge", "5184000"); // 2 months
filter.setInitParameter("allowCredentials", "true");
// ...
}
// ...
}
This solution works for Dropwizard 0.7.0 and can be found on https://groups.google.com/d/msg/dropwizard-user/xl5dc_i8V24/gbspHyl4y5QJ.
This filter will add some Access-Control-Headers to every response. Have a look on http://www.eclipse.org/jetty/documentation/current/cross-origin-filter.html for a detailed description of the initialisation parameters of the CrossOriginFilter.

Can a URL have multiple parts of subdomain to it?

I have a domain name abc.mydomain.com
This is a https URL ( http redirects to the https version )
However, I now need to be able to handle www.abc.mydomain.com to redirect to abc.mydomain.com
How can I do this? is it a webserver level redirect or something to be done at the DNS resolution.
I know my URL already has the "abc" as its sub-domain and I dont need a "www", however, we noticed that "www.news.google.com" resolves to "news.google.com" - hence wondering if I can achieve it too
Thank you!
In short, yes.
DNS works on a hierarchy - the DNS server for .com can delegate down to the nameserver for your domain which can delegate further, or just answer the requests, which needs to be your first step.
If you use Bind style zone files, you can do something like (where 123.45.67.89 is your webserver IP address):
* IN A 123.45.67.89
Then, you also need your webserver to resolve that to the right virtual host/redirect as desired.

Security in Spring MVC and JSON

I want to provide security one way or another for Sending and Getting JSON Data,but I don't know how to do this.
Our System has roles of users (System admin, General Members, etc.)
We decided send data as JSON using the Spring MVC URL pattern. I don't want everybody that outside from system to use this URL, only users can use the URL.
Example
www.example.com/services/"hereUserPass"/"hereUserName"/category/3
Each request time for different URLs, Should I control the username and password whether registered before? or What should I do for Security?
You want to implement security into your Spring Web application. You can do this at two ways:
Url Based Security
Method Based Security
Try to make another xml file as like applicationContext-security.xml Here is an example:
<http use-expressions="true">
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="/static/**" filters="none" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login />
<logout />
</http>
Here we see that permitAll means permit everybody who wants to reach that URL. filters = none has the same effect but it means that user will not go over Spring Security(Previous one goes over Spring Security but has access, filtering doesn't applied). isAuthenticated means that user can reach there if authenticated. You can also apply role based acces to urls.
Other security implementation base on middle tier security. You should add this line at your application context security file:
<global-method-security pre-post-annotations="enabled" />
so you can use method based security as like:
#PreAuthorize("hasRole('ROLE_SUPERVISOR')")
void storeVisit(Visit visit) throws DataAccessException;
You can start to reading with Spring Security implementation of Spring's Pet Clinic example: http://static.springsource.org/spring-security/site/petclinic-tutorial.html
Also I recommend you read here: http://www.mularien.com/blog/2008/07/07/5-minute-guide-to-spring-security/