Category: Client-Side Security

Are my checkout forms filling attackers’ shopping bags this holiday season?

E-skimming attacks have become attackers’ favorite strategy for stealing payment card data. E-commerce skimming cases increased 174% in the 2022 June-November period compared to December 2021 and May 2022 (read Visa Spring 2023 Biannual Threats Report).

All e-commerce companies are at risk. Why?

E-commerce skimming is flourishing, with the majority of e-commerce sites exposed. 75% of all breaches Visa investigated last year involved e-commerce sites, with digital skimming attacks at the top.

Recognizing the inherent vulnerability of e-commerce websites and their web forms is vital to enhancing client-side security and keeping attackers away. Staying ahead of e-skimming attacks on the checkout pages is one of the challenges.

There are currently between 12 and 24 million online retailers worldwide. Moreover, if each of these online retailers includes at least two web forms in their e-commerce stores, the number of potential risks becomes overwhelming.

How many people are shopping online in 2023?

One in three people you see around you is an online shopper. In other words, 33.3% of the population worldwide belongs to the digital buyer category.

People shopping online has been growing over the past few years. 2023 has 80 million more digital buyers than in 2022, a 3.1% year-over-year increase.

The holiday shopping season, including Singles’ Day in China (and now, more widely), Black Friday, and Cyber Monday, with huge discounts, helps to spur shoppers to hop on the online shopping bandwagon.

More online sales, more security threats

The forecasts are that the number of online shoppers will continue increasing, rising to 2.71 billion in 2024 and 2.77 billion in 2025. The number and value of online sales are also on an upward trajectory. In 2024, e-commerce global sales will likely surpass $7 trillion in value.

Therefore, the potential of revenue for online retailers is tremendous, and the risks of e-commerce skimming attacks and e-commerce fraud increase along with it. Remember: The checkout pages are malicious actors’ favorite online store.

The good news and the bad news

The bad news is that third-party scripts and add-ons powering your business and website experience, such as chatbots and pixels, increase the surface area exposure for data leakage and web supply chain attacks.

The good news is that you can significantly mitigate the risk of data loss and e-skimming attacks by taking the proper security steps.

Three simple steps to website risk visibility with Jscrambler

Is your e-commerce or retail business aware of all the third-party scripts running your online storefront during the holiday shopping season? Do you understand how they are behaving, if data is being shared with digital partners, or worse, unknown domains?

In time for the upcoming holiday season, Jscrambler offers e-commerce and online retail businesses an easy way to ensure a secure checkout experience that customers can trust.

Follow these three steps to start your journey to a secure digital shopping experience.

  1. Provide your e-commerce URL.

  2. Receive and review a free inventory report detailing all scripts running on checkout pages.

  3. Hear from a Jscrambler specialist to verify if your forms are leaking data.

The free inventory report is yours to keep and share with your team. Here is some additional value you will receive from the report:

  • Get a snapshot of all third-party scripts on your e-commerce checkout pages and their network requests.

  • Understand script behaviors on your website.

  • Identify gaps outside of your web security perimeter.

  • Verify if your customers’ sensitive data, credit card information, and PII are safe.

  • See details of scripts displaying signs of misbehavior.

And more!

Connect client-side security with customer experience in one of the busiest times of the year: The holiday season. From Singles’ Day to Black Friday worldwide, identify the vulnerabilities of your web supply chain to stay ahead.

Why do secure e-commerce stores matter?

  • 41% of consumers trust digital service providers to keep personal data secure. 

  • 78% of online shoppers think twice about buying from an online retailer after a breach.

  • 75% of VISA breach investigations target e-skimming and third-party integrations on websites

*Sources: 

  • How consumers feel about retail data breaches – Help Net Security.

  • Visa biannual threats report.

Three questions to ask about your e-commerce store and client-side security

  • Are you aware of all third-party scripts running on your checkout pages?

  • How many third parties are on your e-commerce site?

  • How do you monitor and control potential web skimming behaviors?

Increase your visibility with Jscrambler Webpage Integrity. It is an easy and quick solution with real-time monitoring that facilitates compliance with the new PCI DSS v4 requirements for digital skimming protections.

Protect your business. Close the door to malicious actors’ favorite online store: Your Checkout Forms! Explore our e-commerce security infographic for more insights and tips.

e-commerce-security-and-payment-page-security-infographic-jscramblerDownload the infographic about e-commerce security.

Implementing Authentication in JavaScript with Express.js and MongoDB

This article walks you through implementing authentication in JavaScript with Express.js and MongoDB.

In today’s digital age, ensuring the security of web applications is more paramount than ever. When you sign into an application or buy online, mechanisms work behind the scenes to protect your identity and data. Two of the fundamental pillars of this security framework are authentication and authorization.

Authentication vs. Authorization: The Distinction

Both authentication and authorization might sound similar, but they have distinct roles in the web security world.

  • Authentication: At its core, this is about identity. When users provide credentials (a username and password, a fingerprint, or a facial scan), the system checks these details against a stored record. If they match, the user is authentic. It’s the process of ensuring you are who you claim to be.

  • Authorization: After determining who a user is through authentication, we decide what they can and cannot do. That’s where authorization comes in. It grants or denies permissions, like viewing a particular page, editing a document, or accessing certain functionalities.

In summary, authentication verifies users, and authorization defines user permissions.

Setting Up the Environment

Let’s navigate through the complexities of these processes, in which a structured environment is crucial.

Express.js will be our go-to framework for this guide. Through its strong presence in the world of web development, it offers the tools we need to create a robust backend system. Then there’s MongoDB, our chosen database. Suitable for handling vast amounts of data and known for its performance, MongoDB provides a sturdy foundation for our user data storage needs.

In this article, as we move forward, we’ll dive deep into the technicalities, ensuring that by the end, you have a solid grasp of implementing and managing authentication in web applications, always with authorization in mind.

List of Technologies for Authentication and Authorization

We want to remind you that building a robust authentication and authorization system is no small feat. It requires a combination of tools and technologies to ensure user data is secure and access is granted only to those who have the appropriate permissions.

Let’s break down the technologies we’ll be using for this tutorial.

1. Backend Framework: Express.js

Why Express.js?
Well, it’s a minimalistic yet powerful web application framework for Node.js. Also, it is flexible, easy to use, and has extensive middleware support. For our purpose, Express.js will serve as the backbone, managing our routes, requests, and responses.

2. Database: MongoDB

MongoDB is a NoSQL database that uses a document-oriented data model. This property makes MongoDB highly scalable and versatile, especially for applications with vast amounts of data or a need for flexibility in the data structure.

MongoDB will store user details, credentials, and roles for our authentication and authorization system.

3. Token Management: jsonwebtoken

JSON Web Tokens (JWT) provide a compact and self-contained method for securely transmitting information between parties.

In our setup, after the authentication of a user, they will be issued a JWT, which they can use to prove their identity for subsequent requests. The jsonwebtoken library makes creating and verifying these tokens straightforward.

In the coming sections, we’ll delve deeper into how these technologies interplay to provide a cohesive and secure system for managing user identity and permissions.

Setting Up User Registration and Login

1. Modeling Users: Setting up a User Schema or Model

When building a system that requires user registration and login, a foundational step is defining what information we need to store about each user, better known as the user schema (or model).

In the context of MongoDB and many other databases, a schema defines the structure of data: the attributes a dataset will hold, their type, and any default values or constraints they might have.

User Schema Basics
Username: A unique identifier for each user, either an email address or a unique username, depending on your preference.

  • Password: To securely store passwords, we’ll never save them in plain text. Instead, we’ll hash them using a cryptographic function, which turns the password into a string of characters. Even if someone gains unauthorized access to our database, deciphering the original password from the hash should be computationally challenging.

  • Roles: Depending on the complexity of your application, a user might have different roles, such as user, admin, or moderator. This field will store that role information, which will later inform our authorization system.

  • Date Created: An often overlooked but relevant attribute, this timestamp can help understand user demographics and some security protocols.

