mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
Initial merge from main
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
dependencies:
|
||||
codeql/javascript-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Deleted the deprecated `isHTMLElement` and `getDOMName` predicates from the JSX library, use `isHtmlElement` and `getDomName` respectively instead.
|
||||
* Deleted the deprecated `getPackageJSON` predicate from the `SourceMappingComment` class, use `SourceMappingComment` instead.
|
||||
* Deleted many deprecated directives from the `Stmt.qll` file, use the `Directive::` module instead.
|
||||
* Deleted the deprecated `YAMLNode`, `YAMLValue`, and `YAMLScalar` classes from the YAML libraries, use `YamlNode`, `YamlValue`, and `YamlScalar` respectively instead.
|
||||
* Deleted the deprecated `getARouteHandlerExpr` predicate from `Connect.qll`, use `getARouteHandlerNode` instead.
|
||||
* Deleted the deprecated `getGWTVersion` predicate from `GWT.qll`, use `getGwtVersion` instead.
|
||||
* Deleted the deprecated `getOwnOptionsObject` predicate from `Vue.qll`, use `getOwnOptions().getASink()` instead.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added support for TypeScript 5.6.
|
||||
@@ -73,9 +73,6 @@ class JsxElement extends JsxNode {
|
||||
* That is, the name starts with a lowercase letter.
|
||||
*/
|
||||
predicate isHtmlElement() { this.getName().regexpMatch("[a-z].*") }
|
||||
|
||||
/** DEPRECATED: Alias for isHtmlElement */
|
||||
deprecated predicate isHTMLElement() { this.isHtmlElement() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,7 +253,4 @@ class JsxPragma extends JSDocTag {
|
||||
* the result is `React.DOM`.
|
||||
*/
|
||||
string getDomName() { result = this.getDescription().trim() }
|
||||
|
||||
/** DEPRECATED: Alias for getDomName */
|
||||
deprecated string getDOMName() { result = this.getDomName() }
|
||||
}
|
||||
|
||||
@@ -295,6 +295,15 @@ private predicate isRequire(DataFlow::Node nd) {
|
||||
isCreateRequire(call.getCallee().flow()) and
|
||||
nd = call.flow()
|
||||
)
|
||||
or
|
||||
// `$.require('underscore');`.
|
||||
// NPM as supported in [XSJS files](https://www.npmjs.com/package/@sap/async-xsjs#npm-packages-support).
|
||||
exists(MethodCallExpr require |
|
||||
nd.getFile().getExtension() = ["xsjs", "xsjslib"] and
|
||||
require.getCalleeName() = "require" and
|
||||
require.getReceiver().(GlobalVarAccess).getName() = "$" and
|
||||
nd = require.getCallee().flow()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,9 +197,6 @@ class MainModulePath extends PathExpr, @json_string {
|
||||
not exists(getExportRelativePath(this)) and result = "."
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for getPackageJson */
|
||||
deprecated PackageJson getPackageJSON() { result = this.getPackageJson() }
|
||||
|
||||
override string getValue() { result = this.(JsonString).getValue() }
|
||||
|
||||
override Folder getAdditionalSearchRoot(int priority) {
|
||||
@@ -258,9 +255,6 @@ private class FilesPath extends PathExpr, @json_string {
|
||||
/** Gets the `package.json` file in which this path occurs. */
|
||||
PackageJson getPackageJson() { result = pkg }
|
||||
|
||||
/** DEPRECATED: Alias for getPackageJson */
|
||||
deprecated PackageJson getPackageJSON() { result = this.getPackageJson() }
|
||||
|
||||
override string getValue() { result = this.(JsonString).getValue() }
|
||||
|
||||
override Folder getAdditionalSearchRoot(int priority) {
|
||||
|
||||
@@ -23,7 +23,4 @@ class SourceMappingComment extends Comment {
|
||||
|
||||
/** Gets the URL of the source map referenced by this comment. */
|
||||
string getSourceMappingUrl() { result = url }
|
||||
|
||||
/** DEPRECATED: Alias for getSourceMappingUrl */
|
||||
deprecated string getSourceMappingURL() { result = this.getSourceMappingUrl() }
|
||||
}
|
||||
|
||||
@@ -434,36 +434,6 @@ module Directive {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Use `Directive::KnownDirective` instead. */
|
||||
deprecated class KnownDirective = Directive::KnownDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::StrictModeDecl` instead. */
|
||||
deprecated class StrictModeDecl = Directive::StrictModeDecl;
|
||||
|
||||
/** DEPRECATED. Use `Directive::AsmJSDirective` instead. */
|
||||
deprecated class AsmJSDirective = Directive::AsmJSDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::BabelDirective` instead. */
|
||||
deprecated class BabelDirective = Directive::BabelDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::SixToFiveDirective` instead. */
|
||||
deprecated class SixToFiveDirective = Directive::SixToFiveDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::SystemJSFormatDirective` instead. */
|
||||
deprecated class SystemJSFormatDirective = Directive::SystemJSFormatDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::NgInjectDirective` instead. */
|
||||
deprecated class NgInjectDirective = Directive::NgInjectDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::YuiDirective` instead. */
|
||||
deprecated class YuiDirective = Directive::YuiDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::SystemJSDepsDirective` instead. */
|
||||
deprecated class SystemJSDepsDirective = Directive::SystemJSDepsDirective;
|
||||
|
||||
/** DEPRECATED. Use `Directive::BundleDirective` instead. */
|
||||
deprecated class BundleDirective = Directive::BundleDirective;
|
||||
|
||||
/**
|
||||
* An `if` statement.
|
||||
*
|
||||
|
||||
@@ -54,12 +54,3 @@ private class MyYmlNode extends Locatable instanceof YamlNode {
|
||||
|
||||
override string toString() { result = YamlNode.super.toString() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for YamlNode */
|
||||
deprecated class YAMLNode = YamlNode;
|
||||
|
||||
/** DEPRECATED: Alias for YamlValue */
|
||||
deprecated class YAMLValue = YamlValue;
|
||||
|
||||
/** DEPRECATED: Alias for YamlScalar */
|
||||
deprecated class YAMLScalar = YamlScalar;
|
||||
|
||||
@@ -88,12 +88,6 @@ module Connect {
|
||||
|
||||
override DataFlow::Node getServer() { result = server }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getARouteHandlerNode` instead.
|
||||
* Gets an argument that represents a route handler being registered.
|
||||
*/
|
||||
deprecated Expr getARouteHandlerExpr() { result = this.getARouteHandlerNode().asExpr() }
|
||||
|
||||
/**
|
||||
* Gets an argument that represents a route handler being registered.
|
||||
*/
|
||||
|
||||
@@ -28,9 +28,6 @@ class GwtHeader extends InlineScript {
|
||||
result = e.getStringValue()
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for getGwtVersion */
|
||||
deprecated string getGWTVersion() { result = this.getGwtVersion() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -183,14 +183,6 @@ module Vue {
|
||||
result = this.getAsClassComponent().getDecoratorOptions()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `getOwnOptions().getASink()`.
|
||||
*
|
||||
* Gets the options passed to the Vue object, such as the object literal `{...}` in `new Vue{{...})`
|
||||
* or the default export of a single-file component.
|
||||
*/
|
||||
deprecated DataFlow::Node getOwnOptionsObject() { result = this.getOwnOptions().asSink() }
|
||||
|
||||
/**
|
||||
* Gets the class implementing this Vue component, if any.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/javascript-queries
|
||||
pack: codeql/javascript-all
|
||||
extensible: requiredHelmetSecuritySetting
|
||||
data:
|
||||
- ["frameguard"]
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Provides classes for working with Helmet
|
||||
*/
|
||||
|
||||
private import javascript
|
||||
|
||||
/**
|
||||
* A write to a property of a route handler from the "helmet" module.
|
||||
*/
|
||||
class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite {
|
||||
ExpressLibraries::HelmetRouteHandler helmet;
|
||||
|
||||
HelmetProperty() {
|
||||
this = helmet.(DataFlow::CallNode).getAnArgument().getALocalSource().getAPropertyWrite()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the route handler associated to this property.
|
||||
*/
|
||||
ExpressLibraries::HelmetRouteHandler getHelmet() { result = helmet }
|
||||
|
||||
/**
|
||||
* Gets the boolean value of this property, if it may evaluate to a `Boolean`.
|
||||
*/
|
||||
predicate isFalse() { DataFlow::PropWrite.super.getRhs().mayHaveBooleanValue(false) }
|
||||
|
||||
/**
|
||||
* Gets the name of the `HelmetProperty`.
|
||||
*/
|
||||
string getName() { result = DataFlow::PropWrite.super.getPropertyName() }
|
||||
|
||||
/**
|
||||
* read from data extensions to allow enforcing custom settings
|
||||
*/
|
||||
predicate isImportantSecuritySetting() { requiredHelmetSecuritySetting(this.getName()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* defaults are located in `javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml`
|
||||
*/
|
||||
extensible predicate requiredHelmetSecuritySetting(string name);
|
||||
30
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.qhelp
Normal file
30
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.qhelp
Normal file
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Sensitive information included in a GitHub Actions artifact can allow an attacker to access
|
||||
the sensitive information if the artifact is published.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Only store information that is meant to be publicly available in a GitHub Actions artifact.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example uses <code>actions/checkout</code> to checkout code which stores the GITHUB_TOKEN in the `.git/config` file
|
||||
and then stores the contents of the `.git` repository into the artifact:
|
||||
</p>
|
||||
<sample src="examples/actions-artifact-leak.yml"/>
|
||||
<p>
|
||||
The issue has been fixed below, where the <code>actions/upload-artifact</code> uses a version (v4+) which does not include hidden files or
|
||||
directories into the artifact.
|
||||
</p>
|
||||
<sample src="examples/actions-artifact-leak-fixed.yml"/>
|
||||
</example>
|
||||
</qhelp>
|
||||
111
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.ql
Normal file
111
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.ql
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @name Storage of sensitive information in GitHub Actions artifact
|
||||
* @description Including sensitive information in a GitHub Actions artifact can
|
||||
* expose it to an attacker.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @id js/actions/actions-artifact-leak
|
||||
* @tags security
|
||||
* external/cwe/cwe-312
|
||||
* external/cwe/cwe-315
|
||||
* external/cwe/cwe-359
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.Actions
|
||||
|
||||
/**
|
||||
* A step that uses `actions/checkout` action.
|
||||
*/
|
||||
class ActionsCheckoutStep extends Actions::Step {
|
||||
ActionsCheckoutStep() { this.getUses().getGitHubRepository() = "actions/checkout" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `with:`/`persist-credentials` field sibling to `uses: actions/checkout`.
|
||||
*/
|
||||
class ActionsCheckoutWithPersistCredentials extends YamlNode, YamlScalar {
|
||||
ActionsCheckoutStep step;
|
||||
|
||||
ActionsCheckoutWithPersistCredentials() {
|
||||
step.lookup("with").(YamlMapping).lookup("persist-credentials") = this
|
||||
}
|
||||
|
||||
/** Gets the step this field belongs to. */
|
||||
ActionsCheckoutStep getStep() { result = step }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `with:`/`path` field sibling to `uses: actions/checkout`.
|
||||
*/
|
||||
class ActionsCheckoutWithPath extends YamlNode, YamlString {
|
||||
ActionsCheckoutStep step;
|
||||
|
||||
ActionsCheckoutWithPath() { step.lookup("with").(YamlMapping).lookup("path") = this }
|
||||
|
||||
/** Gets the step this field belongs to. */
|
||||
ActionsCheckoutStep getStep() { result = step }
|
||||
}
|
||||
|
||||
/**
|
||||
* A step that uses `actions/upload-artifact` action.
|
||||
*/
|
||||
class ActionsUploadArtifactStep extends Actions::Step {
|
||||
ActionsUploadArtifactStep() { this.getUses().getGitHubRepository() = "actions/upload-artifact" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `with:`/`path` field sibling to `uses: actions/upload-artifact`.
|
||||
*/
|
||||
class ActionsUploadArtifactWithPath extends YamlNode, YamlString {
|
||||
ActionsUploadArtifactStep step;
|
||||
|
||||
ActionsUploadArtifactWithPath() { step.lookup("with").(YamlMapping).lookup("path") = this }
|
||||
|
||||
/** Gets the step this field belongs to. */
|
||||
ActionsUploadArtifactStep getStep() { result = step }
|
||||
}
|
||||
|
||||
from ActionsCheckoutStep checkout, ActionsUploadArtifactStep upload, Actions::Job job, int i, int j
|
||||
where
|
||||
checkout.getJob() = job and
|
||||
upload.getJob() = job and
|
||||
job.getStep(i) = checkout and
|
||||
job.getStep(j) = upload and
|
||||
j = i + 1 and
|
||||
upload.getUses().getVersion() =
|
||||
[
|
||||
"v4.3.6", "834a144ee995460fba8ed112a2fc961b36a5ec5a", //
|
||||
"v4.3.5", "89ef406dd8d7e03cfd12d9e0a4a378f454709029", //
|
||||
"v4.3.4", "0b2256b8c012f0828dc542b3febcab082c67f72b", //
|
||||
"v4.3.3", "65462800fd760344b1a7b4382951275a0abb4808", //
|
||||
"v4.3.2", "1746f4ab65b179e0ea60a494b83293b640dd5bba", //
|
||||
"v4.3.1", "5d5d22a31266ced268874388b861e4b58bb5c2f3", //
|
||||
"v4.3.0", "26f96dfa697d77e81fd5907df203aa23a56210a8", //
|
||||
"v4.2.0", "694cdabd8bdb0f10b2cea11669e1bf5453eed0a6", //
|
||||
"v4.1.0", "1eb3cb2b3e0f29609092a73eb033bb759a334595", //
|
||||
"v4.0.0", "c7d193f32edcb7bfad88892161225aeda64e9392", //
|
||||
] and
|
||||
(
|
||||
not exists(ActionsCheckoutWithPersistCredentials persist | persist.getStep() = checkout)
|
||||
or
|
||||
exists(ActionsCheckoutWithPersistCredentials persist |
|
||||
persist.getStep() = checkout and
|
||||
persist.getValue() = "true"
|
||||
)
|
||||
) and
|
||||
(
|
||||
not exists(ActionsCheckoutWithPath path | path.getStep() = checkout) and
|
||||
exists(ActionsUploadArtifactWithPath path |
|
||||
path.getStep() = upload and path.getValue() = [".", "*"]
|
||||
)
|
||||
or
|
||||
exists(ActionsCheckoutWithPath checkout_path, ActionsUploadArtifactWithPath upload_path |
|
||||
checkout_path.getValue() + ["", "/*"] = upload_path.getValue() and
|
||||
checkout_path.getStep() = checkout and
|
||||
upload_path.getStep() = upload
|
||||
)
|
||||
)
|
||||
select upload, "A secret may be exposed in an artifact."
|
||||
@@ -0,0 +1,14 @@
|
||||
name: secrets-in-artifacts
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
a-job: # NOT VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
name: secrets-in-artifacts
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
a-job: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
@@ -24,7 +24,7 @@ A suitable [model pack](https://docs.github.com/en/code-security/codeql-cli/usin
|
||||
name: my-org/javascript-helmet-insecure-config-model-pack
|
||||
version: 1.0.0
|
||||
extensionTargets:
|
||||
codeql/java-all: '*'
|
||||
codeql/javascript-all: '*'
|
||||
dataExtensions:
|
||||
- models/**/*.yml
|
||||
```
|
||||
|
||||
@@ -12,30 +12,8 @@
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import DataFlow
|
||||
import semmle.javascript.frameworks.ExpressModules
|
||||
|
||||
class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite {
|
||||
ExpressLibraries::HelmetRouteHandler helmet;
|
||||
|
||||
HelmetProperty() {
|
||||
this = helmet.(DataFlow::CallNode).getAnArgument().getALocalSource().getAPropertyWrite()
|
||||
}
|
||||
|
||||
ExpressLibraries::HelmetRouteHandler getHelmet() { result = helmet }
|
||||
|
||||
predicate isFalse() { DataFlow::PropWrite.super.getRhs().mayHaveBooleanValue(false) }
|
||||
|
||||
string getName() { result = DataFlow::PropWrite.super.getPropertyName() }
|
||||
|
||||
predicate isImportantSecuritySetting() {
|
||||
// read from data extensions to allow enforcing custom settings
|
||||
// defaults are located in javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml
|
||||
requiredHelmetSecuritySetting(this.getName())
|
||||
}
|
||||
}
|
||||
|
||||
extensible predicate requiredHelmetSecuritySetting(string name);
|
||||
import semmle.javascript.frameworks.helmet.Helmet
|
||||
|
||||
from HelmetProperty helmetProperty, ExpressLibraries::HelmetRouteHandler helmet
|
||||
where
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
|
||||
- Added a new query (`js/actions/actions-artifact-leak`) to detect GitHub Actions artifacts that may leak the GITHUB_TOKEN token.
|
||||
@@ -0,0 +1,6 @@
|
||||
import { "Foo::new" as Foo_new } from "./foo.wasm"
|
||||
|
||||
const foo = Foo_new()
|
||||
|
||||
export { Foo_new as "Foo::new" }
|
||||
export type * as "Foo_types" from './mod'
|
||||
@@ -3,7 +3,8 @@ test_BulkReExportDeclarations
|
||||
test_ExportDeclarations
|
||||
| a.js:1:1:3:1 | export ... n 23;\\n} |
|
||||
| a.js:5:1:5:32 | export ... } = o; |
|
||||
| arbitarySpecifier.js:5:1:5:32 | export ... :new" } |
|
||||
| arbitrarySpecifier.ts:5:1:5:32 | export ... :new" } |
|
||||
| arbitrarySpecifier.ts:6:1:6:41 | export ... './mod' |
|
||||
| b.js:5:1:5:18 | export { f as g }; |
|
||||
| b.js:7:1:7:21 | export ... './a'; |
|
||||
| d.js:4:1:4:20 | export * from 'm/c'; |
|
||||
@@ -12,6 +13,7 @@ test_ExportDeclarations
|
||||
| es2015_require.js:3:1:3:25 | export ... ss C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; |
|
||||
| f.ts:5:1:5:24 | export ... oo() {} |
|
||||
| jsArbitrarySpecifier.js:5:1:5:32 | export ... :new" } |
|
||||
| m/c.js:5:1:5:30 | export ... '../b'; |
|
||||
| reExportNamespace.js:1:1:1:26 | export ... "./a"; |
|
||||
| tst.html:7:3:7:22 | export const y = 42; |
|
||||
@@ -19,11 +21,12 @@ test_ExportDefaultDeclarations
|
||||
| a.js:1:1:3:1 | export ... n 23;\\n} |
|
||||
| es2015_require.js:3:1:3:25 | export ... ss C {} |
|
||||
test_ExportSpecifiers
|
||||
| arbitarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | arbitarySpecifier.js:5:10:5:16 | Foo_new | arbitarySpecifier.js:5:10:5:30 | Foo_new ... o::new" |
|
||||
| arbitrarySpecifier.ts:5:10:5:30 | Foo_new ... o::new" | arbitrarySpecifier.ts:5:10:5:16 | Foo_new | arbitrarySpecifier.ts:5:21:5:30 | "Foo::new" |
|
||||
| b.js:5:10:5:15 | f as g | b.js:5:10:5:10 | f | b.js:5:15:5:15 | g |
|
||||
| e.js:2:10:2:10 | x | e.js:2:10:2:10 | x | e.js:2:10:2:10 | x |
|
||||
| e.js:2:13:2:13 | y | e.js:2:13:2:13 | y | e.js:2:13:2:13 | y |
|
||||
| e.js:3:10:3:21 | default as g | e.js:3:10:3:16 | default | e.js:3:21:3:21 | g |
|
||||
| jsArbitrarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | jsArbitrarySpecifier.js:5:10:5:16 | Foo_new | jsArbitrarySpecifier.js:5:10:5:30 | Foo_new ... o::new" |
|
||||
| m/c.js:5:10:5:15 | g as h | m/c.js:5:10:5:10 | g | m/c.js:5:15:5:15 | h |
|
||||
test_GlobalVariableRef
|
||||
| a.js:5:31:5:31 | o |
|
||||
@@ -43,7 +46,7 @@ test_ImportNamespaceSpecifier
|
||||
| exports.js:1:8:1:17 | * as dummy |
|
||||
| m/c.js:1:8:1:13 | * as b |
|
||||
test_ImportSpecifiers
|
||||
| arbitarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new | arbitarySpecifier.js:1:24:1:30 | Foo_new |
|
||||
| arbitrarySpecifier.ts:1:10:1:30 | "Foo::n ... Foo_new | arbitrarySpecifier.ts:1:24:1:30 | Foo_new |
|
||||
| b.js:1:8:1:8 | f | b.js:1:8:1:8 | f |
|
||||
| d.js:1:10:1:21 | default as g | d.js:1:21:1:21 | g |
|
||||
| d.js:1:24:1:29 | x as y | d.js:1:29:1:29 | y |
|
||||
@@ -53,12 +56,13 @@ test_ImportSpecifiers
|
||||
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | import-in-mjs.mjs:1:8:1:24 | exported_from_mjs |
|
||||
| import-ts-with-js-extension.ts:1:10:1:12 | foo | import-ts-with-js-extension.ts:1:10:1:12 | foo |
|
||||
| importcss.js:1:8:1:8 | A | importcss.js:1:8:1:8 | A |
|
||||
| jsArbitrarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new | jsArbitrarySpecifier.js:1:24:1:30 | Foo_new |
|
||||
| m/c.js:1:8:1:13 | * as b | m/c.js:1:13:1:13 | b |
|
||||
| reExportNamespaceClient.js:1:10:1:11 | ns | reExportNamespaceClient.js:1:10:1:11 | ns |
|
||||
| tst.html:5:10:5:10 | f | tst.html:5:10:5:10 | f |
|
||||
| unresolved.js:1:8:1:8 | f | unresolved.js:1:8:1:8 | f |
|
||||
test_Imports
|
||||
| arbitarySpecifier.js:1:1:1:50 | import ... o.wasm" | arbitarySpecifier.js:1:39:1:50 | "./foo.wasm" | 1 |
|
||||
| arbitrarySpecifier.ts:1:1:1:50 | import ... o.wasm" | arbitrarySpecifier.ts:1:39:1:50 | "./foo.wasm" | 1 |
|
||||
| b.js:1:1:1:20 | import f from './a'; | b.js:1:15:1:19 | './a' | 1 |
|
||||
| d.js:1:1:1:43 | import ... './a'; | d.js:1:38:1:42 | './a' | 2 |
|
||||
| d.js:2:1:2:13 | import './b'; | d.js:2:8:2:12 | './b' | 0 |
|
||||
@@ -68,6 +72,7 @@ test_Imports
|
||||
| import-in-mjs.mjs:1:1:1:46 | import ... n-mjs'; | import-in-mjs.mjs:1:31:1:45 | 'export-in-mjs' | 1 |
|
||||
| import-ts-with-js-extension.ts:1:1:1:29 | import ... /f.js"; | import-ts-with-js-extension.ts:1:21:1:28 | "./f.js" | 1 |
|
||||
| importcss.js:1:1:1:24 | import ... a.css"; | importcss.js:1:15:1:23 | "./a.css" | 1 |
|
||||
| jsArbitrarySpecifier.js:1:1:1:50 | import ... o.wasm" | jsArbitrarySpecifier.js:1:39:1:50 | "./foo.wasm" | 1 |
|
||||
| m/c.js:1:1:1:26 | import ... '../b'; | m/c.js:1:20:1:25 | '../b' | 1 |
|
||||
| reExportNamespaceClient.js:1:1:1:41 | import ... space"; | reExportNamespaceClient.js:1:20:1:40 | "./reEx ... espace" | 1 |
|
||||
| tst.html:5:3:5:20 | import f from 'a'; | tst.html:5:17:5:19 | 'a' | 1 |
|
||||
@@ -76,7 +81,8 @@ test_Module_exports
|
||||
| a.js:1:1:5:32 | <toplevel> | default | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| a.js:1:1:5:32 | <toplevel> | x | a.js:5:18:5:20 | f() |
|
||||
| a.js:1:1:5:32 | <toplevel> | y | a.js:5:25:5:25 | y |
|
||||
| arbitarySpecifier.js:1:1:5:32 | <toplevel> | Foo::new | arbitarySpecifier.js:5:10:5:16 | Foo_new |
|
||||
| arbitrarySpecifier.ts:1:1:6:41 | <toplevel> | Foo::new | arbitrarySpecifier.ts:5:10:5:16 | Foo_new |
|
||||
| arbitrarySpecifier.ts:1:1:6:41 | <toplevel> | Foo_types | arbitrarySpecifier.ts:6:13:6:28 | * as "Foo_types" |
|
||||
| b.js:1:1:8:0 | <toplevel> | f2 | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| b.js:1:1:8:0 | <toplevel> | g | b.js:5:10:5:10 | f |
|
||||
| e.js:1:1:4:0 | <toplevel> | g | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
@@ -85,21 +91,24 @@ test_Module_exports
|
||||
| es2015_require.js:1:1:3:25 | <toplevel> | default | es2015_require.js:3:16:3:25 | class C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | <toplevel> | exported_from_mjs | export-in-mjs.mjs:1:32:1:33 | 42 |
|
||||
| f.ts:1:1:6:0 | <toplevel> | foo | f.ts:5:8:5:24 | function foo() {} |
|
||||
| jsArbitrarySpecifier.js:1:1:5:32 | <toplevel> | Foo::new | jsArbitrarySpecifier.js:5:10:5:16 | Foo_new |
|
||||
| m/c.js:1:1:6:0 | <toplevel> | h | b.js:5:10:5:10 | f |
|
||||
| reExportNamespace.js:1:1:2:0 | <toplevel> | ns | reExportNamespace.js:1:8:1:14 | * as ns |
|
||||
| tst.html:4:23:8:0 | <toplevel> | y | tst.html:7:20:7:21 | 42 |
|
||||
test_NamedImportSpecifier
|
||||
| arbitarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new |
|
||||
| arbitrarySpecifier.ts:1:10:1:30 | "Foo::n ... Foo_new |
|
||||
| d.js:1:10:1:21 | default as g |
|
||||
| d.js:1:24:1:29 | x as y |
|
||||
| g.ts:1:9:1:11 | foo |
|
||||
| import-ts-with-js-extension.ts:1:10:1:12 | foo |
|
||||
| jsArbitrarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new |
|
||||
| reExportNamespaceClient.js:1:10:1:11 | ns |
|
||||
test_OtherImports
|
||||
| es2015_require.js:1:11:1:24 | require('./d') | d.js:1:1:5:0 | <toplevel> |
|
||||
| import-indirect-path.js:1:1:1:25 | require ... + '/a') | a.js:1:1:5:32 | <toplevel> |
|
||||
| import-indirect-path.js:5:1:5:14 | require(x + y) | a.js:1:1:5:32 | <toplevel> |
|
||||
test_ReExportDeclarations
|
||||
| arbitrarySpecifier.ts:6:1:6:41 | export ... './mod' | arbitrarySpecifier.ts:6:35:6:41 | './mod' |
|
||||
| b.js:7:1:7:21 | export ... './a'; | b.js:7:16:7:20 | './a' |
|
||||
| d.js:4:1:4:20 | export * from 'm/c'; | d.js:4:15:4:19 | 'm/c' |
|
||||
| e.js:3:1:3:35 | export ... './a'; | e.js:3:30:3:34 | './a' |
|
||||
@@ -117,16 +126,18 @@ test_getAnImportedModule
|
||||
| library-tests/Modules/m/c.js | library-tests/Modules/b.js |
|
||||
| library-tests/Modules/reExportNamespaceClient.js | library-tests/Modules/reExportNamespace.js |
|
||||
test_getExportedName
|
||||
| arbitarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | Foo::new |
|
||||
| arbitrarySpecifier.ts:5:10:5:30 | Foo_new ... o::new" | Foo::new |
|
||||
| arbitrarySpecifier.ts:6:13:6:28 | * as "Foo_types" | Foo_types |
|
||||
| b.js:5:10:5:15 | f as g | g |
|
||||
| b.js:7:8:7:9 | f2 | f2 |
|
||||
| e.js:2:10:2:10 | x | x |
|
||||
| e.js:2:13:2:13 | y | y |
|
||||
| e.js:3:10:3:21 | default as g | g |
|
||||
| jsArbitrarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | Foo::new |
|
||||
| m/c.js:5:10:5:15 | g as h | h |
|
||||
| reExportNamespace.js:1:8:1:14 | * as ns | ns |
|
||||
test_getImportedName
|
||||
| arbitarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new | Foo::new |
|
||||
| arbitrarySpecifier.ts:1:10:1:30 | "Foo::n ... Foo_new | Foo::new |
|
||||
| b.js:1:8:1:8 | f | default |
|
||||
| d.js:1:10:1:21 | default as g | default |
|
||||
| d.js:1:24:1:29 | x as y | x |
|
||||
@@ -135,22 +146,25 @@ test_getImportedName
|
||||
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | default |
|
||||
| import-ts-with-js-extension.ts:1:10:1:12 | foo | foo |
|
||||
| importcss.js:1:8:1:8 | A | default |
|
||||
| jsArbitrarySpecifier.js:1:10:1:30 | "Foo::n ... Foo_new | Foo::new |
|
||||
| reExportNamespaceClient.js:1:10:1:11 | ns | ns |
|
||||
| tst.html:5:10:5:10 | f | default |
|
||||
| unresolved.js:1:8:1:8 | f | default |
|
||||
test_getLocalName
|
||||
| arbitarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | Foo_new |
|
||||
| arbitrarySpecifier.ts:5:10:5:30 | Foo_new ... o::new" | Foo_new |
|
||||
| b.js:5:10:5:15 | f as g | f |
|
||||
| b.js:7:8:7:9 | f2 | default |
|
||||
| e.js:2:10:2:10 | x | x |
|
||||
| e.js:2:13:2:13 | y | y |
|
||||
| e.js:3:10:3:21 | default as g | default |
|
||||
| jsArbitrarySpecifier.js:5:10:5:30 | Foo_new ... o::new" | Foo_new |
|
||||
| m/c.js:5:10:5:15 | g as h | g |
|
||||
test_getSourceNode
|
||||
| a.js:1:1:3:1 | export ... n 23;\\n} | default | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| a.js:5:1:5:32 | export ... } = o; | x | a.js:5:18:5:20 | f() |
|
||||
| a.js:5:1:5:32 | export ... } = o; | y | a.js:5:25:5:25 | y |
|
||||
| arbitarySpecifier.js:5:1:5:32 | export ... :new" } | Foo::new | arbitarySpecifier.js:5:10:5:16 | Foo_new |
|
||||
| arbitrarySpecifier.ts:5:1:5:32 | export ... :new" } | Foo::new | arbitrarySpecifier.ts:5:10:5:16 | Foo_new |
|
||||
| arbitrarySpecifier.ts:6:1:6:41 | export ... './mod' | Foo_types | arbitrarySpecifier.ts:6:13:6:28 | * as "Foo_types" |
|
||||
| b.js:5:1:5:18 | export { f as g }; | g | b.js:5:10:5:10 | f |
|
||||
| b.js:7:1:7:21 | export ... './a'; | f2 | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| e.js:2:1:2:16 | export { x, y }; | x | e.js:2:10:2:10 | x |
|
||||
@@ -159,6 +173,7 @@ test_getSourceNode
|
||||
| es2015_require.js:3:1:3:25 | export ... ss C {} | default | es2015_require.js:3:16:3:25 | class C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; | exported_from_mjs | export-in-mjs.mjs:1:32:1:33 | 42 |
|
||||
| f.ts:5:1:5:24 | export ... oo() {} | foo | f.ts:5:8:5:24 | function foo() {} |
|
||||
| jsArbitrarySpecifier.js:5:1:5:32 | export ... :new" } | Foo::new | jsArbitrarySpecifier.js:5:10:5:16 | Foo_new |
|
||||
| m/c.js:5:1:5:30 | export ... '../b'; | h | b.js:5:10:5:10 | f |
|
||||
| reExportNamespace.js:1:1:1:26 | export ... "./a"; | ns | reExportNamespace.js:1:8:1:14 | * as ns |
|
||||
| tst.html:7:3:7:22 | export const y = 42; | y | tst.html:7:20:7:21 | 42 |
|
||||
|
||||
@@ -3,7 +3,6 @@ classDeclaration
|
||||
| test_tsx.vue:3:18:5:3 | class M ... er;\\n } |
|
||||
exprType
|
||||
| htmlfile.html:4:22:4:24 | foo | () => void |
|
||||
| htmlfile.html:4:22:4:24 | foo | () => void |
|
||||
| htmlfile.html:4:33:4:41 | "./other" | any |
|
||||
| htmlfile.html:5:17:5:22 | result | number[] |
|
||||
| htmlfile.html:5:26:5:28 | foo | () => void |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
| bar.ts:1:10:1:10 | A | any |
|
||||
| bar.ts:1:10:1:10 | A | any |
|
||||
| bar.ts:1:19:1:29 | "@blah/foo" | any |
|
||||
| bar.ts:3:5:3:5 | x | A |
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
| test.ts:1:10:1:12 | foo | () => any |
|
||||
| test.ts:1:10:1:12 | foo | () => any |
|
||||
| test.ts:1:21:1:25 | "foo" | any |
|
||||
| test.ts:3:1:3:3 | foo | () => any |
|
||||
| test.ts:3:1:3:5 | foo() | any |
|
||||
|
||||
@@ -474,7 +474,6 @@ getExprType
|
||||
| tst.ts:358:13:358:23 | tstModuleES | () => "a" \| "b" |
|
||||
| tst.ts:358:13:358:25 | tstModuleES() | "a" \| "b" |
|
||||
| tst.ts:360:10:360:21 | tstModuleCJS | () => "a" \| "b" |
|
||||
| tst.ts:360:10:360:21 | tstModuleCJS | () => "a" \| "b" |
|
||||
| tst.ts:360:30:360:49 | './tstModuleCJS.cjs' | any |
|
||||
| tst.ts:362:1:362:7 | console | Console |
|
||||
| tst.ts:362:1:362:11 | console.log | (...data: any[]) => void |
|
||||
|
||||
87
javascript/ql/test/query-tests/Security/CWE-312/.github/workflows/test.yml
vendored
Normal file
87
javascript/ql/test/query-tests/Security/CWE-312/.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
name: secrets-in-artifacts
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
test1: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
test2: # NOT VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
test3: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: "*"
|
||||
test4: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: foo
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: foo
|
||||
test5: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: foo
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: foo/*
|
||||
test6: # NOT VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: pr
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: foo
|
||||
test7: # NOT VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
test8: # VULNERABLE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: file
|
||||
path: .
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
| .github/workflows/test.yml:9:9:14:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||
| .github/workflows/test.yml:27:9:32:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||
| .github/workflows/test.yml:38:9:43:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||
| .github/workflows/test.yml:49:9:54:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||
| .github/workflows/test.yml:82:9:86:18 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-312/ActionsArtifactLeak.ql
|
||||
@@ -9,3 +9,4 @@
|
||||
| tst.js:35:13:35:43 | crypto. ... an(512) | Creation of an asymmetric key uses 512 bits, which is below 2048 and considered breakable. |
|
||||
| tst.js:39:13:39:33 | new Nod ... : 512}) | Creation of an asymmetric RSA key uses 512 bits, which is below 2048 and considered breakable. |
|
||||
| tst.js:43:1:43:31 | key.gen ... 65537) | Creation of an asymmetric RSA key uses 512 bits, which is below 2048 and considered breakable. |
|
||||
| tst.xsjs:3:14:3:71 | crypto. ... 1024 }) | Creation of an asymmetric RSA key uses 1024 bits, which is below 2048 and considered breakable. |
|
||||
|
||||
5
javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs
Normal file
5
javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs
Normal file
@@ -0,0 +1,5 @@
|
||||
const crypto = $.require("crypto");
|
||||
|
||||
const bad1 = crypto.generateKeyPairSync("rsa", { modulusLength: 1024 }); // NOT OK
|
||||
|
||||
const good1 = crypto.generateKeyPairSync("rsa", { modulusLength: 4096 }); // OK
|
||||
@@ -47,9 +47,6 @@ class OspreyMethodDefinition extends MethodCallExpr {
|
||||
/** Get the API to which this method belongs. */
|
||||
OspreyApi getApi() { this.getReceiver() = result.getAnAccess() }
|
||||
|
||||
/** DEPRECATED: Alias for getApi */
|
||||
deprecated OspreyApi getAPI() { result = this.getApi() }
|
||||
|
||||
/** Get the verb which this method implements. */
|
||||
string getVerb() { result = this.getMethodName() }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user