Securing CSP report-uri payloads - authentication

I am looking to implement a Lambda#Edge function that will add CSP headers to my website and thus will improve my site's security.
I do have an issue with the URL report settings (report-to/report-uri). As far as I can tell, there's no way for me to authenticate CSP violation requests. Does that mean that if a malicious person gains a hold of my reporting API, they can just spam POST requests and send false data? Is there any way to add any sort of security for the reports that get posted via the reporting directive?

Yes, a malicious person can sent a fake SPAM violation reports. But he will not gain any profit from that, just DOS-attack which will not affect the website.
You can make some protection from this if you do use your own service for obtaining reports of violations. You can check cookies, generate a special URL for the reporting API for each visitor (for example, add md5 (IP-address) to it), etc.
But there is usually no reason to protect reports. An attacker cannot determine if this API is currently running or disabled. Therefore, a blind attack of reporting API does not make sense.

I don't agree with #granty
If I was the attacker: yes I can't be sure that the reporting API is running but nevermind. I know there is a risk that the API is up until report-uri directive is set in the Content-Security-Policy header. If I was trying to exploit a vulnerability I would perform a blind attack on the CSP report uri so that potential admins are misinformed on all my exploit tests on the website. This attack make sense if you know that there is a risk that CSP can be triggered by your exploit.

Related

When to choose: CORS vs DPOP?

While CORS and DPOP very different mechanisms, don’t they effectively do the same thing?
i.e. prevent unauthorized access to a resource server?
Why choose one over the other?
CORS does not prevent anything. It's used to selectively reduce security and allow servers to tell clients on other origins which requests they are allowed to make.
dPop is a way for a client to proof that they hold a private key when authenticating with OAuth2, without disclosing the key.
They are completely different mechanisms, and mostly unrelated. Lots of security features ultimately help prevent things from being "stolen", but you can't cafeteria-style pick the security feature you like. Chances are you need to be aware of all of them. Most are complimentary and the ones that are redundant are typically still used anyway (see 'Security in Depth')
No, the outcome of these two is not the same. CORS does not "prevent unauthorized access to a resource server". Thanks to CORS you might block some unwanted access from malicious code that is running in a browser on a domain that you didn't authorize to call you. Still, CORS relies on the browser to block any requests/responses that do not follow your CORS policies. Anyone can still call your endpoints bypassing the browser and having CORS configured won't stop them from doing so. With DPoP you authenticate the caller, so you can authorize access to your endpoints.

How to protect secrets properly?