To set up this schema in a MongoDB and Express.js environment, we would typically use a package like Mongoose. This choice allows for easy modeling of our data and provides helpful validation and query-building tools.

Example User Schema with Mongoose:
Example-User-Schema-with-MongooseWith the schema defined, we’re now ready to handle user registration and login, ensuring that each user’s data fits and is stored securely.

2. Password Security: Using bcrypt for Hashing and Verifying Passwords

One of the fundamental rules of web security is to never store passwords in plain text.

If an unauthorized individual ever gains access to your database and finds unencrypted passwords, the damage potential is immense. So, how do we protect passwords? With hashing.

What is Hashing?

Hashing converts a piece of data, in this case, a password, into a fixed-size string of bytes. The result, typically, is a seemingly random string of characters. The beauty of hashing is its one-way nature given the hash, as you can’t revert to the original password.

Why bcrypt?

There are several hashing algorithms available, but not all are created equal, and some are easily susceptible to brute force attacks or rainbow table attacks: Bcrypt stands out as a robust choice for several reasons:

  • Salting: bcrypt automatically handles the generation of salt. It is a random value combined with the password before hashing. It will ensure that even if two users have the same password, their hashes will not match.

  • Adaptive: As computers become more powerful, hashing algorithms can become vulnerable. bcrypt is adaptive; the number of iterations (or the “cost”) increases as computers get faster, ensuring the hash remains hard to crack.

  • Widely Trusted: bcrypt has withstood the test of time and remains a gold standard in password hashing.

Implementing bcrypt in Express.js

To use bcrypt with our Express.js setup, we’ll start by installing the library:
start-by-installing-the-library-to-use-bcrypt-with-our-Express.js-setupThen, during user registration and login, we’ll leverage bcrypt to hash passwords and compare hashes:
leverage-bcrypt-to-hash-passwords-and-compare-hashesIt’s essential to note that while bcrypt offers solid password protection, it’s just one part of the game because combining it with other security measures ensures a more holistic safety net for your application.

3. Registration Endpoint: Handling New User Sign-ups

Users must register an account to access your application. Setting up a registration endpoint in Express.js allows users to do just that. This endpoint will be responsible for several things, namely:

  • Collecting user data

  • Validating the information

  • Hashing the password

  • Storing the new user in the database


Here’s a step-by-step breakdown:

Setting Up the Route

Start by defining the route that will handle user registration. It is typically a POST request, as you’re creating a new resource in the database.
Setting-Up-the-Route

Data Validation

Before we even consider saving data to the database, we must ensure it’s valid, and this could involve:

  • Checking that the required fields are provided.

  • Ensuring the username or email isn’t already registered.

  • Validating the password meets specific criteria (length, contains numbers/special characters, etc.)

Password Hashing

As discussed earlier, we’ll use bcrypt to hash the user’s password before saving it.

Saving The User

Once the data is validated and the password hashed, it’s time to save the new user to the database.
save-the-new-user-to-the-database

Response

After saving the user, you can respond with a success message or, in some cases, directly log the user in by issuing a JWT, which we’ll cover in subsequent sections.

Note: Ensure you exclude sensitive data like the hashed password when sending the user object in the response.

4. Login Endpoint: Validating Credentials and Generating a JWT for Authenticated Users

Once a user has registered, they need a way to log in, which involves verifying the user’s credentials and, upon successful validation, providing them with a token to authenticate subsequent requests.

Setting Up the Route

The login route will typically handle a POST request containing the user’s credentials (e.g., username and password).
setting-up-the-route

Verifying Credentials

The core of the login process is verifying if the provided credentials are correct, which we describe in detail:

  • Fetching the user from the database based on the provided identifier (e.g., username or email).

  • Using bcrypt to compare the stored hashed password with the hash of the entered password.

Generating a JWT

We generate a JWT to authenticate the user for subsequent requests upon successful validation. The token can hold claims about the user, such as their ID and roles.
Generating-a-JWT

Handling Responses

  • Successful Login: On successful validation, return the JWT to the user. This token will then be attached to subsequent requests to prove the user’s identity and role.

  • Unsuccessful Login: If the username is not found or the password doesn’t match, return a 401 Unauthorized response.

Remember, the JWT’s secret key (used for signing the token) should be kept secure and never exposed or hard-coded. Consider using environment variables or configuration management tools to keep it safe.

Implementing Token-based Authentication with JWT

JWT has become one of the most popular methods to implement authentication in modern web applications because its stateless and self-contained nature makes it especially suitable for distributed systems.

1. Generating Tokens: Using jsonwebtoken to Sign Tokens

JWT offers a compact, URL-safe way to represent claims between two parties. Regarding authentication, these “claims” typically represent the user’s identity and possibly roles or permissions.

Here’s a deeper dive into JWT creation.

Structure of a JWT

A JWT has three parts:

  • Header: Describes the type of token and the algorithm used for signing.

  • Payload: Contains the claims or data stored in the token. It can be a user ID, roles, or other data.

  • Signature: Ensures the integrity of the token. It results from encoding the header and payload using a secret key.

These sections are concatenated with periods, forming a string-like header.payload.signature.

Generating a JWT with jsonwebtoken

The jsonwebtoken library in Node.js makes generating JWTs straightforward. Here’s a basic approach:
Generating-a-JWT-with-jsonwebtoken

  • Payload: Here, we’re storing the user ID and roles. The payload can hold other data, but be cautious about not storing sensitive information.

  • Secret Key: Used to sign the JWT. This key must be confidential. If someone knows this key, they can forge tokens.

  • Options: The expiresIn option specifies the token’s lifetime. After this duration, the token will be invalid. This is a security measure to ensure that if a token is compromised, it won’t be valid indefinitely.

Benefits of Using JWT for Authentication

  • Statelessness: Servers don’t need to store session data because every request contains all the information a server needs to authenticate the user.

  • Scalability: Since there’s no session data to store, applications can scale without worrying about where a user gets authentication.

  • Decoupling: JWTs work across different domains. These domains make them suitable for microservices or systems where the authentication server differs from the resource server.

Sending Tokens: Sending the JWT to the Client upon Successful Login

Once the JWT is generated after the user logs in, the next step is to send this token to the client. This step is proof of authentication for the client’s subsequent requests.

Here are the methods for sending tokens to the client.

HTTP Only Cookies

One secure way to send the JWT is by using HTTP Only cookies. An HTTP Only cookie can’t be accessed via JavaScript on the client side, reducing the risk of exposing tokens through Cross-Site Scripting (XSS) attacks.
HTTP-Only-Cookies-to-send-JWTPros:

  • Better security against XSS.

  • Automatic sending with each HTTP request.

Cons:

  • Not suitable for cross-domain setups unless CORS settings are properly configured.

  • Might require additional handling to deal with token expiration and refresh scenarios.

Authorization Header

Another method involves sending the token in the response body after login, and then the client attaches it to the Authorization header for subsequent requests.
authorization-headerOn the client side, for every request:
every-request-from-the-client-sidePros:

  • Flexibility: It can go across domains.

  • Explicitly managed by client-side code.



Cons:

  • A token can be vulnerable if not stored securely on the client side.

  • Requires client-side logic to attach the token for every request.

Response Body

Upon successful authentication, you can send the token in the response body. The client then decides how to store it (e.g., in memory, local storage, etc.).
Response-BodyPros:

  • Straightforward implementation.

  • It gives the client freedom over where and how to store the token.

Cons:

  • The response body relies heavily on the client-side to manage the token securely.

  • The response body might expose the token to XSS if stored improperly.

Final Thoughts on Sending Tokens

Regardless of the chosen method, security should be a top priority. Always send tokens over HTTPS to prevent man-in-the-middle attacks.

Additionally, educate your frontend team (if separate) on the importance of securely managing and storing the token, especially if you’re sending it in the response body or using the Authorization header

