How to use Mailgun sandbox? - mailgun

I am currently testing Mailgun. Therefore, I don't want to add any payment information at the moment.
So, I'm working with the sandbox, and a verified address in the authorized recipients attached to the sandbox. So far, following the documentation, this limited setup is supposed to be working for testing purpose.
I use Postman to better identify how to work with the API, excluding any potential issues with coding.
Here is my Hello World config:
POST https://api:____my_API_Key___#api.mailgun.net/v3/sandboxXXXXX.mailgun.org/messages
The dashboard indicates that the sandbox is located in the US, so I don't use the european API.
Body:
from: postmaster#sandboxXXX.mailgun.org (also tried the verified email address, and postmaster <postmaster#sandbox...>)
to: bob#marley.com (the verified email address)
subject: test
text: Hello World!
I get a 400 error, Bad Request, and the documentation suggests to look for missing parameters.
The other posts I found so far did not help me to find the error spot either.
Also, Mailgun provides a Postman collection. But it did not help either.
Indeed, I dream of a detailed information of the API requirements, value formating... What are the required parameters if the error means I miss some?
Any idea of what I am missing?

Here is the solution.
I had to guess and analyze some examples from the provided Postman Collection to find out what the documentation is supposed to explain in the first place:
4 Required headers:
Authorization
Value : Basic XXXXX, where XXXXX is the Base 64 encoded version of api:___your_API_key___.
Content-Type
Value : multipart/form-data; boundary=XXX, where XXX is any short single string that will be used to identify a boundary within the sent content.
Content-Length
Value : XXX, where XXX is the size of the body request.
Host
Value : mydomain.com, your IP if sending from Postman...

Related

Wrong Error Message - Here Geocode API - InvalidCredentials

I have a list of addresses which need to be translated to coordinates and Here Geocode API stopped in the middle of the list and returned "InvalidCredentials"/"PermissionError" which was wrong since my credential is valid.
The full Error message below:
<ns2:Error xmlns:ns2="http://www.navteq.com/lbsp/Errors/1" type="PermissionError" subtype="InvalidCredentials"><Details>invalid credentials for </Details></ns2:Error>
Then I check my request, I found out that the problem is NOT about credentials but "#" in the address text.
The error message is wrong and it would be really helpful if Here can change their message specially to this case.
It is repeatable by having "#" in the address string:
Ex: https://geocoder.api.here.com/6.2/geocode.json?searchtext=1920+River+Rd+Apt#57,+Tucson,+AZ&app_id=:your_app_id&app_code=:your_app_code&gen=9
It will return 200 and a success if you remove "#" in the request. Please also note that you may need to put your app id and app code to the url above.
Hope this post can help other people who have the same issue and Here API developers can see this and perhaps change its return message.
"#" needs to be encoded as %23. See URL Encoding.

How to detect if the requests to your server are coming from trustworthy service ? (in Django)