I am using HERE api in both frontend and backend. If I try to put my app_id and app_code into the frontend code, it will be available to anyone seeing my site.
I can try to create a domain whitelist and put my domain in this. But still, if I set the HTTP header "Referer" to my domain, I am able to access the API from any IP.
So, what do I do?
The Difference Between WHO and WHAT is Accessing the API Server
Before I dive into your problem I would like to first clear a misconception about WHO and WHAT is accessing an API server.
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
So replace the mobile app by web app, and keep following my analogy around this picture.
The Intended Communication Channel represents the web app being used as you expected, by a legit user without any malicious intentions, communicating with the API server from the browser, not using Postman or using any other tool to perform a man in the middle(MitM) attack.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using Curl or a tool like Postman to perform the requests, a hacker using a MitM attack tool, like MitmProxy, to understand how the communication between the web app and the API server is being done in order to be able to replay the requests or even automate attacks against the API server. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
The WHO is the user of the web app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the browser were your web app should be running from, with a real user.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the web app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise, you may end up discovering that It can be one of the legit users manipulating manually the requests or an automated script that is trying to gamify and take advantage of the service provided by the web app.
Well, to identify the WHAT, developers tend to resort to an API key that usually is sent in the headers of the web app. Some developers go the extra mile and compute the key at run-time in the web app, inside obfuscated javascript, thus it becomes a runtime secret, that can be reverse engineered by deobusfaction tools, and by inspecting the traffic between the web app and API server with the F12 or MitM tools.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?. While in the context of a Mobile App, the overall idea is still valid in the context of a web app. You wish you can read the article in full here, that is the first article in a series of articles about API keys.
Your Problem
I can try to create a domain whitelist and put my domain in this. But still, if I set the HTTP header "Referer" to my domain, I am able to access the API from any IP.
So this seems to be related with using the HERE admin interface, and I cannot help you here...
So, what do I do?
I am using HERE API in both frontend and backend.
The frontend MUST always delegate access to third part APIs into a backend that is under the control of the owner of the frontend, this way you don't expose access credentials to access this third part services in your frontend.
So the difference is that now is under your direct control how you will protect against abuse of HERE API access, because you are no longer exposing to the public the HERE api_id and api_code, and access to it must be processed through your backend, where your access secrets are hidden from public pry eyes, and where you can easily monitor and throttle usage, before your bill skyrockets in the HERE API.
If I try to put my app_id and app_code into the frontend code, it will be available to anyone seeing my site.
So to recap, the only credentials you SHOULD expose in your frontend is the ones to access your backend, the usual api-key and Authorization tokens, or whatsoever you want to name them, not the api_id or api_code to access the HERE API. This approach leaves you only with one access to protect, instead of multiple ones.
Defending an API Server
As I already said, but want to reinforce a web app should only communicate with an API server that is under your control and any access to third part APIs services must be done by this same API server you control. This way you limit the attack surface to only one place, where you will employ as many layers of defence as what you are protecting is worth.
For an API serving a web app, you can employ several layers of dense, starting with reCaptcha V3, followed by Web Application Firewall(WAF) and finally if you can afford it a User Behavior Analytics(UBA) solution.
Google reCAPTCHA V3:
reCAPTCHA is a free service that protects your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive challenges to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.
...helps you detect abusive traffic on your website without any user friction. It returns a score based on the interactions with your website and provides you more flexibility to take appropriate actions.
WAF - Web Application Firewall:
A web application firewall (or WAF) filters, monitors, and blocks HTTP traffic to and from a web application. A WAF is differentiated from a regular firewall in that a WAF is able to filter the content of specific web applications while regular firewalls serve as a safety gate between servers. By inspecting HTTP traffic, it can prevent attacks stemming from web application security flaws, such as SQL injection, cross-site scripting (XSS), file inclusion, and security misconfigurations.
UBA - User Behavior Analytics:
User behavior analytics (UBA) as defined by Gartner is a cybersecurity process about the detection of insider threats, targeted attacks, and financial fraud. UBA solutions look at patterns of human behavior, and then apply algorithms and statistical analysis to detect meaningful anomalies from those patterns—anomalies that indicate potential threats. Instead of tracking devices or security events, UBA tracks a system's users. Big data platforms like Apache Hadoop are increasing UBA functionality by allowing them to analyze petabytes worth of data to detect insider threats and advanced persistent threats.
All these solutions work based on a negative identification model, by other words they try their best to differentiate the bad from the good by identifying what is bad, not what is good, thus they are prone to false positives, despite the advanced technology used by some of them, like machine learning and artificial intelligence.
So you may find yourself more often than not in having to relax how you block the access to the API server in order to not affect the good users. This also means that these solutions require constant monitoring to validate that the false positives are not blocking your legit users and that at the same time they are properly keeping at bay the unauthorized ones.
Summary
Anything that runs on the client side and needs some secret to access an API can be abused in different ways and you must delegate the access to all third part APIs to a backend under your control, so that you reduce the attack surface, and at the same time protect their secrets from public pry eyes.
In the end, the solution to use in order to protect your API server must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.
So using API keys may sound like locking the door of your home and leave the key under the mat, but not using them is liking leaving your car parked with the door closed, but the key in the ignition.
Going the Extra Mile
OWASP Web Top 10 Risks
The OWASP Top 10 is a powerful awareness document for web application security. It represents a broad consensus about the most critical security risks to web applications. Project members include a variety of security experts from around the world who have shared their expertise to produce this list.

How to secure a web API with public key from unauthorized access?

While understanding the nature of web API, Some questions regarding its safety were raised. What are the best practices to design web API such that only authorized user should be able to access it. I tried to check below options, but none was able to achieve perfect safety.
1) I cannot rely on request origin, referrer or user agent string since they can be easily spoofed.
2) Web API requires just a public key to access it so CSRF token is also not suitable to implement.
Is there any other way I can ensure request is coming from trusted source only?
My use case is I would like to implement client side API like google map, where any one who has purchased an access to API, will whitelist their website domain and can include my plugin on their website. Plugin will then make request to my API on behalf of user.
Is it a good idea, if I apply some request signature logic on web API so my server can validate the requester and reject the unauthorized origins. I assume I would have to keep my request signature logic secret and so I may need some obfuscation on code.
You do not mention anything about the usecase, especially if the client is a system or a person?
First off, security by obscurity is never a good choice. Second, it is considered bad practice to "create your own security system", it is much better to stand on the shoulders of others who has the knowledge and experience in security.
Without knowing the exact usercase, it is hard to come with a lot of suggestions... however, i'd suggest you look at at stuff like jwt tokens(i'm guessing that you have a person behind a webclient as the user of your webservice)... since you've tagged the question with asp.net-web-api i'd also suggest you have a look at https://identityserver.io project ... I've previously used IdentityServer4 with success in a large asp.net webapi project...