Implementing Token-based Authentication with JWT

Validating Tokens: Using Middleware to Verify Tokens on Protected Routes

After sending a token to the client, we must ensure the authenticity of that token on subsequent requests. With the token’s validity verified, we can be confident about the user’s identity and grant access to protected resources.

Middleware in Express.js provides a mechanism to execute functions before reaching the route handlers. We can create a middleware function to validate JWTs.

Creating the Middleware

Before we access a protected route, we’ll verify the JWT sent with the request. Here’s a simple middleware function for token validation using jsonwebtoken:
Creating-the-Middleware

Applying Middleware to Routes

Once the middleware is defined, you can apply it to any route you wish to protect:
Applying-Middleware-to-Routes

Handling the Decoded Payload

After verifying the token, jsonwebtoken decodes the payload, and we attach it to the req.user object. This decoded payload helps route handlers understand more about the authenticated user, such as their roles or user ID.

Advantages of Token Validation:

  • Security: Protects sensitive routes from unauthorized access.

  • User Context: Gives route handlers context about the user, such as roles or permissions, which allows them to customize responses.

  • Flexibility: Middleware can be applied selectively, enabling fine-grained control over which routes are protected.

Potential Pitfalls:

  • Token Exposure: Ensure tokens are transmitted only over secure channels (HTTPS). Exposing tokens can lead to unauthorized access.

  • Performance: JWT verification involves cryptographic operations. Though these operations are optimized and fast, in high-traffic scenarios, every millisecond counts. It’s relevant to monitor system performance and scale appropriately.

Closing Thoughts: Understanding Our Digital Defenses

Thank you for staying with me through this exploration of authentication. Implementing authentication in JavaScript with Express.js and MongoDB is an essential topic, and I’m glad we could tackle it together.

Here’s a quick rundown of what we covered:

  • We clarified the difference between authentication and authorization. In basic terms, it’s about identifying users and determining what they can access.

  • We highlighted some key technologies and tools. You must know the tools that can best assist us in our mission for better security.

  • We delved into user management. It’s all about securely handling user registration and login processes.

  • Lastly, we introduced JWTs and their role in token-based authentication. They play a crucial role in making sure our user interactions are genuine.

Web security might seem vast and complex, but breaking it down step-by-step, as we did today, makes it more digestible, and trust me, this foundational knowledge will serve you well as we continue to navigate the landscape of web development together.

Stay tuned for our next article, where we’ll dive into Authorization and build upon the groundwork we’ve laid here.

E-skimming Attacks and the Reconciliation with Client-side Security

E-skimming attacks are client-side attacks that involve placing code onto a web page to steal sensitive data inputted by users into web forms.

Also referred to as digital skimming, web skimming, data skimming, or Magecart attacks, e-skimming attempts include the theft of many types of information. Most e-skimming attacks today are associated with payment card data.

Organizations and brands with forms on their websites are potential targets of e-skimming attacks, with several concerns that we must address:

  1. These client-side attacks can go undetected for months.

  2. PII, personal data, and payment card information exfiltration are significant threats.

Most e-skimming attacks take several weeks or months to identify.

Organizations that are victims of these digital skimming attacks tend to be blind to assets originating from outside of their security perimeter, including all their client-side web assets, allowing cybercriminals to exploit client-side supply chain attacks.

Client-side security incidents cause significant costs to companies, including regulatory sanctions, legal action, the costs of technical remediation, card scheme penalties, and disruption to their businesses until the incident is resolved and the business is made secure again.

E-skimming attacks, the e-commerce industry, and the overall picture

E-skimming attacks can be highly sophisticated and hard to detect.

E-commerce businesses are often the ones that suffer reputational damage and potential legal liabilities as a result of these attacks.

Generally, the attacker must get some criminal JavaScript onto the consumer’s browser. When the payment form is displayed, the attacker has already compromised it. The criminal’s Javascript can skim all the form fields.

The shopper types in the cardholder data and presses the submit button. The transaction goes through as usual: the consumer gets their goods or services, and the merchant gets their payment.

The process is transparent to the consumer and the merchant, and the transaction happens regularly. But the data is also exfiltrated to the attacker somewhere on the internet.

How does the attacker get their e-skimming code into the consumer’s page?

Follow the process below:

1. Initial Compromise

Attackers gain initial access to first- or third-party websites through several methods, such as exploiting vulnerabilities in the website’s software, deploying malware onto the site, or using stolen (or phished) credentials.

2. E-skimming Code Injection

Malicious e-skimming codes can follow different attack surfaces:

  • First-party.

Attackers inject malicious code into the website’s payment processing pages, designed to capture customer payment card information, including credit or debit card numbers, CVV2 codes, and other personal details.

Shortly, the first-party attack involves hacking the merchant’s website and adding their skimming code.

  • Third-party.

The attackers target a different entity that provides JavaScript to the merchant’s web pages.

These JavaScript supply chain attacks are on the rise because security teams cannot keep track of all the third-party scripts included in their websites. Attackers exploit this lack of visibility to introduce malicious code into the supply chain that their web page relies on.

In other words, the skimming code is inserted in third-party JavaScript and loaded from the third-party provider into the consumer’s browser.

3. Data Collection and Exfiltration

Data collection occurs when users enter their card details to complete their purchases on compromised payment pages, including checkout pages. The malicious code covertly skims and collects the information, often encrypting it, before being sent to the attacker’s remote server.

4. Monetization

Making money from data is why attackers carry out e-skimming attacks. Attackers will sell this information on the dark web to other cybercriminals or use it themselves to make unauthorized, fraudulent transactions for goods that they can easily convert into cash.

Who is the target, and who is the victim of e-skimming?

The target of e-skimming is the merchant or a third-party JavaScript provider. The victim of e-skimming is the online shopper. Why?

Because the skimming code process includes different scenarios, such as:

  • Gaining access to the victim’s network through a phishing email or brute force of administrative credentials;

  • Compromising third-party entities and supply chains, which may happen through hidden skimming code in JavaScript. The third-party service loads the skimming code onto the victim’s website.

Visa’s Spring 2023 Biannual Threats Report highlights that digital skimming attacks targeting customer data entered into payment forms on e-commerce checkout pages increased by 174% in the last half of 2022.

What can your business do to protect itself against e-skimming?

To protect your e-commerce business from e-skimming attacks and prevent unauthorized access to user’s sensitive data, consider the following security measures:

  • Regular Security Assessments: Conduct habitual security audits and vulnerability scans to identify and address potential weaknesses in your e-commerce website’s code and infrastructure.

  • Secure Coding Practices: Follow proper coding practices and guidelines to prevent common vulnerabilities that attackers may exploit.

  • Regular Monitoring: Set up continuous monitoring systems to detect any unusual or unauthorized activities on your website.

  • Payment Security Standards: The Payment Card Industry Data Security Standard’s new version (PCI DSS v4.0) requirements, for instance, help ensure the secure handling of payment card data. 

  • Third-Party Risk Management: Vet and monitor the security practices of third-parties, vendors, scripts, and partners interacting with your website. Be selective about which third-party providers you authorize to provide JavaScript that runs on your web pages, especially where sensitive data is collected.

What are the most common signs of e-skimming?

Here are some common signs and alerts online stores should monitor to detect and prevent potential e-skimming incidents:

  • Changes in JavaScript code and files

  • Detecting skimmer code patterns in website files 

  • Unauthorized changes in payment processing code

  • Suspicious user behavior during checkout

  • User complaints. These alerts might be mainly regarding suspicious activities during payment transactions.

Four Predictions by Jscrambler’s security advisor, John Elliott

Prediction 1

Hostile threat actors will use JavaScript skimming techniques to exfiltrate more than just cardholder data. 

Prediction 2

Managing the risk associated with JavaScript that executes in your customers’ browsers will become a regulatory requirement. Soon it will become what regulators consider an “appropriate” or “reasonable” thing to do.

Prediction 3

