Skip to content

Commit 5359dcf

Browse files
authored
Merge pull request #76 from gersbach/TIWFY26Q2-26/inno-weeek
TIWFY26Q2-26 : global perm bug
2 parents 373bf7e + 9e47953 commit 5359dcf

6 files changed

Lines changed: 222 additions & 4 deletions

File tree

crates/forge_analyzer/src/checkers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(dead_code, unused)]
12
use crate::interp::ProjectionVec;
23
use crate::utils::projvec_from_str;
34
use crate::{

crates/forge_analyzer/src/definitions.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,8 +3450,22 @@ impl Visit for GlobalCollector<'_> {
34503450
let mut all_module_items = Vec::new();
34513451

34523452
for item in &n.body {
3453-
if let ModuleItem::Stmt(stmt) = item {
3454-
all_module_items.push(stmt.clone());
3453+
match item {
3454+
// TODO handle all cases
3455+
ModuleItem::Stmt(stmt) => all_module_items.push(stmt.clone()),
3456+
ModuleItem::ModuleDecl(mod_decl) => match mod_decl {
3457+
ModuleDecl::ExportDecl(export_decl) => {
3458+
all_module_items.push(Stmt::Decl(export_decl.decl.clone()))
3459+
}
3460+
ModuleDecl::ExportAll(_)
3461+
| ModuleDecl::ExportDefaultDecl(_)
3462+
| ModuleDecl::ExportDefaultExpr(_)
3463+
| ModuleDecl::ExportNamed(_)
3464+
| ModuleDecl::TsExportAssignment(_)
3465+
| ModuleDecl::Import(_)
3466+
| ModuleDecl::TsImportEquals(_)
3467+
| ModuleDecl::TsNamespaceExport(_) => {}
3468+
},
34553469
}
34563470
}
34573471
analyzer.lower_stmts(all_module_items.as_slice());

crates/forge_analyzer/src/interp.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,10 @@ impl<'cx, C: Runner<'cx>> Interp<'cx, C> {
795795
None => {
796796
if self.is_obj(varid) {
797797
Value::Object(varid)
798+
} else if let Some(defid) = self.body().get_defid_from_var(varid)
799+
&& let Some(val) = self.value_manager.defid_to_value.get(&defid)
800+
{
801+
val.clone()
798802
} else {
799803
Value::Unknown
800804
}
@@ -947,11 +951,13 @@ impl<'cx, C: Runner<'cx>> Interp<'cx, C> {
947951
let mut dataflow = C::Dataflow::with_interp(self);
948952
let mut worklist = WorkList::new();
949953

954+
// funcs then are pushed after
955+
worklist.push_front_blocks(self.env, func_def, self.call_all);
956+
957+
// global should be first
950958
for global_def in &self.env().global {
951959
worklist.push_front_blocks(self.env, *global_def, self.call_all);
952960
}
953-
954-
worklist.push_front_blocks(self.env, func_def, self.call_all);
955961
let old_body = self.curr_body.get();
956962
while let Some((def, block_id)) = worklist.pop_front() {
957963
let arguments = self.callstack_arguments.pop();

crates/forge_analyzer/src/runners.rs

Whitespace-only changes.

crates/forge_loader/src/manifest.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(dead_code, unused)]
12
use std::{
23
borrow::Borrow,
34
collections::{BTreeSet, HashSet},
@@ -164,6 +165,7 @@ struct ContentAction<'a> {
164165
#[serde(flatten, borrow)]
165166
common_keys: CommonKey<'a>,
166167
}
168+
167169
#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize)]
168170
struct ContentByLineItem<'a> {
169171
#[serde(flatten, borrow)]

crates/fsrt/src/test.rs

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,201 @@ fn graphql_compass() {
12301230
dbg!(scan_result.into_vulns()[0].description());
12311231
}
12321232

1233+
#[test]
1234+
fn global_secret_vuln() {
1235+
let test_forge_project = MockForgeProject::files_from_string(
1236+
"// src/index.tsx
1237+
import ForgeUI, { render, Fragment, Macro, Text } from '@forge/ui';
1238+
import api, { route, fetch } from '@forge/api';
1239+
import graphqlGateway from '@atlassian/forge-graphql';
1240+
1241+
const secret = 'test';
1242+
1243+
const App = () => {
1244+
let value = 'value'
1245+
1246+
let h = { headers: { authorization: secret } }
1247+
1248+
fetch('url', h)
1249+
foo();
1250+
1251+
return (
1252+
<Fragment>
1253+
<Text>Hello world!</Text>
1254+
</Fragment>
1255+
);
1256+
};
1257+
export const run = render(<Macro app={<App />} />)
1258+
// manifest.yaml
1259+
modules:
1260+
macro:
1261+
- key: basic-hello-world
1262+
function: main
1263+
title: basic
1264+
handler: nothing
1265+
description: Inserts Hello world!
1266+
function:
1267+
- key: main
1268+
handler: index.run
1269+
app:
1270+
id: ari:cloud:ecosystem::app/07b89c0f-949a-4905-9de9-6c9521035986
1271+
permissions:
1272+
scopes:
1273+
- read:component:compass",
1274+
);
1275+
1276+
let scan_result = scan_directory_test(test_forge_project);
1277+
assert!(scan_result.contains_secret_vuln(1));
1278+
assert!(scan_result.contains_vulns(1));
1279+
}
1280+
1281+
#[test]
1282+
fn global_secret_no_vuln() {
1283+
let test_forge_project = MockForgeProject::files_from_string(
1284+
"// src/index.tsx
1285+
import ForgeUI, { render, Fragment, Macro, Text } from '@forge/ui';
1286+
import api, { route, fetch } from '@forge/api';
1287+
import graphqlGateway from '@atlassian/forge-graphql';
1288+
1289+
const secret = process.env.SECRET;
1290+
1291+
const App = () => {
1292+
let value = 'value'
1293+
1294+
let h = { headers: { authorization: secret } }
1295+
1296+
fetch('url', h)
1297+
foo();
1298+
1299+
return (
1300+
<Fragment>
1301+
<Text>Hello world!</Text>
1302+
</Fragment>
1303+
);
1304+
};
1305+
export const run = render(<Macro app={<App />} />)
1306+
// manifest.yaml
1307+
modules:
1308+
macro:
1309+
- key: basic-hello-world
1310+
function: main
1311+
title: basic
1312+
handler: nothing
1313+
description: Inserts Hello world!
1314+
function:
1315+
- key: main
1316+
handler: index.run
1317+
app:
1318+
id: ari:cloud:ecosystem::app/07b89c0f-949a-4905-9de9-6c9521035986
1319+
permissions:
1320+
scopes:
1321+
- read:component:compass",
1322+
);
1323+
1324+
let scan_result = scan_directory_test(test_forge_project);
1325+
assert!(scan_result.contains_vulns(0));
1326+
}
1327+
1328+
#[test]
1329+
fn global_secret_vuln_reset() {
1330+
let test_forge_project = MockForgeProject::files_from_string(
1331+
"// src/index.tsx
1332+
import ForgeUI, { render, Fragment, Macro, Text } from '@forge/ui';
1333+
import api, { route, fetch } from '@forge/api';
1334+
import graphqlGateway from '@atlassian/forge-graphql';
1335+
1336+
const secret = 'test';
1337+
1338+
const App = () => {
1339+
let value = 'value'
1340+
1341+
let h = { headers: { authorization: secret } }
1342+
1343+
let secret = process.ENV.secret;
1344+
1345+
fetch('url', h)
1346+
foo();
1347+
1348+
return (
1349+
<Fragment>
1350+
<Text>Hello world!</Text>
1351+
</Fragment>
1352+
);
1353+
};
1354+
export const run = render(<Macro app={<App />} />)
1355+
// manifest.yaml
1356+
modules:
1357+
macro:
1358+
- key: basic-hello-world
1359+
function: main
1360+
title: basic
1361+
handler: nothing
1362+
description: Inserts Hello world!
1363+
function:
1364+
- key: main
1365+
handler: index.run
1366+
app:
1367+
id: ari:cloud:ecosystem::app/07b89c0f-949a-4905-9de9-6c9521035986
1368+
permissions:
1369+
scopes:
1370+
- read:component:compass",
1371+
);
1372+
1373+
let scan_result = scan_directory_test(test_forge_project);
1374+
assert!(scan_result.contains_vulns(0));
1375+
}
1376+
1377+
#[test]
1378+
fn global_secret_vuln_alternate_file() {
1379+
let test_forge_project = MockForgeProject::files_from_string(
1380+
"//src/constants.tsx
1381+
1382+
export const secret = 'SECRET'
1383+
1384+
//src/index.tsx
1385+
import ForgeUI, { render, Fragment, Macro, Text } from '@forge/ui';
1386+
import api, { route, fetch } from '@forge/api';
1387+
import { secret } from './constants';
1388+
import graphqlGateway from '@atlassian/forge-graphql';
1389+
1390+
const App = () => {
1391+
let value = 'value'
1392+
1393+
let h = { headers: { authorization: secret } }
1394+
1395+
fetch('url', h)
1396+
foo();
1397+
1398+
return (
1399+
<Fragment>
1400+
<Text>Hello world!</Text>
1401+
</Fragment>
1402+
);
1403+
};
1404+
export const run = render(<Macro app={<App />} />)
1405+
// manifest.yaml
1406+
modules:
1407+
macro:
1408+
- key: basic-hello-world
1409+
function: main
1410+
title: basic
1411+
handler: nothing
1412+
description: Inserts Hello world!
1413+
function:
1414+
- key: main
1415+
handler: index.run
1416+
app:
1417+
id: ari:cloud:ecosystem::app/07b89c0f-949a-4905-9de9-6c9521035986
1418+
permissions:
1419+
scopes:
1420+
- read:component:compass",
1421+
);
1422+
1423+
let scan_result = scan_directory_test(test_forge_project);
1424+
assert!(scan_result.contains_secret_vuln(1));
1425+
assert!(scan_result.contains_vulns(1));
1426+
}
1427+
12331428
#[test]
12341429
fn graphqlgateway_compass() {
12351430
let test_forge_project = MockForgeProject::files_from_string(

0 commit comments

Comments
 (0)