API for mobile app security/auth

I have an API that is serving content to a mobile app, and have no current plans to use the API for other products. I have 2 main questions:
How to prevent someone from sniffing the API requests and making their own requests (this should not be an public API).
If preventing #1 is not possible completely, then how can I limit/throttle requests from un-approved consumers? Are there other concerns here?
Using an auth token (passed as A GET param) for each request satisfies #2 (I can revoke it at anytime) however I do not want to have to update the app to use a different token in future.
Also, there is no authentication for users in the mobile app, and the API is written in PHP.
What are the best practices in this area?
Here are a couple of suggestions that can help keep your API private.
Use TLS to discourage casual packet sniffing.
Make sure your clients verify the server certificate to prevent MITM attacks.
Encrypt or obfuscate the auth token in the client code so it's not obviously exposed in something like a string dump.
Ultimately, though, if someone really wants to access your API, they will - either through reverse engineering your client code, or more complex data interception techniques. The best you can hope for is to discourage access attempts by the average user.
How to prevent someone from sniffing the API requests and making their own requests (this should not be an public API).
I would echo the previous answer that you should use TLS as a matter of course, in order to encrypt the traffic on the wire to prevent sniffing. But I would add that you also need to deter "capture-replay" attacks, whereby an attacker may resend a previous message which they may have obtained (e.g. from a client-side log) despite the usage of TLS. In this case, if you are using a nonce (meaning "number once") and/or timestamp in your requests, with HMAC signing, then the replayed API request can be detected and blocked. I have written about an example of this on my blog: http://www.soatothecloud.com/2011/02/securing-apis.html . Amazon's APIs, for example, use this approach.
If preventing #1 is not possible completely, then how can I
limit/throttle requests from un-approved consumers? Are there other
concerns here?
As well as the HMAC signing (above), you can also consider monitoring incoming IP address range, device info (e.g. headers indicating the device type - Android vs iOS etc), and other factors which can be used to link multiple requests to particular clients, and then apply policies at the API level.
Full disclosure: I work for an API Management / API Gateway vendor (Axway) but the info above should be generic.