Managing JavaScript will be painful for many organizations.

Prediction 4

There will be a disconnect between regulatory opinion and what is practical. Documented risk assessment will be key.

Discover more predictions by John Elliott in his keynote presentation at the RSA Conference in San Francisco. John is a security advisor at Jscrambler and was one of the contributors to PCI DSS 4.0. His keynote presentation is about “Regulation and Risk When Your Customer’s Browser Leaks Data”.

Jscrambler Webpage Integrity Solution Against e-skimming Attacks

Jscrambler’s Webpage Integrity solution identifies all vendors and scripts touching forms and blocks all unauthorized access to sensitive data. Positive outcomes for your business include:

  • Minimize exposure to external JavaScript code.

  • Effective and cost-efficient compliance verification and auditing

  • Automatically block unauthorized scripts from accessing and transferring data entered into forms.

Get a snapshot of all the scripts on your website, their network requests, and threat insights with our comprehensive website report.

Schedule a meeting with Jscrambler security experts and get your free inventory report.

Jscrambler Recognized as a Sample Vendor in 2023 Gartner® Hype Cycle for Application Security

Porto, Portugal

1 September, 2023


Jscrambler, the leader in client-side security, today announces its inclusion for the third consecutive year in Gartner’s® 2023 Hype Cycle for Application Security. As a Sample Vendor for Web Application Client-Side Protection, Jscrambler delivers unprecedented security for websites and payment pages, streamlining compliance, visibility, and reporting.
 

The Hype Cycle for Application Security, 2023 edition, states that “Client-side attacks experienced in the wild have proven to be particularly impactful as they exploit the increasingly decentralized design of modern applications. In particular, single-page applications migrate the control and software logic on the client side, where it is exposed to attacks. For example, by injecting malicious scripts into JavaScript applications, attackers have lured thousands of visitors to banking and online commerce websites to hand over their credit card information”.

As most organizations grapple with the little visibility into client-side activity available, threats or misconfigurations can go unnoticed for long periods of time, leading to data leaks and malicious activity. Jscrambler Webpage Integrity (WPI) helps organizations gain control over their client-side security by providing easy and immediate visualization of all scripts running on a webpage or application. From there, Jscrambler WPI flags all behaviors understood as undesirable or suspicious to simplify threat analysis. 

“We are pleased to see our inclusion once again in the Hype Cycle for Application Security,” said Rui Ribeiro, CEO and co-founder of Jscrambler. “ In today’s web landscape, the norm is for modern web applications to include dozens of third-party scripts as part of the regular user experience app development. Integrating and relying on external code forms a web supply chain that represents a significant security blind spot that we are proactively addressing. The Gartner® Hype Cycle for Application Security, 2023 edition, recommends users: “Implement client-side security protection for critical web applications used to carry out bookings or transactions. Do so favoring approaches that monitor JavaScript and identify malicious, unsanctioned or abnormal behavior.”

Jscrambler WPI provides in-depth visibility over all code running on a website, both first and third-party while providing critical insights into the third-party code being utilized. By listing all vendors and scripts that touch sensitive data, providing any threats or risks associated with these vendors, and listing all sensitive data that has been exposed, businesses gain the protection of sensitive user data, situational awareness for informed threat mitigation, and an overall reduction in dwell and response time. 

About Jscrambler

Jscrambler is a leading authority in client-side security software. Its solution defends enterprises from revenue and reputational harm caused by accidental or intentional JavaScript misbehavior. Jscrambler makes first-party code that is resilient to tampering and prevents interference with third-party code. The solution works continuously, keeping organizations protected regardless of how frequently things change. From code to runtime, Jscrambler has companies covered with a level of visibility and control that supports business innovation. Jscrambler’s customers include the FORTUNE 500, retailers, airlines, banks, and other enterprises whose success depends on safely engaging with their customers online. Jscrambler keeps these interactions secure so they can continue to innovate without fear of damaging their revenue source, reputation, or regulatory compliance. Jscrambler was recently recognized as a winner in the 2023 BIG Innovation Awards.

GARTNER is a registered trademark and service mark of Gartner and Hype Cycle is a registered trademark of Gartner, Inc. and/or its affiliates in the U.S. and internationally and are used herein with permission. All rights reserved. Gartner does not endorse any vendor, product, or service depicted in its research publications and does not advise technology users to select only those vendors with the highest ratings or other designation. Gartner research publications consist of the opinions of Gartner’s research organization and should not be construed as statements of fact. Gartner disclaims all warranties, expressed or implied, with respect to this research, including any warranties of merchantability or fitness for a particular purpose.

Auto-F(a)illing Password Managers

Password managers are a valuable tool for individuals and organizations to enhance their digital security.

By securely storing and auto-filling login credentials, password managers offer convenience and the ability to generate strong, unique passwords. However, it’s vital to understand that password managers are not infallible.

This blog post dives into a potential security concern associated with auto-filling inputs and explores how users can mitigate the risks effectively.

The Danger of Automatic Auto-Filling

While password managers are designed to enhance security, their automatic auto-fill functionality can inadvertently introduce risks.

The primary danger lies in the possibility of a password manager automatically filling in credentials for untrusted or malicious websites. This scenario can occur when attackers manipulate website elements or create convincing phishing sites to deceive password managers.

If users unknowingly rely on automatic auto-fill without verifying the legitimacy of the page, their login credentials could be exposed to adversaries, potentially leading to account compromise.

Auto-Filling Sandboxed Iframes

In January, Google published an advisory informing users that “multiple password managers can be tricked into auto-filling credentials into untrusted pages“. Hence, it could “lead to account compromise for any users using these password managers“.

This was found to be happening on Safari browsers and in Bitwarden and DashLane extensions, where they would automatically auto-fill credentials in forms embedded into sandboxed iframes. By the time this advisory was published, these vulnerabilities had already been fixed.

What about Unsandboxed Iframes?

Our security research team performed tests on common browsers and password managers to determine how these would behave in the presence of same-origin and cross-origin iframes that were not sandboxed.

We created a test page that included four different scenarios when using iframes:

  • Same-Origin iframe without sandboxing;

  • Same-Origin iframe with sandboxing;

  • Cross-Origin iframe without sandboxing;

  • Cross-Origin iframe with sandboxing;

With these tests, we expect only the Same-Origin Iframes without sandboxing to be filled.

1. Firefox

We observed that the Firefox browser behaves as we expected. The autofill feature only fills the same-origin unsandboxed iframe and ignores all other cross-origin or sandboxed iframes.

Firefox-browser-only-auto-fills-the-same-origin-unsandboxed-iFrameImage 1: Firefox browser only auto-fills the same-origin unsandboxed iframe

2. Chrome

Similarly to Firefox, the Chrome browser also displays the correct behavior. The autofill feature will only fill the same-origin unsandboxed iframe, ignoring all other cross-origin or sandboxed iframes.

Chrome-browser-only-auto-fills-the-same-origin-unsandboxed-iFrameImage 2: Chrome browser only auto-fills the same-origin unsandboxed iframe

3. Edge

The Edge browser was found to display a slightly different behavior.

Even though it will still only autofill the password field on the same-origin unsandboxed iframe, as we expected, it will also autofill the username or email field in cross–origin or sandboxed iframes without warning the user that information will be sent to an external domain, which can be considered a security issue.

Edge-browser-auto-fills-username-or-email-fields-in-all-iFramesImage 3: Edge browser auto-fills username/email fields in all iframes

4. Bitwarden

BitWarden shows a warning prompt to the user, informing him that the credentials are about to be sent to a domain that is different from the current one.

This prompt lets the user decide whether he actually wants that form auto-filled or not, and if he accepts, the extension will auto-fill unsandboxed cross-origin iframes.

Bitwarden-extension-warning-the-user-about-auto-filling-cross-origin-iFramesImage 4: Bitwarden extension warning the user about auto-filling cross-origin iframes

