I came across this very interesting article explaining correct use of PATCH in HTTP world. Worth reading even if little out-dated!
https://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
Skill to do come from doing…
I came across this very interesting article explaining correct use of PATCH in HTTP world. Worth reading even if little out-dated!
https://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
Although this information may seem innocuous, it allows an attacker to identify the version of server side components and therefore target further attacks to this specific software. This can quickly lead to successful exploitation if the server side components have vulnerabilities with publicly available exploit code. The server software versions used by the application are revealed by the web server. Displaying version information of software information could allow an attacker to determine which vulnerabilities are present in the software, particularly if an outdated software version is in use with published vulnerabilities.
See the following guide for removing the headers from IIS and ASP.NET: https://blogs.msdn.microsoft.com/varunm/2013/04/23/removeunwanted-http-response-headers
It is recommended that functionality is implemented within the application that detects when an error has occurred and redirects the user to a custom error page that does not disclose any form of sensitive data. These errors that should induce a redirect to a custom error page should include 403 Forbidden Errors – to prevent an adversary from enumerating existing pages on the application that require prior authentication to view; 404 Not Found pages; and 500 Internal Error pages. Alternatively, simply redirecting a user to the applications home page can also suffice in reducing the level of information disclosed.
For ASP.NET, in web.config set one of the following options:
<customErrors mode="RemoteOnly" /> <customErrors mode="On" />
A number of HTTP Security Headers have been introduced in recent years to enhance security of a website by providing protections against certain types of attacks. The following table contains the headers which fall under this vulnerability category, notes are offered in the technical analysis as to which headers are missing and any misconfiguration discovered during the engagement.
It’s strongly recommended that these headers are configured on all applications to further harden the application from attack.
Few example headers that should be used:
Additional information, plus examples of all headers to consider can be found at https://securityheaders.com
Cross-Site Request Forgery (CSRF) vulnerabilities arise when applications rely solely on HTTP cookies to identify the user that has issued a particular request. Because browsers automatically add cookies to requests regardless of their origin, it may be possible for an attacker to create a malicious web site that forges a cross-domain request to the vulnerable application. For a request to be vulnerable to CSRF, the following conditions must hold:
The most effective way to protect against CSRF vulnerabilities is to include within relevant requests an additional token that is not transmitted in a cookie: for example, a parameter in a hidden form field. This additional token should be random enough such that it is not feasible for an attacker to determine or predict the value of any token that was issued to another user. The token should be associated with the user’s session, and the application should validate that the correct token is received before performing any action resulting from the request.
An alternative approach, which may be easier to implement, is to validate that Host and Referer headers in relevant requests are both present and contain the same valid domain name. The Origin header can also be validated against the Host, however some browsers do not support this for requests made from the same domain, therefore this mechanism would need to use the Referer header as a fallback. For AJAX requests, a custom header can be added and then checked server-side (e.g. “X-Requested-With: XMLHttpRequest”), because this cannot be passed cross-domain without CORS being enabled.
However, these header checking approaches are somewhat less robust. Historically, quirks in browsers and implementation errors have often enabled attackers to forge cross-domain requests that manipulate these headers to bypass such defence.
To find the process ID (PID) of the application, we need to run following command:
tasklist | findstr '<application/process name>
This will display all processes running on machine, where process name contains <application/process name> value. Result of above command includes PID – we will use this in next step.
Next, we run below command to find actual port number used by the process:
netstat -ano | findstr <PID>
This command lists all ports used by process.
This is excerpt from ASP.NET Core documentation on semantic versioning. Full document can be found here
The .NET Core Runtime roughly adheres to Semantic Versioning (SemVer), adopting the use of MAJOR.MINOR.PATCH
versioning, using the various parts of the version number to describe the degree and type of change.Copy
MAJOR.MINOR.PATCH[-PRERELEASE-BUILDNUMBER]
The optional PRERELEASE
and BUILDNUMBER
parts are never part of supported releases and only exist on nightly builds, local builds from source targets, and unsupported preview releases.
MAJOR
is incremented when:
MAJOR
version of an existing dependency is adopted.MINOR
is incremented when:
MINOR
version of an existing dependency is adopted.PATCH
is incremented when:
PATCH
version of an existing dependency is adopted.When there are multiple changes, the highest element affected by individual changes is incremented, and the following ones are reset to zero. For example, when MAJOR
is incremented, MINOR
and PATCH
are reset to zero. When MINOR
is incremented, PATCH
is reset to zero while MAJOR
is left untouched.
In this article I’ll walk through creating alias in Windows command line. I will create alias named “subl” for launching Sublime Text 3 editor from command line.
For this purpose, doskey
command is particularly useful.
Sublime Text 3 is installed in default folder on my PC, so running below command will do the trick:
doskey subl="C:\Program Files\Sublime Text 3\sublime_text.exe"
Now I can type
subl
in command prompt and system starts Sublime Text 3 editor.
There is one little catch here though. Even if I type
subl C:\tmp\file.txt
Sublime always opens new blank document.
In order to be able to pass parameter into the alias, doskey command needs to be altered slightly:
doskey subl="C:\Program Files\Sublime Text 3\sublime_text.exe"
$*
Adding “$*” at the end allows the alias to accept zero, one, or more args.
I can now type
subl C:\tmp\file.txt
and Sublime happily loads correct file.
While using this alias, I discovered one very annoying thing: aliases disappear when console is restarted. Doskey command needs to be called again.
There is a way to automate loading Doskey macros (loads of information on this on google), but it requires modifying Windows registry, which I did not want.
Instead I found easier solution:
I created very simple batch file called subl.bat
:
@ECHO OFF
START "" "C:\Program Files\Sublime Text 3\sublime_text.exe" %1
And moved it to location listed in system PATH
variable, i.e. %USERPROFILE%
Now calling
subl \tmp\path.txt
Launches new instance of Sublime Text even after restarting console.
Voila!
Great article on .NET Core versioning by Jon Skeet:
There is also extremely useful set of guidelines from Microsoft on what’s breaking change:
This is post is not meant to be another iteration of “most common questions you will be asked when applying for dev role”. It’s the opposite – it’s about questions you will want to ask your potential employer before you commit yourself any further. The biggest mistake we tend to do when sitting interview is not evaluating employer well enough in order to make informed decision.
Excellent article by Sean Ivey from Microsoft on what’s good (and what’s no so much) about AD FS:
Further read on the subject:
Following command creates SSH key pair:
ssh-keygen
It will then prompt you for the location (the default ~/.ssh/id_rsa) and for a passphrase. The result will be two files, id_rsa (the private key) and id_rsa.pub (the public key). The public key will be store on this server while the private key will be copied into the client.
More details can be found here
Following command needs to be run on the server to push generated public key to SSH key repo:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
This will append newly generated public key to existing authorized keys.
Finally appropriate permissions need to be set on the server:
chmod 600 ~/.ssh/authorized_keys
More details on SSH configuration can be found here
Note: This article is not aiming on digging into details of setting up CI pipeline. It’s sole purpose is to explain my experience with deploying and running .NET Core app in Linux environment.
Another note: For the purpose of this article I created simple HelloWorld Web API (https://github.com/mattuu/HelloWorld.NetCoreApi) and simple HelloWorld Angular app (https://github.com/mattuu/HelloWorld.Angular) that calls this API.
This article will use following file system paths:
/usr/helloworld
|--> api (directory for .NET Core Web API)
|--> www (directory for Angular app)
|--> nginx.conf (config file for Nginx)
The CI pipeline should push your code to file system on Linux machine.
This guide describes steps to install .NET Core: https://www.microsoft.com/net/download/linux-package-manager/centos/runtime-current
To check if .NET Core installed successfully, simply run:
dotnet --version
Now you should be able to start API by typing:
dotnet /usr/helloworld/api/HelloWorld.dll
Every process in Linux needs to run it’s own daemon. In order to accomplish this, we will use SystemD utility.
First we create service file helloworld.service with following content:
[Unit]
Description=Hello World .NET Core App Service
After=network.target
[Service]
ExecStart=/usr/bin/dotnet /usr/helloworld/helloworld.dll 5000
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
Next we copy this file to SystemD location:
sudo cp helloworldapi.service /lib/systemd/system
Now we need to reload SystemD and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable helloworldapi
Finally we start the service and check the status:
sudo systemctl start helloworldapi
systemctl status helloworldapi
More details of how to configure SystemD can be found here: https://www.freedesktop.org/wiki/Software/systemd/ or here: https://pmcgrath.net/running-a-simple-dotnet-core-linux-daemon
Since .NET Core runs on Kestrel, we need to setup a web server that will act as reverse proxy for the API. Most commonly used are Nginx or Apache. I will use Nginx for this article.
Full instructions on how to install Nginx can be found here: http://nginx.org/en/docs/install.html
Now we need to tell Nginx to forward requests to .NET Core application. By default .NET Core runs on port 5000 so below configuration should work fine (path: /usr/helloworld/nginx.conf)
location /api/ {
proxy_pass http://localhost:5000; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
}
This ensures forwarding all requests to http://localhost/api are forwarded to http://localhost:5000 which is where .NET Core Web API is hosted.
Note: Nginx needs to be configured to include our custom configuration file so the following change needs to be done to Nginx default configuration (most likely to be in /etc/nginx/nginx.conf):
include /usr/helloworld/nginx.conf;
More on Nginx configuration options can be found here: https://nginx.org/en/docs/
Our Angular app will be located in following directory: /usr/helloworld/www
Since Angular app is simple index.html, we need to tell Nginx to serve it as static content. Following article describes how to achieve this: https://medium.com/@jgefroh/a-guide-to-using-nginx-for-static-websites-d96a9d034940
Sample configuration may look like this (path: /usr/helloworld/nginx.conf)
location / {
root /usr/helloworld/www;
try_files /index.html =404;
}
location ~* .(js|jpg|png|css|woff|eot|svg|ttf|ico)$ {
root /usr/helloworld/www;
expires 30d;
}
First block ensures index.html is default document served by Nginx. This is needed to load Angular app properly.
Second line tells Nginx what to do with assets like JavaScript, CSS, images, fonts etc.
Once that’s done we should be able to navigate to http://localhost and see Angular app successfully loading:
If we now change browser url to http://localhost/?name=Matt, our application should display personalized greeting:
Our Angular app successfully passed name parameter to API and displayed greeting message generated by .NET Core.
I really think .NET Core on Linux has great potential and will be exploring it further in future. I am planning on creating some bash scripts for dealing with this setup.