javascript.jose.security.audit.jose-exposed-data.jose-exposed-data

profile photo of semgrepsemgrep
Author
3,440
Download Count*

The object is passed strictly to jose.JWT.sign(...) Make sure that sensitive information is not exposed through JWT token payload.

Run Locally

Run in CI

Defintion

rules:
  - id: jose-exposed-data
    message: The object is passed strictly to jose.JWT.sign(...) Make sure that
      sensitive information is not exposed through JWT token payload.
    metadata:
      owasp:
        - A02:2017 - Broken Authentication
        - A04:2021 - Insecure Design
      cwe:
        - "CWE-522: Insufficiently Protected Credentials"
      source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
      asvs:
        section: "V3: Session Management Verification Requirements"
        control_id: 3.5.2 Static API keys or secret
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management
        version: "4"
      category: security
      technology:
        - jose
        - jwt
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      references:
        - https://owasp.org/Top10/A04_2021-Insecure_Design
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cryptographic Issues
    languages:
      - javascript
      - typescript
    severity: WARNING
    patterns:
      - pattern-inside: |
          require('jose');
          ...
      - pattern-either:
          - patterns:
              - pattern-inside: function (...,$INPUT,...) {...}
              - pattern-either:
                  - pattern: $JOSE.JWT.sign($INPUT,...)
                  - pattern: $JWT.sign($INPUT,...)
          - patterns:
              - pattern-inside: function $F(...,$INPUT,...) {...}
              - pattern-either:
                  - pattern: $JOSE.JWT.sign($INPUT,...)
                  - pattern: $JWT.sign($INPUT,...)

Examples

jose-exposed-data.js

const config = require('./config')
const {JWT} = require('jose')

function example(user) {
    // ruleid: jose-exposed-data
    const token = JWT.sign(user, secret)
    return token;
}

function example2(user) {
    // ok: jose-exposed-data
    const token = JWT.sign({name: user.name}, secret)
    return token;
}

function example3(user) {
    // ok: jose-exposed-data
    const obj = {
        name: user.name
    }
    const token = JWT.sign(obj, secret)
    return token;
}

module.exports = {
    siteMetadata: {
      title: "blah",
      titleTemplate: "%s",
      tagline: "blah",
      author: "blah",
      imageUrl: "https://stuff-n-things.com/static/",
      description:
        "blah",
      keywords: `blah`,
    },
    plugins: [
      "gatsby-plugin-react-helmet",
      "gatsby-plugin-sitemap",
      {
        resolve: `gatsby-source-filesystem`,
        options: {
          name: `images`,
          path: `${__dirname}/src/images`,
        },
      },
      {
        resolve: `gatsby-source-filesystem`,
        options: {
          name: "pages",
          path: `${__dirname}/src/pages`,
        },
      },
      {
        resolve: `gatsby-source-filesystem`,
        options: {
          name: `blog`,
          path: `${__dirname}/src/pages/blog`,
        },
      },
      {
        resolve: `gatsby-plugin-manifest`,
        options: {
          name: `blah`,
          short_name: `blah`,
          start_url: `/`,
          background_color: `#ffffff`,
          theme_color: `#ffffff`,
          display: `standalone`,
          icon: "src/images/favicon.png",
        },
      },
      "gatsby-plugin-offline",
      {
        resolve: "gatsby-plugin-google-tagmanager",
        options: {
          id: "GTM-XXXXXXX",
          includeInDevelopment: true,
          defaultDataLayer: { platform: "gatsby" },
        },
      },
      {
        resolve: `gatsby-transformer-remark`,
        options: {
          plugins: [
            {
              resolve: `gatsby-remark-social-cards`,
            },
            {
              resolve: `gatsby-remark-embedder`,
            },
            {
              resolve: `gatsby-remark-images`,
              options: {
                maxWidth: 1200,
              },
            },
            `gatsby-remark-responsive-iframe`,
            {
              resolve: "gatsby-remark-embed-youtube",
              options: {
                width: 640,
                height: 360,
                related: false,
                noIframeBorder: true,
              },
            },
            {
              resolve: `gatsby-remark-prismjs`,
              options: {
                classPrefix: "language-",
                inlineCodeMarker: null,
                aliases: {},
                showLineNumbers: false,
                noInlineHighlight: false,
              },
            },
            {
              resolve: "gatsby-remark-external-links",
              options: {
                target: "_blank",
                rel: "noopener",
              },
            },
            {
              resolve: `gatsby-remark-copy-linked-files`,
              options: {
                ignoreFileExtensions: [
                  `png`,
                  `jpg`,
                  `jpeg`,
                  `bmp`,
                  `tiff`,
                  `pdf`,
                ],
              },
            },
          ],
        },
      },
      "gatsby-plugin-twitter",
      "gatsby-transformer-sharp",
      "gatsby-plugin-sharp",
      `gatsby-plugin-sass`,
      {
        resolve: `gatsby-plugin-google-analytics`,
        options: {
          trackingId: "UA-XXXXXXXXX",
          anonymize: true,
        },
      },
      {
        resolve: `gatsby-plugin-sitemap`,
        options: {
          output: `/sitemap.xml`,
          query: `
          {
            site {
              siteMetadata {
                siteUrl
              }
            }
            allSitePage(
              filter: {isCreatedByStatefulCreatePages: {eq: true}}
              ) {
              edges {
                node {
                  path
                }
              }
            }
            allMarkdownRemark(
              filter: {frontmatter: {unlisted: {ne: true}}}
            ) {
              edges {
                node {
                  fields {
                    slug
                  }
                }
              }
            }
          }`,
          serialize: ({ site, allSitePage, allMarkdownRemark }) => {
            let pages = [];
            allSitePage.edges.map((edge) => {
              pages.push({
                url: site.siteMetadata.siteUrl + edge.node.path,
                changefreq: `daily`,
                priority: 0.7,
              });
            });
            allMarkdownRemark.edges.map((edge) => {
              pages.push({
                url: site.siteMetadata.siteUrl + edge.node.fields.slug,
                changefreq: `daily`,
                priority: 0.7,
              });
            });
            return pages;
          },
        },
      },
    ],
  };