Bitwarden-extension-filling-same-origin-and-cross-origin-iFrames-if-the-user-consentsImage 5: Bitwarden extension filling same-origin and cross-origin iframes, if the user consents

5. LastPass

Like BitWarden, LastPass will also show a warning prompt to the user, informing that the credentials are about to be sent to a domain that is different from the current one. If he accepts, the extension will also auto-fill unsandboxed cross-origin iframes.

LastPass-extension-warning-the-user-about-auto-filling-cross-origin-iFramesImage 6: LastPass extension warning the user about auto-filling cross-origin iframes


LastPass-extension-filling-same-origin-and-cross-origin-iFrames-if-the-user-consentsImage 7: LastPass extension filling same-origin and cross-origin iframes, if the user consents

6. Passbolt

From the password managers that were tested, Passbolt was found to be one of the most secure, as it does not auto-fill or even present the auto-fill option to the user, in cross-origin or sandboxed iframes.

Passbolt-extension-only-auto-fills-the-same-origin-unsandboxed-iFrameImage 8: Passbolt extension only auto-fills the same-origin unsandboxed iframe

7. 1Password

1Password did also display the behavior we were expecting. It does not auto-fill or even present the auto-fill option to the user in cross-origin or sandboxed iframes, just like Passbolt.

1Password-extension-only-auto-fills-the-same-origin-unsandboxed-iFrameImage 9: 1Password extension only auto-fills the same-origin unsandboxed iframe

Conclusion

While password managers are powerful tools for enhancing online security, users must remain vigilant and understand the potential risks associated with auto-fill functionality.

We suggest that users disable the automatic auto-fill feature on their password managers and instead choose to trigger the auto-fill manually only when they are confident that the form presented is legitimate and should be filled.

Remember, the key to secure password management lies not only in the technology but also in the user’s responsible and proactive approach to online security.

Validating your Email with Pure JavaScript

Email validation is necessary for today’s form development, as it prevents your email input from being infiltrated by cyber criminals and keeps malicious data from entering your system. It also helps you properly format and verify the email addresses of users and reject invalid addresses.

Although numerous built-in tools assist with email address validation, it is crucial to understand the fundamental steps and logic underlying email validation. In addition, some of these built-in tools cannot be customized. You will learn the importance of email validation from this article, as well as what Regular expression is, how to use it to validate emails with pure JavaScript, and how to modify your message.

Note: This form of validation is vulnerable if done simply on the front end because malicious users can easily bypass it. Therefore, backend validation serves as a second line of defense against invalid or malicious input.

What is Email Validation?

Let’s first discuss what validation is before discussing email validation, since before understanding email validation, you need to grasp what validation is.

So what is Validation in the context of form?
Validation is checking the values inputted by the user in a form. Validation plays a very important role in a web application as it helps keep the input sanitized and safe. Aside from that, it enhances the user experience.

What is Email Validation?
Email validation is a technique for determining whether or not an email address is valid and delivered. It also verifies whether an email address is associated with a trustworthy domain, such as Gmail or Yahoo. Users frequently enter their addresses incorrectly by failing to double-check for formatting or typographical errors.

Email validation is vital because it prevents the transmission of spam and unsolicited emails and improves the quality of your contact database by deleting irrelevant data. It can also be used for fraud prevention measures, particularly on an e-commerce website.

How to validate your Email with Pure JavaScript

Validating your email can be done in different forms as there are built-in tools to help you get started with email validation at a glance. Some of these tools have customized features. While these tools are there, you will learn how to Validate your email with pure Javascript using regular expressions.

Let’s study it before incorporating it into your application.

Regular Expression: a pattern of characters that is used for searching and replacing characters in strings. Regular expressions are also known as objects in Javascript. A regular expression might be as simple as a single character or as complex as a pattern.

A regular expression can be implemented in two ways: as a regular expression literal or RegExp() ****constructor function.

Regular expression literal:

    const regExp = /edbca/;

The regular expression above consists of a pattern enclosed between slashes.

RegExp() constructor function:

    const regExp = new RegExp('edbca');

A sample of the RegExp constructor function is shown in the code above. Keep in mind that there are two approaches to implementing regular expression; this is one of them.

RegExp includes several methods for finding the patterns you require in an email and validating emails. Explore other ways to apply RegExp, which include several methods.

Create form layout

In this section, you will create a basic HTML structure for your form. This form will contain an input field allowing users to enter their email addresses. Add the following code below to your HTML file:

        <form id="emailForm">
            <label for="email">Enter your email:</label>
           <input type="email" name="email" id="email">
            <button type="submit">Submit</button>
        </form>

Create a JavaScript file and Implement email validation

The final step is to create a Javascript file that will contain the email validation logic.

The first step is to build a Javascript method that retrieves a reference to an HTML element based on its ID attribute. The form element then has an event listener added. The submit event, which is set off when the form is submitted, will be listened to by this. The `validateEmail` function must now be called with warning messages if the user is valid or invalid, and a conditional statement must be used to determine whether the email the user entered is valid:

    <script>
        const emailForm = document.getElementById("emailForm");
        const emailInput = document.getElementById("email");
        emailForm.addEventListener("submit", function(event) {
           event.preventDefault();
            if (validateEmail(emailInput.value)) {
                alert("Email is valid!");
            } else {
                alert("Sorry, this email address is invalid")
           }
        });
       </script>

In the last stage, you’ll construct a function called `validateEmail` that accepts an email address as input. After that, you’ll create a variable with a regular expression pattern that will be used to validate the users’ emails. You must now check the user email result to determine if the pattern is present. You will use the regular expression `test()` function to accomplish that; recall that I stated previously in this post that there are too many methods for regular expression, and this is one of them.

You will determine whether the user-provided email matches the particular pattern in the variable const pattern. The function will return true if it does and false if otherwise:

    function validateEmail(email) {
            const pattern = /^[A-Za-z._-0-9]*[@][A-Za-z]*[.][a-z]{2,4}$/
            return pattern.test(email)
        }

In the above example, you constructed a pattern using the following elements in the regular expression: a series of letters, numbers, underscores, dots, or hyphens followed by @ symbols. then a top-level domain consisting of 2–4 characters follows.

Conclusion

Regular expression is an excellent approach for verifying emails; however, you must research the methods and understand which one best fits your email requirements, as there are several to choose from.

In this article, you learned how to validate an email using RegExp in pure JavaScript. This should get you started with email validation using Pure JavaScript.

Creating a simple and functional form using Netlify and Vue

The form is a highly important component in our software application, whether we are collecting user feedback, handling customer queries, or gathering user data. Having a well-designed functional form is essential for creating a good user experience.

We can collect user data using a variety of patterns and technologies. But in this article, we’ll look at a primary method for creating a powerful form: Netlify and Vue are the two examples.

Prerequisites for the creation of the form using Netlify and Vue

This article will be straightforward, as we don’t need any Netlify setup to create our form. But there are basic things we need to know and set up. This includes:

  • Basic knowledge of working or designing with Tailwind CSS

  • An updated version of Node is installed on our Computer

  • Netlify account created and setup

  • Vue project created and setup

Introduction to Netlify

Netlify is a cloud-based platform that facilitates website and web application management, development, and deployment. It leverages modern web development tools such as Git, Javascript, and API, which allow developers to build static websites with popular libraries and frameworks such as React, Vue, Angular, etc.

With the Netlify integration system, we can collaborate with other tools like Git, making it easier for us to deploy changes and collaborate with team members.

Designing the Form with Vue and Tailwind 

The correct tools and frameworks are critical when it comes to creating appealing and user-friendly web forms. Tailwind and Vue are excellent choices since they allow us to design beautiful forms.

The first step in constructing our form is to install Node on our Computer, then create our Vue project and incorporate TailwindCSS in the Vue Project created as indicated In terms of prerequisites.

