Storing client's IP address in Firebase - firebase

As far I know there is no information available from the browser to find out the client's IP address without making another call to another resource.
Is there a way to store a client's IP address? I mean in a similar way as the firebase.timestamp placeholder works.

Although I've heard that there are now ways for clients to determine and report their IP address, relying on client side code to report their IP address also opens up the ability for anyone to run custom client side code to report the wrong IP address.
The only secure way of keeping track of the clients' IP addresses would either involve you having a server, or Firebase having a special function, when called by the client, that causes firebase's server to grab the client's IP address and save it for you.
My recommendation would be to run a simple server that can take a POST request. The server only needs to be able to verify what user the request is coming from, and will be able to accurately grab the client's IP address and save it on firebase.

in the following URL
https://firebase.google.com/docs/auth/admin/manage-sessions
In section "Advanced Security: Enforce IP address restrictions"
you'll find a reference to the remoteIpAddress
in this piece of code (the row that the arrow points to):
app.post('/getRestrictedData', (req, res) => {
// Get the ID token passed.
const idToken = req.body.idToken;
// Verify the ID token, check if revoked and decode its payload.
admin.auth().verifyIdToken(idToken, true).then((claims) => {
// Get the user's previous IP addresses, previously saved.
return getPreviousUserIpAddresses(claims.sub);
}).then(previousIpAddresses => {
// Get the request IP address.
const requestIpAddress = req.connection.remoteAddress; <=============================
// Check if the request IP address origin is suspicious relative to previous
// IP addresses. The current request timestamp and the auth_time of the ID
// token can provide additional signals of abuse especially if the IP address
// suddenly changed. If there was a sudden location change in a
// short period of time, then it will give stronger signals of possible abuse.
if (!isValidIpAddress(previousIpAddresses, requestIpAddress)) {
// Invalid IP address, take action quickly and revoke all user's refresh tokens.
revokeUserTokens(claims.uid).then(() => {
res.status(401).send({error: 'Unauthorized access. Please login again!'});
}, error => {
res.status(401).send({error: 'Unauthorized access. Please login again!'});
});
} else {
// Access is valid. Try to return data.
getData(claims).then(data => {
res.end(JSON.stringify(data);
}, error => {
res.status(500).send({ error: 'Server error!' })
});
}
});
});

Related

Stripe webhook security - verify IP address in addition to signature?

I'm using webhooks in a Next.js app to handle incoming customer payment events from Stripe. Similar to the example in the docs, the first thing my webhook does is verify the signature of the incoming event:
const webhookSecret = process.env.SECRET_STRIPE_WEBHOOK
const webhookHandler = async (req, res) =>
{
if (req.method === 'POST')
{
const buf = await buffer(req)
const sig = req.headers['stripe-signature']
let event
try
{
event = stripe.webhooks.constructEvent(buf.toString(), sig, webhookSecret)
}
catch (error)
{
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
// On error, log and return the error message
if (error instanceof Error) console.log(error)
console.log(`Error message: ${errorMessage}`)
res.status(400).send(`Webhook Error: ${errorMessage}`)
return
}
// The rest of the webhook
}
}
However, the docs also mention to only trust events coming from these IP addresses, and provides a list of IP addresses from which webhook events may originate.
For security purposes, is it necessary to also check the IP address of the incoming event, or does the above implementation of verifying the signature cover all bases? The docs explain that verifying signatures through Stripe's libraries does protect against replay attacks, but they do still mention verifying IP addresses in the same sentence.
If verifying IP addresses is a necessary or prudent thing to do, how can I add that to the above implementation? I wasn't able to find examples on the Stripe docs.
Verifying the IP address is an additional layer of security to guarantee the request comes from Stripe. Years ago it was the best approach as webhook signatures didn't exist but since they shipped this feature I think most developers have defaulted to that approach. An attacker can't calculate the signature themselves though they could find a way to replay the requests. I would say most integrations do not bother with the IP allow list.
If you were to implement this, you'd need to look at the IP address associated with the request in your route server-side. This is done with NextRequest though there are other solutions in this answer.

Is it possible to determine the source of an incoming request?

Is it possible to know the hostname of the source of an incoming request to a cloud firestore document? I would like to write a database rule of the form allow write: if request.resource.data.source_host_name == some_predefined_value. This is a web application so I'm trying to find a good way to limit who gets to write to my database without using traditional auth methods.
That sort of rule is not possible with Cloud Firestore. It also wouldn't be very secure, as it's possible to spoof source IP addresses.
If you want to limit who can access your database, the only supported mechanism is through security rules and Firebase Authentication.
Here's my solution to logging a client's IP address when interacting with Firestore. I agree with Doug that this won't guard against IP spoofing. Nonetheless, it's helpful for my purposes.
The trick is to create intermediary API endpoints using Cloud Functions, which then interact with Firestore. Here's an example Google Cloud function.
const admin = require("firebase-admin");
const functions = require("firebase-functions");
admin.initializeApp();
exports.yourEndpoint = functions.https.onRequest(req, (res) => {
// Get the IP address from the headers in the request object
const ipAddress = getIPAddress(req);
// Do whatever you need in your firestore DB with ipAddress
admin.firestore().collection('ipAddresses').add({address: ipAddress})
.then((writeResult) => {
return res.status(200).send();
})
.catch((error) => {
return res.status(500).send();
});
});
// Helper function to extract the IP address from request headers
function getIPAddress(req) {
return (
req.headers["fastly-client-ip"] ||
req.headers["x-forwarded-for"] ||
req.headers["No IP, probably because we are in development mode"]
);
}
Note: you won't get an IP address in development mode, because the Firebase emulators don't create the proper headers.

Meteor.user() on iron-router server side

How can check, on server side route, if user is logged?
I would add check on 'before', but Metor.user() don't work here.
thanks in advance.
p.s. I have found How to get Meteor.user() to return on the server side?, but not work on iron-router
I'm afraid that this is not possible. I guess that the problem comes from the fact that you're trying to connect to the server with two different protocols - both literally and in logically - so there is no obvious way to relate this two actions.
There is, however, a pretty simple solution that may suit your needs. You'll need to develop a simple system of privileges tokens, or secret keys, or whatever you call them. First, create a server method
var Secrets = new Meteor.Collection("secrets"); // only on server!!!
Meteor.methods({
getSecretKey: function () {
if (!this.userId)
// check if the user has privileges
throw Meteor.Error(403);
return Secrets.insert({_id: Random.id(), user: this.userId});
},
});
Then, you can now use it on the client to get the secretKey which attach to your AJAX request (or something), either within the HTTP header or in the URL itself. Fear not!
They will all be encrypted if you're using HTTPS.
On the server side you can now retrieve the secretKey from the incoming request and check if it is present in the Secrets collection. You'll know then if the user is granted certain privileges or not.
Also you may want to remove your secret keys from the collection after some time for safety reasons.
If what you're looking to do is to authenticate the Meteor.user making the request, I'm currently doing this within the context of IronRouter.route(). The request must be made with a valid user ID and auth token in the header. I call this function from within Router.route(), which then gives me access to this.user:
###
Verify the request is being made by an actively logged in user
#context: IronRouter.Router.route()
###
authenticate = ->
# Get the auth info from header
userId = this.request.headers['x-user-id']
loginToken = this.request.headers['x-auth-token']
# Get the user from the database
if userId and loginToken
user = Meteor.users.findOne {'_id': userId, 'services.resume.loginTokens.token': loginToken}
# Return an error if the login token does not match any belonging to the user
if not user
respond.call this, {success: false, message: "You must be logged in to do this."}, 401
# Attach the user to the context so they can be accessed at this.user within route
this.user = user
###
Respond to an HTTP request
#context: IronRouter.Router.route()
###
respond = (body, statusCode=200, headers={'Content-Type':'text/json'}) ->
this.response.writeHead statusCode, headers
this.response.write(JSON.stringify(body))
this.response.end()
This code was heavily inspired by RestStop and RestStop2. It's part of a meteor package for writing REST APIs in Meteor 0.9.0+ (built on top of Iron Router). You can check out the complete source code here:
https://github.com/krose72205/meteor-restivus

How to get the current server IP of request when multiple interfaces are used?

Sorry, but I was not able to find the answer for this simple question after two attempts of googaling:
How can I get the current IP of the server connection a client is handled on? Is it possible to extract this somehow Meteor.status()?
(Background: we have different IPs which are served by the same instance. But we like to distinguish by the IP entry point.)
Meteor.status() don't have the information. But you can publish the IP address to the client or make a method that return it.
This is a pseudo-code and I don't know if this works. It's just an idea:
server.js:
var THIS_IP = '8.8.8.8'; // Try to get it dinamically with node or some npm package
Meteor.methods({
'serverIp': function () {
return THIS_IP;
}
});
client.js:
Meteor.call('serverIp', function (err, serverIp) { //do something with the IP });
EDIT: Sorry about this response. Just saw you have 2 IPs in same server. Maybe this hack can solve problems for now?
how to get external ip of the server from node.js

Email Address Varification Application in ASP.NET

I am getting 555 syntax error in mailfrom
SendData(tcpSocket, string.Format("MAIL From: {0}\r\n", MailFrom));
if (!CheckResponse(tcpSocket, 220))
{
tcpSocket.Close();
return false;
}
is it the problem in my local system because of localhost?
Please help me. I am using this code from below link.
http://www.codeproject.com/Articles/5189/End-to-end-Email-Address-Verification-for-Applicat
Please don't try to implement your own SMTP client, use the one that comes with .NET: System.Net.Mail.SmtpClient.
Many SMTP servers require TLS, for example, which your code does not account for.
Furthermore, for security reasons most mailservers will not reveal if an email address in an RCPT TO line is valid or not. If a system can positively reveal an address exists then it can be used by spam harvesters. Consequently using a dry-run of an SMTP client should only be used to validate an email address (because of the complicated rules regarding valid email addresses). The verification (a separate concept from validation) must be performed manually by requiring the user to respond to an email sent to that address, there is no other way to be sure.

Resources