Skip to content

Commit

Permalink
Update ex-01 and friends after run-11 (#39)
Browse files Browse the repository at this point in the history
* Remove ex-01 checks for zsh as zsh now is default
* Removing usage of vscode rest-client from ex-01
* Add python code for first and second leg in ex-01
* Stop using Github Codespace User secret for ex-01 client_secret
* Optimize cloc part of ex-04
  • Loading branch information
larskaare authored Nov 13, 2024
1 parent f46fe72 commit cb93c0a
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 89 deletions.
2 changes: 0 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
"extensions": [
"ms-vscode-remote.remote-containers",
"GitHub.codespaces",
"mhutchie.git-graph",
"humao.rest-client",
"streetsidesoftware.code-spell-checker",
"dbaeumer.vscode-eslint",
"ms-azuretools.vscode-docker",
Expand Down
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,34 @@ node_modules/
.tap

.vscode/


### Python ###

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
2 changes: 1 addition & 1 deletion docs/content/ex-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

---

>The purpose of this exercise is get an access token using code. We are moving from the raw style using bare http requests to start exploring what's needed to get this done in code.
>The purpose of this exercise is get an access token using code. We are moving from the raw style using bare http requests to start exploring what's needed to get this done using more code.
Open the file `ex-02/readme.md` for the exercise. ([official repo](https://github.com/equinor/appsec-fundamentals-authn-authz-cs/blob/main/ex-02/readme.md))

Expand Down
35 changes: 0 additions & 35 deletions ex-01/doc/registering_app_object_in_azure_ad.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,3 @@ Steps:
* Do the steps, register the app object

* Post a message to the [appsec-fundamentals-authn-authz](https://equinor.slack.com/archives/C051G3JV7NE) Slack channel and include the "OAuth 2.0 Authorization endpoint (v2)" for your application ⚡️


## Registering the client secret

The client need to authenticate itself with the Authorization Server (MS Entra ID). For this it uses a client secret.

Steps:

* Verify that you are using Zsh as shell in your CS terminal window
* Look for the `>zsh` in the upper right corner area of you CS terminal
* Running `echo $0` should emit `/usr/bin/zsh`
* Register a client secret for your application (In 'Certificates and Secrets')
* Expire: 7 days
* Copy the secret value (not the secret id)
* Execute the following command to persist the client secret as a "Github Codespaces User Secret"</br>Typing "aa-" and then pressing "tab" should help, we have file completion in the terminal.

```shell
aa-save-client-secret.sh
```

* When asked for by the script, paste the value of the client secret
* Select "Reload to Apply" when the message on "Your Codespace Secrets have changed" pops-up.
* Verify that the client secret is available in the CS environment
* Examine the Github Codespaces Config for you Github profile at [https://github.com/settings/codespaces](https://github.com/settings/codespaces)
* You should find the "APPSEC_AA_CLIENT_SECRET" and it should be connected to 1 repo
* Execute the following script to output the value secret into your terminal

```shell
echo $APPSEC_AA_CLIENT_SECRET
```
* (If the GH CS user secret is not available, run the "aa-save-client-secret.sh" script again)

## --Now You--

* Do the steps
44 changes: 29 additions & 15 deletions ex-01/doc/request_an_authorization_code.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
# Requesting an Authorization Code using Rest Client.
# Requesting an Authorization Code

At this point we will start the first leg of the OAuth2 Code Grant flow - getting the auth code that we later will use to request a token. We will use the VS Code Rest Client.
At this point we will start the first leg of the OAuth2 Code Grant flow - getting the auth code that we later will use to request a token. We use a small Python program to generate the request and past this into our browser

Steps:

* Let's start by looking at the [auth code flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) in the documentation of the _Microsoft Identity Platform_
* Open a new terminal window if one is not already available.
* Current directory should be `/workspaces/appsec-fundamentals-authn-authz-cs `
* Open the `./ex-01/authCode.http` file in VSCode.
* Verify that the 'Rest Client' extension is active
* In 'authCode.http' - add value values for
* Your tenant id to `@tenant_id=`
* Your client id to `@client_id=`
* The redirect URI to `@redirect_uri=`
* Explore the set-up and the `GET` request (The first leg)
* In VSCode, select the GET request
* Right-click and select 'Generate Code Snippet' ([doc](https://github.com/Huachao/vscode-restclient#generate-code-snippet))
* Select 'Shell' and then 'cURL'
* Copy the `url` from the curl request
* Paste the url into your browser and execute
* Navigate to the `./ex-01` directory

```shell
cd ex-01
```

* Open and explore `./ex-01/first-leg.py` file in VSCode.
* Update values for the following variables:
* Your tenant id (`tenant_id`)
* Your client id (`client_id`)
* The redirect URI (`redirect_uri`)
* Explore values fro `scope` and `state`
* Prepare the Python environment

```shell
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

* Execute `first-leg.py` and copy the authorization url

```shell
python ./first-leg.py
````

* Paste the url into your browser and execute (or click link in terminal if available)
* Using the Browser Web Developer Tools is recommended.
* Why in the browser?
* Why the "consent" flow?
Expand Down
46 changes: 38 additions & 8 deletions ex-01/doc/requesting_an_access_token.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
# Requesting an Access Token using using Rest Client.
# Requesting an Access Token

Now we are continuing on the second leg of the auth code flow, using the acquired code to request a token.

## Registering the client secret

The client need to authenticate itself with the Authorization Server (Microsoft Entra ID). For this it uses a client secret.

Steps:

* Explore the `POST` request in 'authCode.http'
* Copy the one-time `Code` from previous exercise (leg 1) to `&code=` of the post request
* Select "Send the request" in VSCode (just above the POST definition)
* Explore the results in the 'Response window'

* Register a client secret for your application (In 'Certificates and Secrets')
* Expire: 7 days
* Copy the secret *value* (not the secret id)
* Execute the following command to make the client secret available to the environment (add your secret value)

```shell
export CLIENT_SECRET='THE-VALUE-OF-YOUR-CLIENT-SECRET'
```

## --Now You--

* Do the steps


## Getting the access token

Steps:

* We assume your terminal window is in `./ex-01`
* Open and explore `./ex-01/second-leg.py` file in VSCode.
* Update values for the following variables:
* Your tenant id (`tenant_id`)
* Your client id (`client_id`)
* The redirect URI (`redirect_uri`)
* The One time code (`authorization_code`) (use code from first leg)
* (The client_secret is read from the terminal environment)
* Execute `second-leg.py`

```shell
python ./second-leg.py
````
## --Now You--
* Do the steps
* Resend the POST request with the same o-t-code - observe results
## --Discuss security issues and good practices--
* This part of the communication happens in the "back-channel"
(will be more obvious later on)
* This part of the communication happens in the "back-channel" (will be more obvious later on)
* Public vs. Confidential Client (Trust level)
* The importance of proper SSL, exception of localhost
* The importance of handling `client_secret` as a secret
23 changes: 23 additions & 0 deletions ex-01/first-leg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import urllib.parse

# OAuth2 configuration
tenant_id = "YOUR_TENANT_ID"
client_id = "YOUR_CLIENT_ID"
redirect_uri = "YOUR_REDIRECT_URI"
authorization_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize"

# Requested permissions/scope
scope = "openid profile"
state = "1234" # optional but recommended for security, CSRF

# Construct the authorization URL
params = {
"response_type": "code",
"client_id": client_id,
"redirect_uri": redirect_uri,
"scope": scope,
"state": state
}

authorization_url = authorization_endpoint + "?" + urllib.parse.urlencode(params)
print("Authorization URL:\n\n", authorization_url)
2 changes: 1 addition & 1 deletion ex-01/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Authorization Code Grant

In this exercise we will explore the OAuth2 authorization code grant from a raw perspective, that is the raw http flow. We are using the browser and [VSCode Rest Client](https://github.com/Huachao/vscode-restclient#system-variables) to facilitate the investigation.
In this exercise we will explore the OAuth2 authorization code grant from a raw perspective, that is the raw http flow

## Outline

Expand Down
1 change: 1 addition & 0 deletions ex-01/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests==2.32.3
37 changes: 37 additions & 0 deletions ex-01/second-leg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import requests
import os
import json

# OAuth2 configuration
tenant_id = "YOUR_TENANT_ID"
client_id = "YOUR_CLIENT_ID"
redirect_uri = "YOUR_REDIRECT_URI"

# Getting client secret from the environment
client_secret = os.getenv("CLIENT_SECRET")

# Calculate the token endpoint
token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"

# Authorization code received in the redirect
authorization_code = "AUTHORIZATION_CODE_FROM_FIRST_LEG"

# Request parameters
data = {
"grant_type": "authorization_code",
"code": authorization_code,
"redirect_uri": redirect_uri,
"client_id": client_id,
"client_secret": client_secret
}

# Send the POST request to get the access token
response = requests.post(token_endpoint, data=data)

# Check if the request was successful
if response.status_code == 200:
# Parse the JSON response
tokens = response.json()
print(json.dumps(tokens, indent=4))
else:
print("Failed to obtain token:\n", json.dumps(json.loads(response.text),indent=4))
4 changes: 2 additions & 2 deletions ex-02/doc/environment_variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ Steps:
* You can extract the value from the CLIENT_SECRET from the environment using the following command

```shell
echo $APPSEC_AA_CLIENT_SECRET
echo $CLIENT_SECRET
```
* If you have create a new code space since you configured the Entra ID Application Object for the client app, you may need to update the app registration with the proper redirect uri.
* (If you have create a new code space since you configured the Entra ID Application Object for the client app, you may need to update the app registration with the proper redirect uri.)


## --Now You--
Expand Down
5 changes: 0 additions & 5 deletions ex-02/doc/secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ Steps:
source $HOME/envs/appsec-course-client-eq.env
npm start
```
* Once the needed config is saved into the .env file we can delete the Codespace user secret for Client Secret.
```shell
aa-delete-client-secret.sh
```
## --Now You--
Expand Down
2 changes: 1 addition & 1 deletion ex-02/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# EX-2 - Getting an access token using code

The purpose of this exercise is get an access token using code. We are moving from the raw style http to exploring what's needed to get this done in code.
The purpose of this exercise is get an access token using code. We are moving from the "raw style" http to exploring what's needed to get this done using more code.

## Outline

Expand Down
30 changes: 11 additions & 19 deletions ex-04/doc/lines_of_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,43 @@ In this section we will explore some of the impact using open source frameworks

## --Code Analysis--

Counting lines of JavaScript code in project, my own code and code in modules/frameworks.</br>(We have used **cloc** to do the counting)
Counting approx lines of JavaScript/TypeScript code in project, our own code and code in modules/frameworks.</br>(We have used **cloc** to do the counting)

| Part | EX-2 | EX-4 |
| --- | --- | --- |
| Exercise JS LOC | 797 | 838 |
| Modules JS LOC | 1.519.329 | 1.525.575 |
| % own code | 0.052% | 0.054% |
| Exercise JS LOC | 811 | 852 |
| Modules JS LOC | 1.384.607 | 1.435.897 |
| % own code | 0.058% | 0.059% |
| Direct Node Modules | 16 | 16 |
| Indirect Node Modules | 363 | 391 |
| Indirect Node Modules | 352 | 369 |

Steps:

You will use the command line for the next steps
* Stop the application if it's running, navigate to the `./ex-04` directory
* Remove installed dependencies

```shell
rm -r node_modules
```

* Use CLOC to analyse code, observe technologies in use, lines of code etc.
* Our own code

```shell
cloc .
cloc . --exclude-dir=node_modules
```

* Install dependencies
* Installed dependencies

```shell
npm ci
cloc node_modules
```

* Use CLOC to analyse code, observe technologies in use, lines of code etc.

```shell
cloc .
```
* Notice that we have 30 technologies/languages/systems in use!

## --Now You--

* Do the steps

## --Dependency scanning--

The patterns shown above is not unique to the JavaScript environment - it is more or less how it is these days. From a security perspective we should be able analyses issues in our own code - but what about the 99.9% of the code we have not written ourselves?
The patterns shown above is not unique to the JavaScript environment - it is more or less how it is these days. From a security perspective we should be able analyses issues in our own code - but what about the 85-95% of the code we have not written ourselves?

This is where open source dependency scanning could make a difference. In Equinor we use [Snyk](https://snyk.io/) to scan open source dependencies for known vulnerabilities. Scanning of source code is mandatory in Equinor. Read more about Snyk at [appsec.equinor.com](https://appsec.equinor.com/snyk/) ⚡️

Expand Down

0 comments on commit cb93c0a

Please sign in to comment.