Copy the code below and paste it inside the Vue component you created:

    <template>
        <section class="text-gray-600 body-font relative">
            <div class="container px-5 py-24 mx-auto flex sm:flex-nowrap flex-wrap">
                <div
                    class="lg:w-2/3 md:w-1/2 bg-gray-100 rounded-lg overflow-hidden sm:mr-10 p-10 flex items end justify-start relative">
                    <img class="object-cover object-center rounded" alt="hero" src="../assets/contact-image.png">
                </div>
                <div class="lg:w-1/3 md:w-1/2 bg-white flex flex-col md:ml-auto w-full md:py-8 mt-8 md:mt-0">
                    <h2 class="text-gray-900 text-2xl mb-1 font-bold title-font">Send us a Message now</h2>
                   <p class="leading-relaxed mb-5 text-gray-600 text-md"> You are only a few steps away from obtaining the information you require. However, if you send the message now, our team will contact you right away</p>
                    <form>
                        <p><input type="hidden" name="form-name" value="contact"></p>
                        <div class="relative mb-4">
                            <label for="name" class="leading-7 text-sm text-gray-600">Name</label>
                            <input type="text" id="name" name="name"

                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
                               >
                        </div>
                        <div class="relative mb-4">
                            <label for="email" class="leading-7 text-sm text-gray-600">Email</label>
                            <input type="email" id="email" name="email"
                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
                                >
                        </div>
                        <div class="relative mb-4">
                            <label for="message" class="leading-7 text-sm text-gray-600">Message</label>
                            <textarea id="message" name="message"
                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
                               ></textarea>
                        </div>
                        <button
                            class="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg
indigo-600 rounded text-lg"
                            type="submit" >Send</button>
                    </form>
                </div>
            </div>
        </section>
    </template>

This is how our application should look after implementing the code above.
After implementing the code, you should see a form with a bottom

Submitting the Form data with Netlify 

Now comes the exciting part. This is where we will learn the new way of submitting our form using a different method. Until now, Firebase and Appwrite have been solutions for collecting user data via a form. But this article will show a new method of implementing form solutions in our app.

Implementing the Netlify form in our app might be simple, but tricky. When constructing a Netlify form for a single-page application, we must create two forms, one of which will be copied into our public folder’s HTML file and the other into our Vue file.

When the build is finished, the Netlify build system detects our form by analyzing the HTML of our site. This means that if we use Javascript to render our form client-side, our build system will not detect the pre-built files.

So the ideal strategy is to create the form in our HTML file, then add the Netlify attributes and a hidden property to allow the Netlify system to identify our state after the build is finished. Here’s a code example of the HTML file:

     <form name="contact" method="POST" netlify hidden>
        <p><input type="hidden" name="form-name" value="contact"></p>
        <div class="relative mb-4">
          <label for="name" class="leading-7 text-sm text-gray-600">Name</label>
          <input type="text" id="name" name="name"
            class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out">
        </div>
        <div class="relative mb-4">
          <label for="email" class="leading-7 text-sm text-gray-600">Email</label>
          <input type="email" id="email" name="email"
            class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out">
        </div>
        <div class="relative mb-4">
          <label for="message" class="leading-7 text-sm text-gray-600">Message</label>
          <textarea id="message" name="message"
            class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"></textarea>
        </div>
        <button
          class="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded
text-lg">Button</button>
        <p class="text-xs text-gray-500 mt-3">Chicharrones blog helvetica normcore iceland tousled brook viral artisan.</p>
     </form>

Note: The hidden attribute will only be added to the HTML file. This is to prevent Vue from rendering two forms in our browser.

The second form for our Vue file will be created next. We’ll build a form tag with a name and method to accomplish this. The Netlify attribute will be added. This attribute will aid the Netlify system in detecting our form submission.  We’ll also include a hidden input, <input` `*type*“=”hidden”` `*name*“=”form-name” `*value*“=”contact”>, inside our form tag. See the following code example:

     <form name="contact" method="POST" netlify>
                        <p><input type="hidden" name="form-name" value="contact"></p>
                        <div class="relative mb-4">
                            <label for="name" class="leading-7 text-sm text-gray-600">Name</label>
                            <input type="text" id="name" name="name"
                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
                                v-model="form.name">
                        </div>
                        <div class="relative mb-4">
                            <label for="email" class="leading-7 text-sm text-gray-600">Email</label>
                            <input type="email" id="email" name="email"
                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
                                v-model="form.email">
                        </div>
                        <div class="relative mb-4">
                            <label for="message" class="leading-7 text-sm text-gray-600">Message</label>
                            <textarea id="message" name="message"
                                class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
                                v-model="form.message"></textarea>                        </div>
                        <button
                            class="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
                            type="submit" @click.prevent="formSubmit">Send</button>
                    </form>

We have added the Netlify attribute to our form. The next step is to submit the form. We will submit the form using Javascript. We create data that returns the name of our form, the v-model. Create two objects, encode, and formSubmit. The encoded object takes data as input and returns an object.keys(data) to extract an array of keys from the object, using the map function to iterate over each key and value in the array. 

We then create a method called formSubmit. When we submit a form, this method initiates a fetch request to the root path, which contains the post request and the header.

If the form is successfully submitted, the fetch request returns a promise that displays the success message on our console.

    <script>
    export default {
        data() {
            return {
                form: {
                    name: '',
                    email: '',
                    message: '',
                },
            };
        },
        methods: {
            encode(data) {
                return Object.keys(data)
                    .map(
                        key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`
                    )
                    .join('&');
            },
            formSubmit() {
                fetch('/', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: this.encode({ 'form-name': 'contact', ...this.form }),
                })
                    .then(() => console.log('You have sucessfully submitted the form'))
                    .catch(error => alert(error));
            },
        },
    };
    </script>

Please remember that after we deploy our form to Netlify, we must enable form detection on our Netlify dashboard to see the data submitted to our form console. Here’s an illustration of how to activate form detection:

example about how to activate form detection

Conclusion

Forms are the most common approach to adding interactivity to a page while also collecting useful data to further communicate with the audience.

Aside from the form submission, we can also protect our form using Akismet, which filters and restricts spam emails from users.

Can ChatGPT reverse engineer Jscrambler obfuscation?

ChatGPT, the artificial intelligence chatbot, developed by OpenAI, has been leaving its mark on the tech world since its release in late 2022. This tool has been eyed with suspicion by some and as a great asset by others. As the potential of ChatGPT (and of Generative AI in general) is unveiled, experts and developers keep asking questions and experimenting with the tool. Can it crack even the strongest protections applied to code? 

During the latest RSAC in San Francisco, where Jscrambler was present this past April, obfuscated JavaScript and the possibility of ChatGPT easily reversing that technique were a hot topic. Our team decided to take that challenge on and show that our JavaScript protection is something that not even the mighty ChatGPT can break. Let’s explain how your code is still protected with Jscrambler.

Can ChatGPT reverse Jscrambler’s obfuscation technique? 

The AI chatbot is currently in version 4, the most recent one available to users. What did we find? Our test consisted of feeding ChatGPT with an obfuscated JavaScript by Jscrambler Code Integrity and asking it to de-obfuscate it.

Firstly it’s important to state that yes, ChatGPT-4 can read a JavaScript source code, understand and explain what it does, and make changes to it. However, could it do the same if the JavaScript code has been obfuscated?

Testing

The following block of code was provided in the web interface of GhatGPT. The source code is a short program to draw a trapezoidal prism. This was minified when download for testing purposes.

block of code provided in the web interface of chatGPT for testing purposes

When ChatGPT was provided with a minified JavaScript, it easily “reversed” the process of minification through indentation and renaming variables based on its interpretation of the source code. Below, we can see the output delivered by the AI tool.

chatGPT “reversed” the process of minification through indentation

However, and most importantly, when provided with the obfuscated (by Jscrambler) version of the same source code, the output differs. When unable to de-obfuscate the source code by itself, ChatGPT doesn’t provide an output answer. It’s only capable of giving general directions about what the user could do manually to try to achieve that goal.

