Compare commits

..
Author SHA1 Message Date
Varun Sharma 550c2d137a update 2023-11-13 19:48:31 -08:00
Varun Sharma a2d24fd62e add timeout 2023-11-13 19:47:23 -08:00
Varun Sharma 7bca9467a9 update 2023-11-13 19:43:53 -08:00
Varun Sharma 787deb7075 update 2023-11-13 19:34:10 -08:00
Varun Sharma 34aaaff088 update 2023-11-13 19:14:30 -08:00
Varun Sharma 1cc5c91d22 Update 2023-11-13 18:57:27 -08:00
Varun Sharma 310d9e1272 update 2023-11-13 18:48:43 -08:00
Varun Sharma 36b4d31475 Update 2023-11-13 18:43:32 -08:00
Varun Sharma 061aec38f6 Older ncc 2023-11-13 16:17:39 -08:00
Varun Sharma 70e522ccac update 2023-11-13 16:08:04 -08:00
Varun Sharma b15422ae8d Remove while loop 2023-11-13 16:02:18 -08:00
Varun Sharma 7ceaa3a76e Add return 2023-11-13 15:53:52 -08:00
Varun Sharma 830048ccdb Add logs 2023-11-13 15:41:47 -08:00
Varun Sharma d1ed228523 Update dependencies 2023-11-13 13:59:57 -08:00
Varun Sharma 7fd1ef6945 Update packages 2023-11-13 13:14:11 -08:00
Varun Sharma 987bde6ebb Use node20 2023-11-13 13:08:25 -08:00
Varun Sharma 2750bff0ce Update README 2023-11-08 16:07:41 -08:00
Varun Sharma 7c994b37b5 Update markdown 2023-11-08 14:41:52 -08:00
Varun Sharma ddd6620b25 Update markdown 2023-11-05 21:42:42 -08:00
Varun Sharma b11d6ca1b9 Update dist and version 2023-10-27 15:33:57 -07:00
Varun Sharma 9cef6384fa Merge pull request #355 from step-security/update-packages
Update package-lock.json
2023-10-27 15:31:13 -07:00
Varun Sharma b2d3a9faf3 Merge pull request #354 from step-security/fix-cache
Fix cache
2023-10-27 15:30:45 -07:00
Varun Sharma 03369ff6e2 Merge branch 'rc-v2.6.1' into fix-cache 2023-10-27 15:30:21 -07:00
Varun Sharma b750996025 Merge branch 'rc-v2.6.1' into fix-cache 2023-10-27 15:28:53 -07:00
Varun Sharma d4ca02bcc4 Merge pull request #353 from step-security/markdown
Update markdown
2023-10-27 15:27:42 -07:00
Varun Sharma fc9d972ad4 Merge branch 'rc-v2.6.1' into markdown 2023-10-27 15:26:34 -07:00
Varun Sharma 27f4fdf2ed Update dist 2023-10-27 14:46:17 -07:00
Varun Sharma 4f41e47d74 Fix cache issue 2023-10-27 14:43:31 -07:00
Varun Sharma 0827586e44 Update markdown 2023-10-27 13:37:20 -07:00
Varun Sharma f5cfd3fe85 Update markdown 2023-10-27 13:19:55 -07:00
jatin abb3730f28 Add k8s-mode detection (#345) 2023-10-27 12:58:37 -07:00
19 changed files with 95507 additions and 87232 deletions
+14
View File
@@ -140,6 +140,20 @@ Once allowed endpoints are set in the policy in the workflow file, or in the [Po
<img src="images/blocked-outbound-call-2.png" alt="Policy recommended by harden-runner" >
</p>
### 🤖 Select GitHub Actions with Confidence
> Applies to both GitHub-hosted and self-hosted runners
Before integrating a GitHub Action into your workflow, evaluate its network activity.
- Access network behavior data for hundreds of GitHub Actions, compiled from thousands of workflow runs that use Harden-Runner in public repositories
- Search for a GitHub Action and view a comprehensive report of its outbound network traffic
- Use this insight to make educated choices about incorporating GitHub Actions into your projects
<p align="left">
<img src="images/network-behavior.png" alt="Networking behavior of an Action" >
</p>
### 📁 Detect tampering of source code during build
> Applies to both GitHub-hosted and self-hosted runners
+1 -1
View File
@@ -33,7 +33,7 @@ branding:
icon: "check-square"
color: "green"
runs:
using: "node16"
using: "node20"
pre: "dist/pre/index.js"
main: "dist/index.js"
post: "dist/post/index.js"
+23984 -668
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+23711 -58718
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
View File
+45899 -19647
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

+1828 -8121
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "step-security-harden-runner",
"version": "2.5.1",
"version": "2.6.1",
"description": "Security agent for GitHub-hosted runner: block egress traffic & detect code overwrite to prevent breaches",
"main": "index.js",
"scripts": {
@@ -26,27 +26,27 @@
"@actions/cache": "^3.1.4",
"@actions/core": "^1.5.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^5.0.0",
"@actions/http-client": "^2.0.1",
"@actions/tool-cache": "^1.7.1",
"@actions/github": "^6.0.0",
"@actions/tool-cache": "^2.0.1",
"ansi-regex": ">=5.0.1",
"axios": "^1.6.1",
"is-docker": "^3.0.0",
"node-fetch": ">=3.2.0",
"uuid": "^8.3.2"
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/jest": "^27.5.2",
"@types/node": "^16.9.0",
"@types/jest": "^29.5.8",
"@types/node": "^20.9.0",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"@vercel/ncc": "^0.30.0",
"eslint": "^7.32.0",
"@vercel/ncc": "0.38.0",
"eslint": "^8.53.0",
"eslint-config-google": "^0.14.0",
"jest": "^29.3.1",
"jest-junit": ">=13.0.0",
"nock": "^13.3.0",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typescript": "^4.3.5"
"typescript": "^5.2.2"
}
}
+12 -2
View File
@@ -1,14 +1,24 @@
import * as cp from "child_process";
import * as fs from "fs";
import { sleep } from "./setup";
export function isArcRunner(): boolean {
const runnerUserAgent = process.env["GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT"];
let isARC = false;
if (!runnerUserAgent) {
return false;
isARC = false;
} else {
isARC = runnerUserAgent.includes("actions-runner-controller/");
}
return runnerUserAgent.includes("actions-runner-controller/");
return isARC || isSecondaryPod();
}
function isSecondaryPod(): boolean {
const workDir = "/__w";
return fs.existsSync(workDir);
}
function getRunnerTempDir(): string {
+3 -19
View File
@@ -1,11 +1,7 @@
import * as fs from "fs";
import * as cp from "child_process";
import * as core from "@actions/core";
import * as common from "./common";
import isDocker from "is-docker";
import * as cache from "@actions/cache";
import { cacheFile, cacheKey, isValidEvent } from "./cache";
import path from "path";
import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
(async () => {
@@ -18,18 +14,6 @@ import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
return;
}
if (isValidEvent()) {
try {
const cacheResult = await cache.saveCache(
[path.join(__dirname, "cache.txt")],
cacheKey
);
console.log(cacheResult);
} catch (exception) {
console.log(exception);
}
}
if (isArcRunner()) {
console.log(`[!] ${common.ARC_RUNNER_MESSAGE}`);
arcCleanUp();
@@ -54,8 +38,8 @@ import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
JSON.stringify({ event: "post" })
);
var doneFile = "/home/agent/done.json";
var counter = 0;
const doneFile = "/home/agent/done.json";
let counter = 0;
while (true) {
if (!fs.existsSync(doneFile)) {
counter++;
@@ -71,7 +55,7 @@ import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
}
}
var log = "/home/agent/agent.log";
const log = "/home/agent/agent.log";
if (fs.existsSync(log)) {
console.log("log:");
var content = fs.readFileSync(log, "utf-8");
+10 -9
View File
@@ -101,9 +101,9 @@ export async function addSummary() {
return;
}
const insightsRow = `<h4><a href="${insights_url}">View Full Runtime Security Report & Recommended Policy</a></h4>`;
const insightsRow = `<p><b><a href="${insights_url}">📄 View Full Report</a></b></p>`;
await core.summary.addSeparator().addRaw(`<h2>StepSecurity Report</h2>`);
await core.summary.addSeparator().addRaw(`<h2>🛡 StepSecurity Report</h2>`);
tableEntries.sort((a, b) => {
if (a.status === "❌ Blocked" && b.status !== "❌ Blocked") {
@@ -118,8 +118,9 @@ export async function addSummary() {
tableEntries = tableEntries.slice(0, 3);
await core.summary.addRaw(`
<p>Preview of the network events that occurred on the GitHub-hosted runner during this workflow run.</p>
<h3>🌐 Network Events</h3>
<blockquote>
<p>Preview of the outbound network calls during this workflow run.</p></blockquote>
<h3>Network Calls</h3>
<table>
<thead>
<tr>
@@ -132,16 +133,16 @@ export async function addSummary() {
${tableEntries
.map(
(entry) => `<tr>
<td>${entry.process}</td>
<td><code>${entry.process}</code></td>
<td>${entry.domain.replace(/\.$/, "")}</td>
<td>${entry.status}</td>
</tr>`
)
.join("")}
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
<td><code>...</code></td>
<td><code>...</code></td>
<td><code>...</code></td>
</tr>
</tbody>
</table>
@@ -150,7 +151,7 @@ export async function addSummary() {
await core.summary
.addRaw(
`<p>Markdown generated by the <a href="https://github.com/step-security/harden-runner">Harden-Runner GitHub Action</a></p>`
`<p><i>Markdown generated by the <a href="https://github.com/step-security/harden-runner">Harden-Runner GitHub Action</a>.</i></p>`
)
.addSeparator()
.write();
+29 -31
View File
@@ -1,7 +1,7 @@
import * as core from "@actions/core";
import * as cp from "child_process";
import * as fs from "fs";
import * as httpm from "@actions/http-client";
import axios from "axios";
import * as path from "path";
import { v4 as uuidv4 } from "uuid";
import * as common from "./common";
@@ -19,7 +19,7 @@ import {
} from "./cache";
import { Configuration, PolicyResponse } from "./interfaces";
import { fetchPolicy, mergeConfigs } from "./policy-utils";
import * as cache from "@actions/cache";
import { getCacheEntry } from "@actions/cache/lib/internal/cacheHttpClient";
import * as utils from "@actions/cache/lib/internal/cacheUtils";
import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
@@ -54,22 +54,6 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
private: context?.payload?.repository?.private || false,
};
let policyName = core.getInput("policy");
if (policyName !== "") {
console.log(`Fetching policy from API with name: ${policyName}`);
try {
let idToken: string = await core.getIDToken();
let result: PolicyResponse = await fetchPolicy(
context.repo.owner,
policyName,
idToken
);
confg = mergeConfigs(confg, result);
} catch (err) {
core.info(`[!] ${err}`);
core.setFailed(err);
}
}
fs.appendFileSync(
process.env.GITHUB_STATE,
`disableSudo=${confg.disable_sudo}${EOL}`,
@@ -93,13 +77,20 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
core.setFailed("disable-telemetry must be a boolean value");
}
if (isValidEvent()) {
if (isValidEvent() && confg.egress_policy === "block") {
try {
let compressionMethod: CompressionMethod =
const cacheResult = await cache.saveCache(
[path.join(__dirname, "cache.txt")],
cacheKey
);
console.log(cacheResult);
} catch (exception) {
console.log(exception);
}
try {
const compressionMethod: CompressionMethod =
await utils.getCompressionMethod();
let cacheFilePath = path.join(__dirname, "cache.txt");
cacheFilePath = cacheFilePath.replace("/pre/", "/post/");
const cacheFilePath = path.join(__dirname, "cache.txt");
core.info(`cacheFilePath ${cacheFilePath}`);
const cacheEntry: ArtifactCacheEntry = await getCacheEntry(
[cacheKey],
@@ -158,15 +149,18 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
}
return;
}
//return;
let _http = new httpm.HttpClient();
let statusCode;
_http.requestOptions = { socketTimeout: 3 * 1000 };
//_http.requestOptions = { socketTimeout: 3 * 1000 };
try {
const resp: httpm.HttpClientResponse = await _http.get(
`${api_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}/monitor`
const resp = await axios.get(
`${api_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}/monitor`,
{ timeout: 3000 }
);
statusCode = resp.message.statusCode; // adding error code to check whether agent is getting installed or not.
statusCode = resp.status; // adding error code to check whether agent is getting installed or not.
console.log(`statuscode: ${statusCode}`);
fs.appendFileSync(
process.env.GITHUB_STATE,
`monitorStatusCode=${statusCode}${EOL}`,
@@ -177,13 +171,13 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
} catch (e) {
console.log(`error in connecting to ${api_url}: ${e}`);
}
//return;
console.log(`Step Security Job Correlation ID: ${correlation_id}`);
if (String(statusCode) === common.STATUS_HARDEN_RUNNER_UNAVAILABLE) {
console.log(common.HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
return;
}
//return;
const confgStr = JSON.stringify(confg);
cp.execSync("sudo mkdir -p /home/agent");
cp.execSync("sudo chown -R $USER /home/agent");
@@ -200,7 +194,7 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
verifyChecksum(downloadPath); // NOTE: verifying agent's checksum, before extracting
const extractPath = await tc.extractTar(downloadPath);
//return;
let cmd = "cp",
args = [path.join(extractPath, "agent"), "/home/agent/agent"];
cp.execFileSync(cmd, args);
@@ -222,6 +216,7 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
var statusFile = "/home/agent/agent.status";
var logFile = "/home/agent/agent.log";
var counter = 0;
await sleep(5000);
while (true) {
if (!fs.existsSync(statusFile)) {
counter++;
@@ -233,6 +228,7 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
}
break;
}
console.log("sleeping");
await sleep(300);
} // The file *does* exist
else {
@@ -245,6 +241,8 @@ import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
} catch (error) {
core.setFailed(error.message);
}
console.log("method done");
return;
})();
export function sleep(ms) {