I have a 3rd party service that i've configured a webhook that triggers posting data on my url address. Now i want to restrict incoming requests to be allowed only for this service. How can i do this in Django ? Is there any trick on applying some security measures?
i'd be glad if you can provide some code snippets, please
EDITED
I can't count on the ip address of the requester, it can change in any time. I should use domain name i think
EDITED 2
I have a header called HTTP_X_REAL_IP, that contains the ip address of the service. Can i count on that header by comparing the socket ip address with properly received header ?
It appears that they don't have anything set up to easily do a test, and you aren't saying exactly what you are doing with this API, but it appears that you can query their API for information regarding a bunch of things.
What I would do is to take the information they sent you and send it back in a query to see if the information they now have matches the change they are telling you they made. If they match, it is authentic. If they don't match, discard it.
That's about the best I can tell you to do.
No, you can't use the domain name, as you don't have it when processing a request (note that normally most requesters - internet users - don't have domain names, they only have IP addresses).
The simplest solution is to add an authentication key as required parameter to your APIs. Then, you process only those API calls which provide valid authentication key.

Unable to send mail via Mailgun over api or smtp

I have setup a new account and not verified my domain. I would like to test and confirm mail-send before proceeding with verification and adding payment information.
I have tried curl using the sandbox method and api key (including smtp). I have also tried to use my domain using the top account mail-address as recipient. But each time the send command (both curl and smtp) I get "Mailgun Magnificent API" response - but no mail is delivered. So far the Mailgun API does not look so Magnificent... I have gone through the documentation multiple times and cannot find what I might be doing wrong..
Any help is much appreciated.
Faced the same issue while sending emails via api by php curl. I solved it by changing API Base URL https://api.mailgun.net/v3/YOUR_DOMAIN_NAME to https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages.
It's because their api is not only for sending.
Hope this helps.
For anyone else trying to figure out what "Mailgun Magnificent API" means in a Mailgun HTTP 200-OK API response, it occurs when posting to https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/some/api/endpoint when /some/api/endpoint is not a valid Mailgun API endpoint.
If you are using a client library, there's probably a mistake in your Mailgun sender domain setting. Say you've verified the domain mg.example.com with Mailgun. Examples that can result in "Mailgun Magnificent API" (the exact setting name depends on the library):
MAILGUN_DOMAIN = mg.example.com # comment—this is a common mistake in dotenv files, which don't usually support inline comments; move the # comment to its own line
MAILGUN_DOMAIN = mg.example.com/mysite—get rid of the /mysite part
If you are posting directly to the Mailgun API (or developing a client library), there are some additional ways you might get "Mailgun Magnificent API":
Omitting the API endpoint: https://api.mailgun.net/v3/mg.example.com (as noted in another response)
Misspelling the endpoint: https://api.mailgun.net/v3/mg.example.com/massages (that should be messages with an e)
Including a # or ? after your domain: https://api.mailgun.net/v3/mg.example.com #/messages (see the note above about comments in config files)
Including an extra path after your domain: https://api.mailgun.net/v3/mg.example.com/route/to/my/app/messages
Note that you won't see "Mailgun Magnificent API" if YOUR_DOMAIN_NAME is not a valid sending domain you've registered with Mailgun. (In that case, Mailgun instead responds 404-Not Found).
The mailgun guide shows you to use https://api.mailgun.net/v3/YOUR_DOMAIN as YOUR_DOMAIN_NAME as in the snippet below and this was the problem.
If you're using mailgun-js, you simply need to have YOUR_DOMAIN as YOUR_DOMAIN_NAME.
No need for the https://api.mailgun.net/v3 part
const API_KEY = 'YOUR_API_KEY';
const DOMAIN = 'YOUR_DOMAIN_NAME';
const mailgun = require('mailgun-js')({apiKey: API_KEY, domain: DOMAIN});
const data = {
from: 'Excited User <me#samples.mailgun.org>',
to: 'foo#example.com, bar#example.com',
subject: 'Hello',
text: 'Testing some Mailgun awesomeness!'
};
mailgun.messages().send(data, (error, body) => {
console.log(body);
});
The problem for me was not including my domain name in the url and trying to type everything onto a single line. Strictly following their online example. Typing a backslash will bring your cursor to a new line.
$ curl -s --user 'api:key-xxx' \
https://api.mailgun.net/v3/your_domain/messages \
-F from='User <user#sample.mailgun.org>' \
-F to='xxx#gmail.com' \
-F subject='Hello' \
-F text='Testing some mailgun!'
Response
{
"id": "<xxx.x.xxx#your_domain>",
"message": "Queued. Thank you."
}
Including an slash "/" after messages url part at the end causes this failure too.
For example if you are using a library like Refit for c#, ensure your service interface be declared like this (see the Post attribute):
public interface IMailgunService
{
[Post("")]
Task<JsonDocument> SendEmailAsync([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, object> data);
}

Understanding CORS

I've been looking on the web regarding CORS, and I wanted to confirm if whatever I made of it is, what it actually is.
Mentioned below is a totally fictional scenario.
I'll take an example of a normal website. Say my html page has a form that takes a text field name. On submitting it, it sends the form data to myPage.php. Now, what happens internally is that, the server sends the request to www.mydomain.com/mydirectory/myPage.php along with the text fields. Now, the server sees that the request was fired off from the same domain/port/protocol
(Question 1. How does server know about all these details. Where does it extract all these details froms?)
Nonetheless, since the request is originated from same domain, it server the php script and returns whatever is required off it.
Now, for the sake of argument, let's say I don't want to manually fill the data in text field, but instead I want to do it programmatically. What I do is, I create a html page with javascript and fire off a POST request along with the parameters (i.e. values of textField). Now since my request is not from any domain as such, the server disregards the service to my request. and I get cross domain error?
Similarly, I could have written a Java program also, that makes use of HTTPClient/Post request and do the same thing.
Question 2 : Is this what the problem is?
Now, what CORS provide us is, that the server will say that 'anyone can access myPage.php'.
From enable cors.org it says that
For simple CORS requests, the server only needs to add the following header to its response:
Access-Control-Allow-Origin: *
Now, what exactly is the client going to do with this header. As in, the client anyway wanted to make call to the resources on server right? It should be upto server to just configure itself with whether it wants to accept or not, and act accordingly.
Question 3 : What's the use of sending a header back to client (who has already made a request to the server)?
And finally, what I don't get is that, say I am building some RESTful services for my android app. Now, say I have one POST service www.mydomain.com/rest/services/myPost. I've got my Tomcat server hosting these services on my local machine.
In my android app, I just call this service, and get the result back (if any). Where exactly did I use CORS in this case. Does this fall under a different category of server calls? If yes, then how exactly.
Furthermore, I checked Enable Cors for Tomcat and it says that I can add a filter in my web.xml of my dynamic web project, and then it will start accepting it.
Question 4 : Is that what is enabling the calls from my android device to my webservices?
Thanks
First of all, the cross domain check is performed by the browser, not the server. When the JavaScript makes an XmlHttpRequest to a server other than its origin, if the browser supports CORS it will initialize a CORS process. Or else, the request will result in an error (unless user has deliberately reduced browser security)
When the server encounters Origin HTTP header, server will decide if it is in the list of allowed domains. If it is not in the list, the request will fail (i.e. server will send an error response).
For number 3 and 4, I think you should ask separate questions. Otherwise this question will become too broad. And I think it will quickly get close if you do not remove it.
For an explanation of CORS, please see this answer from programmers: https://softwareengineering.stackexchange.com/a/253043/139479
NOTE: CORS is more of a convention. It does not guarantee security. You can write a malicious browser that disregards the same domain policy. And it will execute JavaScript fetched from any site. You can also create HTTP headers with arbitrary Origin headers, and get information from any third party server that implements CORS. CORS only works if you trust your browser.
For question 3, you need to understand the relationship between the two sites and the client's browser. As Krumia alluded to in their answer, it's more of a convention between the three participants in the request.
I recently posted an article which goes into a bit more detail about how CORS handshakes are designed to work.
Well I am not a security expert but I hope, I can answer this question in one line.
If CORS is enabled then server will just ask browser if you are calling the request from [xyz.com]? If browser say yes it will show the result and if browser says no it is from [abc.com] it will throw error.
So CORS is dependent on browser. And that's why browsers send a preflight request before actual request.
In my case I just added
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
to my WebSecurityConfiguration file issue is resolved

How to identify GET/POST requests made by a human ignoring any requests following

I'm writing an application that listens to HTTP traffic and tries to recognize which requests where initiated by a human.
For example:
The user types cnn.com in their address bar, which starts a request. Then I want to find
CNN's server response while discarding any others requests (such as XHR, etc.)
How could you tell from the header information what means what?
After doing some research I've found that relevant responses come with :
Content-Type: text/html
Html comes with a meaningful title
status 200 ok
There is no way to tell from the bits on the wire. The HTTP protocol has a defined format, which all (non-broken) user agents adhere to.
You are probably thinking that the translation of a user's typing of just 'cnn.com' into 'http://www.cnn.com/' on the wire can be detected from the protocol payload. The answer is no, it can't.
To detect the user agent allowing the user such shorthand, you would have to snoop the user agent application (e.g. a browser) itself.
Actually, detecting non-human agency is the interesting problem (with spam detection as one obvious motivation). This is because HTTP belongs to the family of NVT protocols, where the basic idea, believe it or not, is that a human should be able to run the protocol "by hand" in a network terminal/console program (such as a telnet client.) In other words, the protocol is basically designed as if a human were using it.
I don't think header information can suffice to identify real users from bots, since bots are made to mimic real users and headers are very easy to imitate.
One thing you can do, is to track the path (sequence of clicks) followed by a user, which is most likely to be different from one made by a bot, and made some analysis on the posted information (i.e. bayesian filters).
A very easy to implement check is based on the IP source. There are databases of black listed IP addresses, see Project Honeypot - and if you are writing your software in java, here is an example on how to check an IP address: How to query HTTP:BL for spamming IP addresses.
What I do on my blog is this (using wordpress plugins):
check if an IP address is in the HTTP:BL, if it is the user is shown an html page to take action to whitelist his IP address. This is done in Wordpress by Bad Behavior plugin.
when the user submits some content, a bayesian filter verifies the content of his submission and if his comment is identified as spam, a captcha is displayed before completing the submission. This is done with akismet and conditional captcha, and the comment is also enqueued for manual approval.
After being approved once, the same user is considered safe, and can post without restrictions/checks.
Applying the above rules, I have nomore spam on my blog. And I think that a similar logic can be used for any website.
The advantage of this approach, is that most of the users don't even notice any security mechanism, since no captcha is displayed, nor anything unusual happens in 99% of the times. But still there is quite restrictive, and effective, checks going on under the hoods.
I can't offer any code to help, but I'd say look at the Referer HTTP header. The initial GET request shouldn't have a Referer, but when you start loading the resources on the page (such as JavaScript, CSS, and so on) the Referer will be set to the URL that requested those resources.
So when I type in "stackoverflow.com" in my browser and hit enter, the browser will send a GET request with no Referer, like this:
GET / HTTP/1.1
Host: stackoverflow.com
# ... other Headers
When the browser loads the supporting static resources on the page, though, each request will have a Referer header, like this:
GET /style.css HTTP/1.1
Host: stackoverflow.com
Referer: http://www.stackoverflow.com
# ... other Headers