chatGPT is not able to de-obfuscate the source code provided by Jscrambler obfuscation tool

Jscrambler’s team discovered that ChatGPT is also capable of identifying some obfuscation techniques, even if it is unable to deobfuscate them.

ChatGPT is capable of dentifying some obfuscation techniques

GPT-4 is unable to directly execute code, so it’s very limited in its ability to deal with advanced obfuscation techniques. The Jscrambler team also asked the AI tool which obfuscation techniques are the most difficult or even impossible for it to crack, and it quickly enumerated the following techniques (all of which Jscrambler currently offers):

GPT-4 is unable to directly execute code but enumerated obfuscation techniques hard to crack, including Jscrambler features

Any attempt to automatically and fully de-obfuscate the JavaScript has failed for different reasons in different contexts:

  • Fails to process inputs with a considerable size of ~1kB or greater;
    • “The message you submitted was too long, please reload the conversation and submit something shorter.“
  • Refuses to do it for security or legal reasons;
    • “I apologize, but the code you provided appears to be obfuscated and potentially harmful. I cannot assist with executing or deobfuscating it. Is there anything else I can help you with?“
  • Provides a manual step-by-step process for the user to do;
  • Sometimes the resulting JavaScript is a completely different program (e.g. input is a program that draws a cube and output is a function to encrypt messages);
  • Sometimes deletes a considerable part of the JavaScript in the process;
  • Sometimes it outputs the same code.

The different results seem to be related to the context provided before the request to de-obfuscate the source code is made. For instance, it seems to be more successful in understanding the obfuscated source code in a conversation where the source code was previously provided.

On the other hand, if a conversation with the AI tool is started right away with the obfuscated source code, it’s more likely to lead to failure. Not everything is so easily achieved.

f a conversation with the AI tool is started right away with the obfuscated source code, it’s more likely to lead to failure

Conclusion

Our tests determined that ChatGPT-4 is a very limited tool as a de-obfuscation solution, showing some limitations in interpretation.

Obfuscation techniques that require programs to run (e.g., CFF, String Concealing) make it impossible for ChatGPT to interpret the source code and produce a simplified version of it. Although we weren’t able to run tests on techniques like self-defending or VM-based obfuscation it seems safe to assume that the results wouldn’t be much different.

ChatGPT seems to be a very useful tool for someone looking to understand the process of de-obfuscation/reverse engineering while having a more guided experience.

AI tools and artificial intelligence rise, in general, create new challenges for cybersecurity, with attackers conquering new assets to win more battles, according to an article from The Washington Post.

PCI SSC welcomes Jscrambler’s CTO Pedro Fortuna to its Board of Advisors

Lisbon, Portugal

Monday, June 5th 2023

Jscrambler, a leading solution for JavaScript protection and real-time webpage monitoring, is pleased to announce that its Chief Technology Officer and Cofounder, Pedro Fortuna, has been appointed to the 2023–2025 PCI Security Standards Council Board of Advisors. 

The Board of Advisors represents PCI SSC Participating Organizations worldwide to ensure global industry involvement in the development of PCI Security Standards and programs. Jscrambler’s own Pedro Fortuna is one of 52 board members to join the PCI Security Standards Council in its efforts to secure payment data globally. As strategic partners, board members bring industry, geographical, and technical insight to PCI SSC plans and projects. 

The PCI Security Standards Council is a global organization responsible for developing and maintaining the Payment Card Industry Data Security Standard (PCI DSS) and other important payment security standards.

The Council’s Board of Advisors is comprised of individuals with extensive expertise in payment security and related fields who are committed to advancing the Council’s mission of protecting payment card data worldwide.

Pedro Fortuna has over 20 years of experience in the security industry, including software design and engineering, and penetration testing. Fortuna has served as the CTO of Jscrambler since 2014, where he has been consistently at the helm of the company’s technical wing as well as participating in key business management decisions as a member of the board. 

“I am thrilled to be chosen as a participating member of the Board of Advisors for PCI SSC,” said Pedro Fortuna, CTO and Cofounder, Jscrambler. “Our main focus as a company is always to provide the highest level of client-side security, and that must come with regulatory requirements that span globally. We are grateful for the opportunity to provide insight and expertise with the holistic goal of improving payment security standards.”

PCI SSC Executive Director, Lance J. Johnson, said: “The Board of Advisors provides industry expertise and perspectives that influence and shape the development of PCI Security Standards and programs. We look forward to working with Jscrambler in our efforts to help organizations secure payment data globally.”

About Jscrambler

Jscrambler is a leading authority in client-side security software. Its solution defends enterprises from revenue and reputational harm caused by accidental or intentional JavaScript misbehavior. Jscrambler makes first-party code that is resilient to tampering and prevents interference with third-party code.

The solution works continuously, keeping organizations protected regardless of how frequently things change.

From code to runtime, Jscrambler has companies covered with a level of visibility and control that supports business innovation. Jscrambler’s customers include the Fortune 500, retailers, airlines, banks, and other enterprises whose success depends on safely engaging with their customers online. Jscrambler keeps these interactions secure so they can continue to innovate without fear of damaging their revenue source, reputation, or regulatory compliance.

Jscrambler was recently recognized as a winner in the 2023 BIG Innovation Awards.

About the PCI Security Standards Council

The PCI Security Standards Council (PCI SSC) leads a global, cross-industry effort to increase payment security by providing industry-driven, flexible, and effective data security standards and programs that help businesses detect, mitigate, and prevent cyberattacks and breaches.

Connect with the PCI SSC on LinkedIn. Join the conversation on Twitter @PCISSC. Subscribe to the PCI Perspectives Blog.

About how Jscrambler is helping companies comply with PCI DSS v4.0

Jscrambler’s free PCI DSS 4.0 compliance tool helps Merchants achieve compliance with requirements 6.4.3 and 11.6.1 of PCD DSS v4.0 and QSAs to validate compliance.

The only solution developed by

  • A PCI SSC Principal Participating Organization.

  • A member of the PCI SSC Board of Advisors.

  • A company with more than a decade of experience protecting JavaScript.

Request a PCI DSS Payment Page Analysis!

Working with Redux in Next.js

Redux is a state management tool for JavaScript applications. In this article, we’ll be using Redux with the Next.js app, but it can be used alongside any JavaScript framework. Today’s tutorial is about working with Redux in Next.js.

Redux provides a central store for the application state, providing a proper way to update the store values and fetch them. With a centralized store, it becomes easier to write applications and manage the state.

From official documentation, Redux is:

A Predictable State Container for JS Apps. Redux helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test.

Why do we need Redux?


One of the primary reasons for using Redux is to make it easy to share data between two components. This really comes in handy when the components we are trying to share data between are far away from each other in the component tree.


It creates a central store that is accessible from all over the application. Since it’s a central store, it becomes easier to understand how or when the state of the application has changed, and hence it’s predictable.


Using Redux in Next.js App


Creating the Next.js App


For working with Next.js, you’ll need Node.js 16.8 or above. Install it if you already don’t have it installed. We’ll be using `create-next-app` to create our Next.js app, and we’ll be using TypeScript in our project.

Create your app using `create-next-app`:

npx create-next-app next-redux-app --typescript


Once the installation starts, it will ask a few questions:

  • Would you like to use ESLint with this project? ***No*** 

  •  Would you like to use Tailwind CSS with this project? ***No***

  • Would you like to use `src/` directory with this project? ***Yes***

  • Would you like to use the experimental `app/` directory with this project? ***No***

  • What import alias would you like configured? ***Press Enter***


Enter the answers as shown in the above list and it will create your Next.js app with the required dependencies installed.

Navigate to the project directory and start the project.

cd next-redux-app
npm run dev


Point your browser to http://localhost:3000 and you will have the Next.js app running with the boilerplate code.

Adding Redux to Project


You’ll be needing a Redux toolkit. Let’s start by adding it to the project.