Best Practices for securing a REST API / web service [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When designing a REST API or service are there any established best practices for dealing with security (Authentication, Authorization, Identity Management) ?
When building a SOAP API you have WS-Security as a guide and much literature exists on the topic. I have found less information about securing REST endpoints.
While I understand REST intentionally does not have specifications analogous to WS-* I am hoping best practices or recommended patterns have emerged.
Any discussion or links to relevant documents would be very much appreciated.
If it matters, we would be using WCF with POX/JSON serialized messages for our REST API's/Services built using v3.5 of the .NET Framework.
As tweakt said, Amazon S3 is a good model to work with. Their request signatures do have some features (such as incorporating a timestamp) that help guard against both accidental and malicious request replaying.
The nice thing about HTTP Basic is that virtually all HTTP libraries support it. You will, of course, need to require SSL in this case because sending plaintext passwords over the net is almost universally a bad thing. Basic is preferable to Digest when using SSL because even if the caller already knows that credentials are required, Digest requires an extra roundtrip to exchange the nonce value. With Basic, the callers simply sends the credentials the first time.
Once the identity of the client is established, authorization is really just an implementation problem. However, you could delegate the authorization to some other component with an existing authorization model. Again the nice thing about Basic here is your server ends up with a plaintext copy of the client's password that you can simply pass on to another component within your infrastructure as needed.
There are no standards for REST other than HTTP. There are established REST services out there. I suggest you take a peek at them and get a feel for how they work.
For example, we borrowed a lot of ideas from Amazon's S3 REST service when developing our own. But we opted not to use the more advanced security model based on request signatures. The simpler approach is HTTP Basic auth over SSL. You have to decide what works best in your situation.
Also, I highly recommend the book RESTful Web Services from O'reilly. It explains the core concepts and does provide some best practices. You can generally take the model they provide and map it to your own application.
You may also want to take a look at OAuth, an emerging open protocol for token-based authorization specifically targeting http apis.
It is very similar to the approach taken by flickr and remember the milk "rest" apis (not necessarily good examples of restful apis, but good examples of the token-based approach).
There is a great checklist found on Github:
Authentication
Don't reinvent the wheel in Authentication, token generation, password storage. Use the standards.
Use Max Retry and jail features in Login.
Use encryption on all sensitive data.
JWT (JSON Web Token)
Use a random complicated key (JWT Secret) to make brute forcing the token very hard.
Don't extract the algorithm from the payload. Force the algorithm in the backend (HS256 or RS256).
Make token expiration (TTL, RTTL) as short as possible.
Don't store sensitive data in the JWT payload, it can be decoded easily.
OAuth
Always validate redirect_uri server-side to allow only whitelisted URLs.
Always try to exchange for code and not tokens (don't allow response_type=token).
Use state parameter with a random hash to prevent CSRF on the OAuth authentication process.
Define the default scope, and validate scope parameters for each application.
Access
Limit requests (Throttling) to avoid DDoS / brute-force attacks.
Use HTTPS on server side to avoid MITM (Man In The Middle Attack)
Use HSTS header with SSL to avoid SSL Strip attack.
Input
Use the proper HTTP method according to the operation: GET (read), POST (create), PUT/PATCH (replace/update), and DELETE (to delete a record), and respond with 405 Method Not Allowed if the requested method isn't appropriate for the requested resource.
Validate content-type on request Accept header (Content Negotiation) to allow only your supported format (e.g. application/xml, application/json, etc) and respond with 406 Not Acceptable response if not matched.
Validate content-type of posted data as you accept (e.g. application/x-www-form-urlencoded, multipart/form-data, application/json, etc).
Validate User input to avoid common vulnerabilities (e.g. XSS, SQL-Injection, Remote Code Execution, etc).
Don't use any sensitive data (credentials, Passwords, security tokens, or API keys) in the URL, but use standard Authorization header.
Use an API Gateway service to enable caching, Rate Limit policies (e.g. Quota, Spike Arrest, Concurrent Rate Limit) and deploy APIs resources dynamically.
Processing
Check if all the endpoints are protected behind authentication to avoid broken authentication process.
User own resource ID should be avoided. Use /me/orders instead of /user/654321/orders.
Don't auto-increment IDs. Use UUID instead.
If you are parsing XML files, make sure entity parsing is not enabled to avoid XXE (XML external entity attack).
If you are parsing XML files, make sure entity expansion is not enabled to avoid Billion Laughs/XML bomb via exponential entity expansion attack.
Use a CDN for file uploads.
If you are dealing with huge amount of data, use Workers and Queues to process as much as possible in background and return response fast to avoid HTTP Blocking.
Do not forget to turn the DEBUG mode OFF.
Output
Send X-Content-Type-Options: nosniff header.
Send X-Frame-Options: deny header.
Send Content-Security-Policy: default-src 'none' header.
Remove fingerprinting headers - X-Powered-By, Server, X-AspNet-Version etc.
Force content-type for your response, if you return application/json then your response content-type is application/json.
Don't return sensitive data like credentials, Passwords, security tokens.
Return the proper status code according to the operation completed. (e.g. 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed, etc).
I'm kind of surprised SSL with client certificates hasn't been mentioned yet. Granted, this approach is only really useful if you can count on the community of users being identified by certificates. But a number of governments/companies do issue them to their users. The user doesn't have to worry about creating yet another username/password combination, and the identity is established on each and every connection so communication with the server can be entirely stateless, no user sessions required. (Not to imply that any/all of the other solutions mentioned require sessions)
Everyone in these answers has overlooked true access control / authorization.
If for instance your REST APIs / web services are about POSTing / GETing medical records, you may want to define access control policie about who can access the data and under which circumstances. For instance:
doctors can GET the medical record of a patient they have a care relationship with
no one can POST medical data outside practice hours (e.g. 9 to 5)
end-users can GET medical records they own or medical records of patients for whom they are the guardian
nurses can UPDATE the medical record of a patient that belongs to the same unit as the nurse.
In order to define and implement those fine-grained authorizations, you will need to use an attribute-based access control language called XACML, the eXtensible Access Control Markup Language.
The other standards here are for the following:
OAuth: id. federation and delegation of authorization e.g. letting a service act on my behalf on another service (Facebook can post to my Twitter)
SAML: identity federation / web SSO. SAML is very much about who the user is.
WS-Security / WS-* standards: these focus on the communication between SOAP services. They are specific to the application-level messaging format (SOAP) and they deal with aspects of messaging e.g. reliability, security, confidentiality, integrity, atomicity, eventing... None cover access control and all are specific to SOAP.
XACML is technology-agnostic. It can be applied to java apps, .NET, Python, Ruby... web services, REST APIs, and more.
The following are interesting resources:
the OASIS XACML website
the NIST ABAC standard
I've used OAuth a few times, and also used some other methods (BASIC/DIGEST). I wholeheartedly suggest OAuth. The following link is the best tutorial I've seen on using OAuth:
http://hueniverse.com/oauth/guide/
One of the best posts I've ever come across regarding Security as it relates to REST is over at 1 RainDrop. The MySpace API's use OAuth also for security and you have full access to their custom channels in the RestChess code, which I did a lot of exploration with. This was demo'd at Mix and you can find the posting here.
Thanks for the excellent advice. We ended up using a custom HTTP header to pass an identity token from the client to the service, in preparation for integrating our RESTful API with the the upcoming Zermatt Identity framework from Microsoft. I have described the problem here and our solution here. I also took tweakt's advice and bought RESTful Web Services - a very good book if you're building a RESTful API of any kind.
OWASP(Open Web Application Security Project) has some cheat sheets covering about all aspects of Web Application development. This Project is a very valuable and reliable source of information.
Regarding REST services you can check this: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
I would recommend OAuth 2/3. You can find more information at http://oauth.net/2/
I searched a lot about restful ws security and we also ended up with using token via cookie from client to server to authenticate the requests . I used spring security for authorization of requests in service because I had to authenticate and authorized each request based on specified security policies that has already been in DB.
The fact that the SOAP world is pretty well covered with security standards doesn't mean that it's secure by default. In the first place, the standards are very complex. Complexity is not a very good friend of security and implementation vulnerabilities such as XML signature wrapping attacks are endemic here.
As for the .NET environment I won't help much, but “Building web services with Java” (a brick with ~10 authors) did help me a lot in understanding the WS-* security architecture and, especially, its quirks.
REST itself offers no security standards, but things like OAuth and SAML are rapidly becoming the standards in this space. However, authentication and authorization are only a small part of what you need to consider. Many of the known vulnerabilities relating to web applications apply very much to REST apis. You have to consider input validation, session cracking, inappropriate error messages, internal employee vulnerabilities and so on. It is a big subject.
I want to add(in line with stinkeymatt), simplest solution would be to add SSL certificates to your site. In other words, make sure your url is HTTPS://. That will cover your transport security (bang for the buck). With RESTful url's, idea is to keep it simple (unlike WS* security/SAML), you can use oAuth2/openID connect or even Basic Auth (in simple cases). But you will still need SSL/HTTPS. Please check ASP.NET Web API 2 security here: http://www.asp.net/web-api/overview/security (Articles and Videos)
As #Nathan ended up with which is a simple HTTP Header, and some had said OAuth2 and client side SSL certificates. The gist of it is this... your REST API shouldn't have to handle security as that should really be outside the scope of the API.
Instead a security layer should be put on top of it, whether it is an HTTP Header behind a web proxy (a common approach like SiteMinder, Zermatt or even Apache HTTPd), or as complicated as OAuth 2.
The key thing is the requests should work without any end-user interaction. All that is needed is to ensure that the connection to the REST API is authenticated. In Java EE we have the notion of a userPrincipal that can be obtained on an HttpServletRequest. It is also managed in the deployment descriptor that a URL pattern can be secure so the REST API code does not need to check anymore.
In the WCF world, I would use ServiceSecurityContext.Current to get the current security context. You need to configure you application to require authentication.
There is one exception to the statement I had above and that's the use of a nonce to prevent replays (which can be attacks or someone just submitting the same data twice). That part can only be handled in the application layer.
For Web Application Security, you should take a look at OWASP (https://www.owasp.org/index.php/Main_Page) which provides cheatsheets for various security attacks. You can incorporate as many measures as possible to secure your Application.
With respect to API security (authorization, authentication, identity management), there are multiple ways as already mentioned (Basic,Digest and OAuth). There are loop holes in OAuth1.0, so you can use OAuth1.0a (OAuth2.0 is not widely adopted due to concerns with the specification)
It's been a while but the question is still relevant, though the answer might have changed a bit.
An API Gateway would be a flexible and highly configurable solution.
I tested and used KONG quite a bit and really liked what I saw. KONG provides an admin REST API of its own which you can use to manage users.
Express-gateway.io is more recent and is also an API Gateway.