-
Notifications
You must be signed in to change notification settings - Fork 36
Frontend Attacks
OWASP – A7:2017
Cross-site scripting (XSS) is a vulnerability class related to web application input and output validation. In cross-site scripting, the application accepts input from an end user and returns it in a response without properly encoding HTML metacharacters. This allows an attacker to inject JavaScript code into the resulting page.
Reflected XSS occurs when some supplied input is returned immediately in the application's response without encoding. Test for reflected XSS by submitting payloads to all parameters for the application and checking that the response does not contain any payload reflected without correct encoding.
Reflected XSS can be exploited by causing the victim to click a link, view an attacker-controlled website, or even by browsing to a legitimate site where the attacker can place a malicious advertisement.
Stored XSS occurs when the application accepts input from an end user, stores it, and later displays it without properly encoding HTML metacharacters. Test for stored XSS concurrently with reflected XSS, but be aware that the input may appear in a completely separate location of the application.
In the case of stored XSS, the attacker generally does not need to leverage an element of social engineering (in the form of a link to click on or an email), increasing the likelihood of victims being exposed to the exploit code. A user may fall victim to the attack just by using the application.
If the application allows file uploads, all user-uploaded content should be returned with the Content-Disposition: Attachment header that instructs the browser to download (rather than display) the content. Otherwise, check that the filename, extension, and file contents are all handled securely to prevent XSS.
DOM (Document Object Model) XSS refers to any situation where XSS occurs as a result of client-side JavaScript unsafely handling some data on the client side, such as an API response or the URL anchor (location.hash). Test for DOM XSS concurrently with other types, but be aware that some HTML elements will not be evaluated when inserted into the DOM using JavaScript, including <script> elements. Test using a payload such as '"><img src=x onerror='alert(/xss/)'>, which will evaluate in many situations regardless of how the input is rendered. A tool such as NCC Group's tracy may assist in identifying input sources which are likely to lead to exploitable vulnerabilities.
DOM XSS can be reflected or stored.
DOM XSS can be more effectively tested by auditing JavaScript source code for usage of unsafe functions that do not perform output encoding, such as .innerHTML or jQuery's .html(), .append(), etc. There are many possible unsafe functions (examples include eval() and Angular JS templates), as well as many possible sources of unsafe input (for example, window.postMessage). See DOMXSS Wiki on Github for an introduction.
Web browsers rely on the HTTP Content-Type header to determine how to handle responses from web applications, whether that content is HTML, JavaScript, an image, or something else. If an application returns an invalid or incorrect Content-Type, browsers will still attempt to parse the response, but often behave unexpectedly or insecurely.
Check that all responses from the web application have a correct, valid Content-Type header. If an incorrect content type is returned, attempt to insert HTML into the response in order to cause XSS.
Browsers contain a number of APIs allowing for cross-site client-side communication. Generally, applications must explicitly protect themselves from malicious cross-site requests.
Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a user loads or interacts with an untrusted web site while logged into a vulnerable application in the same browser. The untrusted web site can cause the user's browser to submit requests (including the user's cookies) to any other site; vulnerable sites cannot differentiate between a legitimate request from the user and malicious requests submitted by other sites. Because an attacker cannot directly steal response data, CSRF attacks primarily target requests that a user would use to perform an action within the application (called "state-changing requests").
Verify that the application employs working CSRF protections, that all state-changing routes have CSRF protection applied, and that no GET or HEAD routes allow state-changing functionality. For an introduction to CSRF prevention in modern applications, read Filippo Valsorda's post discussing common patterns and recommending the use of the Sec-Fetch-Site header.
Cross-Origin Resource Sharing (CORS) is a browser standard which allows for the resources or functionality of a web application to be accessed by other web pages originating from a different domain. CORS allows applications to extend the types of cross-site requests they can make, and to read the response to those requests. Applications can opt-in to CORS by returning Access-Control HTTP headers with responses.
If the application returns CORS headers, check which headers are returned and what the effect is to a requesting site. The two most important headers are:
-
Access-Control-Allow-Origin: a domain (or wildcard) which the application wants to allow communication from -
Access-Control-Allow-Credentials: true if the application wants to allow credentials (cookies)
For more information, see Exploiting CORS Misconfigurations for Bitcoins and Bounties on the PortSwigger blog.
A websocket is a real-time communication channel between a client (generally, a browser) and an application. Any site can attempt to open a websocket to any application.
If the application uses websockets for any functionality, verify that it checks the Origin header on the websocket connection request. If the origin is not checked, a connection can be opened from a malicious page in a user's browser and exploited similarly to CSRF.
Websocket functionality should also be audited for standard Authentication, Authorization, and Input Handling vulnerabilities.
Via client-side JavaScript, an application can opt-in to receiving cross-window messages from the Window.postMessage() API. If the received message is handled unsafely, DOM XSS or other vulnerabilities can occur. Audit listeners in the application's JavaScript for safe handling of cross-window messages:
window.addEventListener("message", ...
The received message contains a trusted origin parameter which should be used to determine whether the source of the message is valid, in order to prevent messages from malicious or unexpected sites from reaching application logic.
For applications which send email to users, it is important to prevent an attacker from controlling destination and content. An attacker can use the service to send emails with malicious content in order to create convincing phishing attacks.
Ensure users can only cause emails to be sent to addresses they control. For example, if a user can specify an email address in the application, a verification email should first be sent to that address to ensure the user controls it.
If possible, the application should not create emails using user-controlled input. Instead, use static templates for emails from the application. If the application includes user-controlled input in emails to arbitrary users, input should be validated or sanitized.
In the security model implemented by major browsers, a webpage can embed
any other webpage in an inline frame using the <iframe> tag. The
embedding page then has tightly restricted control over the embedded
page; it can't execute JavaScript in the embedded page context but can
control the appearance and focus of the embedded frame.
Attackers exploit this by loading target pages in hidden iframes and orienting the frame such that a user click on the embedding page is routed to a UI control on the embedded page. By doing this, attackers can cause users to unknowingly click on arbitrary UI elements or send keystrokes to the application.
Verify that the application uses the X-Frame-Options header or a CSP
with the frame-ancestors
directive in order to deny framing by other sites.
Continue to Input Handling.