npm install @reduxjs/toolkit --save


The `–save` option adds the package dependency to the `package.json` file.

You’ll also be using `next-redux-wrapper` since we are working with Redux with the Next.js framework.


Creating Slice

A state is an object that contains information about a component, and a `slice` is actually a portion of the state representing a particular feature. Multiple slices come together to create a Redux state.

Create a folder called redux inside your `src` folder and add a file called `cartSlice.ts`. This slice is related to the Cart feature and may contain information related to the cart like the total amount, the total number of items, etc.

Inside `cartSlice.ts` start by importing `createSlice` from `reduxjs/toolkit` which will be used for creating the slice.

import { createSlice } from  "@reduxjs/toolkit";


Next, define a default state or initial state for the `cartSlice`.

// ## CartState Interface
export interface CartState {
    itemsInCart: number;
    totalAmount: number;
}
// ## Define the initial state of Cart State 
const initialState: CartState = {
    itemsInCart: 0,
    totalAmount: 0
};


Now, using the initial state, let’s create the slice.

export const cartSlice = createSlice({
    name: "cart",
    initialState,
    reducers: {
        setItemsInCart(state, action) {
            state.itemsInCart = action.payload;
        }, 
        setTotalAmount(state, action) {
            state.totalAmount = action.payload;
        }
    }
});


`createSlice` takes in an object where you need to specify the name of the slice, the initial state of the slice, and `reducers`. `reducers` are functions that help in updating the state. In the above code, you can see `setItemsInCart` and `setTotalAmount` which help in updating the respective state variables.

`createSlice` returns an object as a response that has `actions`,`name`, and `reducer`. `actions` in response is the same function name as passed in `reducers` during creating a slice. You’ll need to export it so it can be used for setting the state value.

export  const { setItemsInCart, setTotalAmount } = cartSlice.actions;


`createSlice` also returns a `reducer` function, which will be used while creating the redux store. Here are the complete `cartSlice.ts`.

import { createSlice } from "@reduxjs/toolkit";
import { AppState } from "./store";

// ## CartState Interface
export interface CartState {
    itemsInCart: number;
    totalAmount: number;
}

// ## Define the initial state of Cart State 
const initialState: CartState = {
    itemsInCart: 0,
    totalAmount: 0
};

export const cartSlice = createSlice({
    name: "cart",
    initialState,
    reducers: {
        setItemsInCart(state, action) {
            state.itemsInCart = action.payload;
        }, 
        setTotalAmount(state, action) {
            state.totalAmount = action.payload;
        }
    }
});
export const { setItemsInCart, setTotalAmount } = cartSlice.actions;

export default cartSlice.reducer; 


Creating Store

A store can be considered a collection of different reducer functions like the one we defined above, `createSlice`. It holds the complete state of the application.
 

For this, create a file called `store.ts` inside the `redux` folder.

Import the `configureStore`, `cartSlice`, and `createWrapper` from the respective libraries.

import { configureStore } from  "@reduxjs/toolkit";
import { cartSlice } from  "./cartSlice";
import { createWrapper } from  "next-redux-wrapper";


Using `configureStore` creates the store by passing the `cartSlice` reducers.

const makeStore = () =>
  configureStore({
    reducer: {
      [cartSlice.name]: cartSlice.reducer,
    },
    devTools: true,
  });


You can also pass multiple reducers. Next, you need to pass the makeStore method to the `createWrapper` method and export it.

export type AppStore = ReturnType<typeof makeStore>;
export type AppState = ReturnType<AppStore["getState"]>;
export const wrapper = createWrapper<AppStore>(makeStore);


Here are the complete `store.ts`.

import { configureStore } from "@reduxjs/toolkit";
import { cartSlice } from "./cartSlice";
import { createWrapper } from "next-redux-wrapper";

const makeStore = () =>
  configureStore({
    reducer: {
      [cartSlice.name]: cartSlice.reducer,
    },
    devTools: true,
  });

export type AppStore = ReturnType<typeof makeStore>;
export type AppState = ReturnType<AppStore["getState"]>;
export const wrapper = createWrapper<AppStore>(makeStore);


Connecting App to Store


Go to your `_app.tsx` file and import `wrapper` from `store.ts`.

import { wrapper } from  "../redux/store"


Now instead of importing the App, you wrap it up using the `wrapper` and export.

import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import { wrapper } from "../redux/store"

function App({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

export default wrapper.withRedux(App)


Getting and Updating Store Values


You already exported a method to update the cart values using `setItemsInCart` and `setTotalAmount`. To get the store values, you need to export another method in `cartSlice.ts`.

export  const  getItemsInCart = (state: AppState) =>  state.cart.itemsInCart;
export  const  getTotalAmount = (state: AppState) =>  state.cart.totalAmount;


The above two methods, `getItemsInCart` and `getTotalAmount`, get the store values. Here is the modified `cartSlice.ts` file.

import { createSlice } from "@reduxjs/toolkit";
import { AppState } from "./store";

// ## CartState Interface
export interface CartState {
    itemsInCart: number;
    totalAmount: number;
}

// ## Define the initial state of Cart State 
const initialState: CartState = {
    itemsInCart: 0,
    totalAmount: 0
};

export const cartSlice = createSlice({
    name: "cart",
    initialState,
    reducers: {
        setItemsInCart(state, action) {
            state.itemsInCart = action.payload;
        }, 
        setTotalAmount(state, action) {
            state.totalAmount = action.payload;
        }
    }
});

export const { setItemsInCart, setTotalAmount } = cartSlice.actions;

export const getItemsInCart = (state: AppState) => state.cart.itemsInCart;
export const getTotalAmount = (state: AppState) => state.cart.totalAmount;

export default cartSlice.reducer; 


Now let’s see how you use the Redux store to get and set values. Go to `index.tsx` file and replace the existing code with the following code:

export default function Home() {  const itemsInCart:any = 0;

  const addItemsToCart = () => { 
 }
  
  return (
    <>
      <h2>
        Items in Cart : {itemsInCart}
      </h2>
      <button value="Add" type="button" onClick={addItemsToCart}>
        Add
      </button>
    </>
  )
}


Now if you run your application, you’ll be able to see a UI with a counter and a button. So that counter indicates the number of items in the cart, which we’ll get from `getItemsInCart`.

To get data from Redux stores, we’ll make use of `useSelector` and `getItemsInCart`. Let’s import those first,

import { getItemsInCart } from  "@/redux/cartSlice";
import{useSelector}from  "react-redux";


Then you use the above to fetch the store value for `itemsInCart`

const  itemsInCart:any = useSelector(getItemsInCart);


Similarly, to update the store value of `itemsInCart` you need to import  `useDispatch` and `setItemsInCart`.

import { setItemsInCart } from  "@/redux/cartSlice";
import { useDispatch } from  "react-redux";
And on the button click you need to increment the existing value by one.
  const addItemsToCart = () => {
    dispatch(setItemsInCart(parseInt(itemsInCart)+1))
  }


Here is how the modified `index.tsx` file looks:

import { getItemsInCart, setItemsInCart } from "@/redux/cartSlice";
import { useSelector, useDispatch } from "react-redux";

export default function Home() {
  const itemsInCart: any = useSelector(getItemsInCart);
  const dispatch = useDispatch();

  const addItemsToCart = () => {
    dispatch(setItemsInCart(parseInt(itemsInCart) + 1))
  }

  return (
    <>
      <h2>
        Items in Cart : {itemsInCart}
      </h2>
      <button value="Add" type="button" onClick={addItemsToCart}>
        Add
      </button>
    </>
  )
}


Save the above changes and check the application’s UI. Initially, it will show the default or initial state value. At the click of a button, the value increments by one.

Wrapping It Up

In this tutorial, you learned about Redux, why we need it in our applications, and how to use and set up Redux in your Next.js application by creating a slice and store.

This is just the tip of the iceberg, and there are many other features in Redux that we can discuss in upcoming tutorials.